//
//  File.swift
//  LKF
//
//  Created by Alexander Holzer on 13.01.25.
//  Copyright © 2025 Alexander Holzer. All rights reserved.
//

import Foundation
@_implementationOnly import LibLKF

public enum LKFStatCategoryType : UInt32 {
    case ka = 0
    case abt = 1
    case age = 2
    case hws = 3
    
    public var label : String {
        switch (self) {
        case .ka: return "Krankenanstalt"
        case .abt: return "Abteilung"
        case .age: return "Alter"
        case .hws: return "Hauptwohnsitz"
        }
    }
}

public enum LKFStatCategoryField : Int {
    case belagsTage = 0
    case aufnahme = 1
    case verblieben = 2
    case entlassung = 3
    case verstorben = 4
    case verbleibend = 5
    case ganzjahr = 6
    case eintag = 7
    case maennlich = 8
    case weiblich = 9
    case aufCount = 10
    case pflegetage = 11
    case amb = 12
    case divers = 13
    
    public var label : String {
        switch (self) {
        case .belagsTage: return "Belagstage"
        case .aufnahme: return "Aufnahmen"
        case .verblieben: return "Verblieben"
        case .entlassung: return "Entlassungen"
        case .verstorben: return "Verstorben"
        case .verbleibend: return "Verbleibend"
        case .ganzjahr: return "Ganzjahr"
        case .eintag: return "Eintag"
        case .maennlich: return "Männlich"
        case .weiblich: return "Weiblich"
        case .aufCount: return "Stationär"
        case .pflegetage: return "Pflegetage"
        case .amb: return "Ambulant"
        case .divers: return "Divers"
        }
    }
}

public class LKFStatCategoryRow : Identifiable {
    
    public let parts: [String]
    
    public var id: String {
        return parts.count > 0 ? parts[0] : ""
    }
    
    public func value (at index:Int) -> String? {
        if index + 1 >= parts.count {
            return nil
        }
        return parts[index + 1]
    }
    
    init (string: String) {
        self.parts = string.components(separatedBy: ";").map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
    }
}

public class LKFStatCategory {
    
    public let categoryType: LKFStatCategoryType
    public let fields: [LKFStatCategoryField]
    public let data: [LKFStatCategoryRow]
    
    public init (lkfContext: LKFContext, categoryType: LKFStatCategoryType) {
        self.categoryType = categoryType
        guard let ptr = lkfContext.ptr else
        {
            fields = []
            data = []
            return
        }
        LibLKF.lkf_stat(ptr)
        let fieldCount = LibLKF.lkf_stat_getFieldCount(ptr, categoryType.rawValue)
        let fieldRange : Range<UInt32> = (0 ..<  fieldCount)
        self.fields = fieldRange.compactMap {
            let rawValue = Int (LibLKF.lkf_stat_getFieldAtIndex(ptr, categoryType.rawValue,
                                                                 $0))
            return LKFStatCategoryField (rawValue: rawValue)
        }
        var dataCount = LibLKF.lkf_stat_getLineCount(ptr, categoryType.rawValue)
        
        if dataCount == 0 {
            LibLKF.lkf_stat(ptr)
            dataCount = LibLKF.lkf_stat_getLineCount(ptr, categoryType.rawValue)
        }
        
        let dataRowRange : Range<UInt32> = (0 ..< dataCount)
        
        let lineBuffer = UnsafeMutablePointer<CChar>.allocate(capacity:2048)
        defer {
            lineBuffer.deallocate()
        }
        
        self.data = dataRowRange.compactMap {
            LibLKF.lkf_stat_getLine(ptr, categoryType.rawValue, $0, lineBuffer, 1024)
            return LKFStatCategoryRow(string: String(cString: lineBuffer))
        }
    }
}
