//
//  LKFScoringDetailsMEL.swift
//  LKF
//
//  Created by Alexander Holzer on 21.03.22.
//  Copyright © 2022 Alexander Holzer. All rights reserved.
//

import Foundation
@_implementationOnly import LibLKF

public class LKFScoringDetailsMEL : LKFScoringDetailsGroup {
    public let mel: LKFAufenthaltMEL
    public let scoringMelIndex: UInt32
    public let melIndex : UInt32
    public var melzu: [LKFScoringDetailsGroupMelzu]?
    public var pools: [LKFScoringDetailsGroupMelPool]?

    init (aufenthalt:LKFAufenthalt, melIndex: UInt32, mainGroupIndex: Int)  {
        
        let lineBuffer = UnsafeMutablePointer<CChar>.allocate(capacity:2048)
        let aufenthaltPtr = aufenthalt.ptr
        LibLKF.lkf_scoringdetails_getMELInfo (aufenthaltPtr, melIndex, lineBuffer, 2048)
        let parts = String.utf8String(cString: lineBuffer).components(separatedBy: "|")

        self.scoringMelIndex = melIndex
        
        if parts.count > 4 {
            self.melIndex = UInt32(parts[4]) ?? melIndex
        }
        else {
            self.melIndex = melIndex
        }
        self.mel = aufenthalt.melAt(index: self.melIndex)
        
        super.init(aufenthalt: aufenthalt, parts: parts, mainGroupIndex: mainGroupIndex)
        
        let ch = LibLKF.lkf_scoringdetails_getMELCommentCount(aufenthaltPtr, melIndex)
        if ch > 0 {
            var comments = [String]()
            for i in 0..<ch {
                LibLKF.lkf_scoringdetails_getMELComment(aufenthaltPtr, melIndex, i, lineBuffer, 1024)
                comments.append(String.utf8String(cString: lineBuffer))
            }
            self.comments = comments
        }
        else {
            comments = nil
        }

        if self.inactive {
            self.melzu = nil
            self.pools = nil
        }
        else {
            var melzu = [LKFScoringDetailsGroupMelzu]()
            var pools = [Int:[LKFScoringDetailsGroupMelzu]]()
            if let subgruppeIndex = self.subgruppeIndex {
                for i in 0..<aufenthalt.melCount {
                    if LibLKF.lkf_scoringdetails_getSubgruppeMEL(aufenthalt.ptr, subgruppeIndex, i, lineBuffer, 2048) == 0 {
                        continue
                    }
                    let groupMelZu = LKFScoringDetailsGroupMelzu(group: self, melIndex: i, line: String(cString: lineBuffer))
                    melzu.append(groupMelZu)
                    
                    if pools[groupMelZu.melPool] == nil {
                        pools[groupMelZu.melPool] = [groupMelZu]
                    }
                    else {
                        pools[groupMelZu.melPool]!.append(groupMelZu)
                    }
                    
                    self.pools = pools.map { p, arr in
                        LKFScoringDetailsGroupMelPool (poolIndex: p, mels: arr)
                    }
                }
            }
            self.melzu = melzu
        }
        lineBuffer.deallocate()
    }
    
    public override var traceIdent: String {
        return "\(mel.MEL) (\(LKFConvert.toShortString(optionalDate:mel.MELDate)):\(mel.MELANZString))"
    }
    
    override public var index : UInt32 {
        return melIndex
    }
    
    public override var traceLines : [String] {
        if !active {
            return [traceLine]
        }
        else {
            var arr = [String]()
            
            arr.append(traceLine)
            if let subgruppeParts = subgruppeParts {
                arr.append(subgruppeParts.joined(separator: "|"))
            }
            if let pools = pools {
                for p in pools {
                    arr.append(contentsOf: p.traceLines)
                }
            }
            else if let melzu = melzu {
                for m in melzu {
                    arr.append(contentsOf: m.traceLines)
                }
            }
            if let comments = comments {
                for c in comments {
                    arr.append(c)
                }
            }
            return arr
        }
    }

    func melzu (for index: Int) -> LKFScoringDetailsGroupMelzu? {
        if let melzu {
            for m in melzu {
                if m.melIndex == index {
                    return m
                }
            }
        }
        return nil
    }
}

