//
//  LNSkillFieldBaseEditView.swift
//  Gami
//
//  Created by OneeChan on 2026/1/21.
//

import Foundation
import UIKit
import SnapKit


protocol LNSkillFieldBaseEditViewDelegate: AnyObject {
    func onSkillFieldBaseEditViewInputChanged(view: LNSkillFieldBaseEditView)
}


class LNSkillFieldBaseEditView: LNJoinUsInputFieldGroupView {
    private(set) var field: LNSkillEditField?
    var needReview: Bool = false
    
    weak var delegate: LNSkillFieldBaseEditViewDelegate?
    
    func update(_ field: LNSkillEditField) {
        titleLabel.text = field.fieldName
        
        descLabel.text = field.fieldDesc
        descLabel.isHidden = field.fieldDesc.isEmpty
        
        if let example = field.example, !example.value.isEmpty {
            showExample {
                switch example.type {
                case .photo:
                    let panel = LNJoinUsPhotoExamplePanel()
                    panel.update(example)
                    panel.popup()
                case .voice:
                    let panel = LNJoinUsVoiceExamplePanel()
                    panel.update(example)
                    panel.popup()
                }
            }
        }
        
        self.field = field
    }
    
    func hasInput() -> Bool {
        guard let field else { return false }
        if !field.validate.required {
            return true
        }
        return field.value != nil
    }
    
    func checkAvailable() -> Bool {
        guard let field else { return false }
        if !field.validate.required {
            return true
        }
        
        let isMatchLimit = if field.array {
            checkArrayAvailable()
        } else {
            checkValueAvailable()
        }
        
        return isMatchLimit
    }
    
    private func checkArrayAvailable() -> Bool {
        guard let field else { return false }
        if !field.validate.required {
            return true
        }
        
        guard let limit = field.validate.arraySize else {
            if field.value == nil {
                showToast(.init(key: "B00064", field.fieldName))
                return false
            } else {
                return true
            }
        }
        let count = if let texts = field.value as? [String] {
            texts.count
        } else if let numbers = field.value as? [Int] {
            numbers.count
        } else if let numbers = field.value as? [Double] {
            numbers.count
        } else {
            0
        }
        
        if count < limit.min {
            showToast(.init(key: "B00059", limit.min, field.fieldName))
            return false
        } else if count > limit.max {
            return false
        } else {
            return true
        }
    }
    
    private func checkValueAvailable() -> Bool {
        guard let field else { return false }
        if !field.validate.required {
            return true
        }
        
        switch field.type {
        case .singleLineText, .multiLineText:
            guard let text = field.value as? String else {
                showToast(.init(key: "B00065", field.fieldName))
                return false
            }
            guard let size = field.validate.size else {
                return true
            }
            if text.count < size.min {
                showToast(.init(key: "B00066", field.fieldName, size.min))
                return false
            } else if text.count > size.max {
                return false
            } else {
                return true
            }
        case .singleSelection:
            if field.value == nil {
                showToast(.init(key: "B00064", field.fieldName))
                return false
            } else {
                return true
            }
        case .multiSelection:
            if (field.value as? [String])?.isEmpty != false {
                showToast(.init(key: "B00064", field.fieldName))
                return false
            } else {
                return true
            }
        case .number:
            guard let limit = field.validate.numLimit else {
                if field.value == nil {
                    showToast(.init(key: "B00065", field.fieldName))
                    return false
                } else {
                    return true
                }
            }
            if let number = field.value as? Int {
                if Double(number) < limit.min {
                    showToast(.init(key: "B00067", field.fieldName, limit.min.toDisplay))
                    return false
                } else if Double(number) > limit.max {
                    showToast(.init(key: "B00068", field.fieldName, limit.max.toDisplay))
                    return false
                } else {
                    return true
                }
            } else if let number = field.value as? Double {
                if number < limit.min {
                    showToast(.init(key: "B00067", field.fieldName, limit.min.toDisplay))
                    return false
                } else if number > limit.max {
                    showToast(.init(key: "B00068", field.fieldName, limit.max.toDisplay))
                    return false
                } else {
                    return true
                }
            } else {
                return false
            }
        case .photo:
            if (field.value as? [String])?.isEmpty != false {
                showToast(.init(key: "B00069", field.fieldName))
                return false
            } else {
                return true
            }
        case .voice:
            guard (field.value as? String)?.isEmpty == false else {
                showToast(.init(key: "B00070", field.fieldName))
                return false
            }
            guard let limit = field.validate.numLimit else {
                return true
            }
            if Double(field.duration) < limit.min {
                showToast(.init(key: "B00009", limit.max))
                return false
//            } else if Double(field.duration) > limit.max {
//                return false
            } else {
                return true
            }
        case .unknown:
            return false
        }
    }
}
