//
//  LNCreateOrderPanel.swift
//  Lanu
//
//  Created by OneeChan on 2025/12/22.
//

import Foundation
import UIKit
import SnapKit


class LNCreateOrderPanel: LNPopupView {
    private let gameNameLabel = UILabel()
    
    private let avatar = UIImageView()
    private let nameLabel = UILabel()
    private let priceLabel = UILabel()
    
    private let countEditView = UIView()
    private let minuButton = UIButton()
    private let customCountLabel = UILabel()
    private let addButton = UIButton()
    
    private let countLabel = UILabel()
    private let costLabel = UILabel()
    
    private let discountView = UIView()
    private let newbieView = LNNewbieDiscountView()
    private let discountCoinLabel = UILabel()
    
    private let extraView = UIView()
    private let extraInput = UITextField()
    
    private let curCoinLabel = UILabel()
    
    private var skillId: String?
    private var qrCode: String?
    private var price: Double = 0.0
    private var curCount = 1 {
        didSet {
            countLabel.text = "x\(curCount)"
            customCountLabel.text = "\(curCount)"
            
            if let discount = LNOrderManager.shared.discountFor(price) {
                costLabel.text = (price * Double(curCount) - (1 - discount) * price).toDisplay
            } else {
                costLabel.text = (price * Double(curCount)).toDisplay
            }
            if curCount <= 1 {
                minuButton.isEnabled = false
            } else {
                minuButton.isEnabled = true
            }
        }
    }
    
    var editable: Bool = false {
        didSet {
            extraView.isHidden = !editable
            countEditView.isHidden = !editable
            countLabel.isHidden = editable
        }
    }
    var scene: LNOrderScene = .normal
    
    private var targetUid: String?
    var completionHandler: ((String) -> Void)?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupViews()
        
        LNEventDeliver.addObserver(self)
        LNPurchaseManager.shared.reloadWalletInfo()
    }
    
    func update(_ detail: LNGameMateSkillDetailVO, count: Int, extra: String) {
        gameNameLabel.text = detail.categoryName
        avatar.showAvatar(detail.avatar)
        nameLabel.text = detail.nickname
        priceLabel.text = "\(detail.price.toDisplay)/\(detail.unit)"
        
        if let discount = LNOrderManager.shared.discountFor(detail.price) {
            discountView.isHidden = false
            newbieView.update(1 - discount)
            discountCoinLabel.text = "-\(detail.price * (1 - discount))"
        } else {
            discountView.isHidden = true
        }
        
        skillId = detail.id
        price = detail.price
        targetUid = detail.userNo
        curCount = count
        
        extraInput.text = extra
    }
    
    func update(_ skill: LNGameMateSkillVO, user: LNUserProfileVO) {
        gameNameLabel.text = skill.name
        avatar.showAvatar(user.avatar)
        nameLabel.text = user.nickname
        priceLabel.text = "\(skill.price.toDisplay)/\(skill.unit)"
        
        if let discount = LNOrderManager.shared.discountFor(skill.price) {
            discountView.isHidden = false
            newbieView.update(1 - discount)
            discountCoinLabel.text = "-\(skill.price * (1 - discount))"
        } else {
            discountView.isHidden = true
        }
        
        skillId = skill.id
        price = skill.price
        targetUid = user.userNo
        curCount = 1
    }
    
    func update(_ detail: LNQRCodeDetailResponse, count: Int, extra: String) {
        gameNameLabel.text = detail.bizCategoryName
        avatar.showAvatar(detail.avatar)
        nameLabel.text = detail.nickname
        priceLabel.text = "\(detail.price.toDisplay)/\(detail.unit)"
        
        if let discount = LNOrderManager.shared.discountFor(detail.price) {
            discountView.isHidden = false
            newbieView.update(1 - discount)
            discountCoinLabel.text = "-\(detail.price * (1 - discount))"
        } else {
            discountView.isHidden = true
        }
        
        qrCode = detail.qrCode
        price = detail.price
        targetUid = detail.sellerUserNo
        curCount = count
        
        extraInput.text = extra
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension LNCreateOrderPanel: LNPurchaseManagerNotify {
    func onUserWalletInfoChanged(info: LNUserWalletInfo) {
        curCoinLabel.text = info.coin.toDisplay
    }
}

extension LNCreateOrderPanel: UITextFieldDelegate {
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let currentText = textField.text ?? ""
                
        guard let range = Range(range, in: currentText) else { return false }
        let newText = currentText.replacingCharacters(in: range, with: string)
        if newText.count < currentText.count {
            return true
        }
        
        return newText.count <= LNOrderManager.orderExtraMaxLength
    }
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }
}

extension LNCreateOrderPanel {
    private func setupViews() {
        container.backgroundColor = .primary_1
        
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.spacing = 10
        container.addSubview(stackView)
        stackView.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(12)
            make.top.equalToSuperview().offset(20)
        }
        
        let billInfo = buildBillInfo()
        stackView.addArrangedSubview(billInfo)
        
        let extra = buildExtra()
        stackView.addArrangedSubview(extra)
        
        let wallet = buildWalletInfo()
        stackView.addArrangedSubview(wallet)
        
        let confirmButton = UIButton()
        confirmButton.setTitle(.init(key: "A00123"), for: .normal)
        confirmButton.setTitleColor(.text_1, for: .normal)
        confirmButton.titleLabel?.font = .heading_h3
        confirmButton.setBackgroundImage(.primary_8, for: .normal)
        confirmButton.layer.cornerRadius = 23.5
        confirmButton.clipsToBounds = true
        confirmButton.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            let extra = extraInput.text ?? ""
            
            let handler = { [weak self] (orderNo: String?) in
                guard let self else { return }
                guard let orderNo else { return }
                dismiss()
                if let targetUid,
                    !(navigationController?.topViewController is LNIMChatViewController) {
                    pushToChat(uid: targetUid)
                }
                completionHandler?(orderNo)
            }
            if let skillId {
                LNOrderManager.shared.createOrder(
                    skillId: skillId, count: curCount, remark: extra, scene: scene, handler: handler)
            } else if let qrCode {
                LNOrderManager.shared.createQRCodeOrder(
                    data: qrCode, count: curCount, extra: extra, scene: scene, handler: handler)
            }
        }), for: .touchUpInside)
        container.addSubview(confirmButton)
        confirmButton.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(12)
            make.top.equalTo(stackView.snp.bottom).offset(15)
            make.bottom.equalToSuperview().offset(commonBottomInset)
            make.height.equalTo(47)
        }
    }
    
    private func buildBillInfo() -> UIView {
        let container = UIView()
        container.backgroundColor = .fill
        container.layer.cornerRadius = 12
        container.onTap { [weak self] in
            guard let self else { return }
            endEditing(true)
        }
        
        let stackView = UIStackView()
        stackView.axis = .vertical
        container.addSubview(stackView)
        stackView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        
        stackView.addArrangedSubview(buildUserInfo())
        stackView.addArrangedSubview(buildPrice())
        stackView.addArrangedSubview(buildDiscount())
        stackView.addArrangedSubview(buildCost())
        
        return container
    }
    
    private func buildUserInfo() -> UIView {
        let container = UIView()
        container.isUserInteractionEnabled = false
        container.snp.makeConstraints { make in
            make.height.equalTo(83)
        }
        
        let skillTag = UIImageView()
        skillTag.image = .icOrderSkillBg
        container.addSubview(skillTag)
        skillTag.snp.makeConstraints { make in
            make.leading.top.equalToSuperview()
        }
        
        avatar.layer.cornerRadius = 30
        avatar.layer.borderWidth = 2
        avatar.layer.borderColor = UIColor.fill.cgColor
        avatar.backgroundColor = .fill
        avatar.clipsToBounds = true
        container.addSubview(avatar)
        avatar.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.top.equalToSuperview().offset(-8)
            make.width.height.equalTo(60)
        }
        
        gameNameLabel.font = .heading_h5
        gameNameLabel.textColor = .text_1
        gameNameLabel.textAlignment = .center
        skillTag.addSubview(gameNameLabel)
        gameNameLabel.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.horizontalEdges.equalToSuperview().inset(14)
            make.width.lessThanOrEqualTo(82)
        }
        
        nameLabel.font = .heading_h4
        nameLabel.textColor = .text_5
        container.addSubview(nameLabel)
        nameLabel.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.top.equalTo(avatar.snp.bottom).offset(3)
        }
        
        let line = UIView()
        line.backgroundColor = .fill_2
        container.addSubview(line)
        line.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(12)
            make.height.equalTo(1)
            make.bottom.equalToSuperview()
        }
        
        return container
    }
    
    private func buildPrice() -> UIView {
        let container = UIView()
        container.snp.makeConstraints { make in
            make.height.equalTo(49)
        }
        
        let titleLabel = UILabel()
        titleLabel.font = .heading_h5
        titleLabel.textColor = .text_5
        titleLabel.text = .init(key: "A00128")
        container.addSubview(titleLabel)
        titleLabel.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(12)
            make.centerY.equalToSuperview()
        }
        
        let coin = UIImageView.coinImageView()
        container.addSubview(coin)
        coin.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.leading.equalTo(titleLabel.snp.trailing).offset(6)
            make.width.height.equalTo(18)
        }
        
        priceLabel.font = .body_m
        priceLabel.textColor = .text_5
        container.addSubview(priceLabel)
        priceLabel.snp.makeConstraints { make in
            make.leading.equalTo(coin.snp.trailing).offset(2)
            make.centerY.equalToSuperview()
        }
        
        countLabel.font = .body_m
        countLabel.textColor = .text_5
        container.addSubview(countLabel)
        countLabel.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalToSuperview().offset(-16)
        }
        
        countEditView.isHidden = true
        container.addSubview(countEditView)
        countEditView.snp.makeConstraints { make in
            make.verticalEdges.equalToSuperview()
            make.trailing.equalToSuperview()
        }
        
        addButton.setTitle("+", for: .normal)
        addButton.setTitleColor(.text_4, for: .normal)
        addButton.setTitleColor(.text_2, for: .disabled)
        addButton.backgroundColor = .primary_1
        addButton.layer.cornerRadius = 12
        addButton.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            curCount += 1
        }), for: .touchUpInside)
        countEditView.addSubview(addButton)
        addButton.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalToSuperview().offset(-12)
            make.width.height.equalTo(24)
        }
        
        customCountLabel.font = .body_m
        customCountLabel.textColor = .text_5
        countEditView.addSubview(customCountLabel)
        customCountLabel.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalTo(addButton.snp.leading).offset(-10)
        }
        
        minuButton.setTitle("-", for: .normal)
        minuButton.setTitleColor(.text_4, for: .normal)
        minuButton.setTitleColor(.text_2, for: .disabled)
        minuButton.backgroundColor = .primary_1
        minuButton.layer.cornerRadius = 12
        minuButton.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            self.curCount -= 1
        }), for: .touchUpInside)
        countEditView.addSubview(minuButton)
        minuButton.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalTo(customCountLabel.snp.leading).offset(-10)
            make.width.height.equalTo(24)
            make.leading.equalToSuperview()
        }
        
        return container
    }
    
    private func buildDiscount() -> UIView {
        discountView.snp.makeConstraints { make in
            make.height.equalTo(49)
        }
        
        let titleLabel = UILabel()
        titleLabel.font = .heading_h5
        titleLabel.textColor = .text_5
        titleLabel.text = .init(key: "A00129")
        discountView.addSubview(titleLabel)
        titleLabel.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(12)
            make.centerY.equalToSuperview()
        }
        
        discountView.addSubview(newbieView)
        newbieView.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.leading.equalTo(titleLabel.snp.trailing).offset(8)
        }
        
        discountCoinLabel.font = .heading_h3
        discountCoinLabel.textColor = .init(hex: "#FF6F32")
        discountView.addSubview(discountCoinLabel)
        discountCoinLabel.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalToSuperview().offset(-12)
        }
        
        let coin = UIImageView.coinImageView()
        discountView.addSubview(coin)
        coin.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalTo(discountCoinLabel.snp.leading).offset(-2)
            make.width.height.equalTo(20)
        }
        
        return discountView
    }
    
    private func buildCost() -> UIView {
        let container = UIView()
        container.isUserInteractionEnabled = false
        container.snp.makeConstraints { make in
            make.height.equalTo(49)
        }
        
        costLabel.font = .heading_h1
        costLabel.textColor = .text_5
        container.addSubview(costLabel)
        costLabel.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalToSuperview().offset(-12)
        }
        
        let coin = UIImageView.coinImageView()
        container.addSubview(coin)
        coin.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalTo(costLabel.snp.leading).offset(-2)
            make.width.height.equalTo(24)
        }
        
        let totalLabel = UILabel()
        totalLabel.text = .init(key: "A00124")
        totalLabel.font = .body_m
        totalLabel.textColor = .text_5
        container.addSubview(totalLabel)
        totalLabel.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalTo(coin.snp.leading).offset(-2)
        }
        
        return container
    }
    
    private func buildExtra() -> UIView {
        extraView.isHidden = true
        extraView.backgroundColor = .fill
        extraView.layer.cornerRadius = 12
        extraView.snp.makeConstraints { make in
            make.height.equalTo(50)
        }
        
        let titleLabel = UILabel()
        titleLabel.font = .heading_h5
        titleLabel.text = .init(key: "A00086")
        titleLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal)
        titleLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
        titleLabel.textColor = .text_5
        extraView.addSubview(titleLabel)
        titleLabel.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(12)
            make.centerY.equalToSuperview()
        }
        
        extraInput.placeholder = .init(key: "A00125", LNOrderManager.orderExtraMaxLength)
        extraInput.font = .body_s
        extraInput.textColor = .text_5
        extraInput.clearButtonMode = .whileEditing
        extraInput.delegate = self
        extraInput.visibleView = extraView
        extraView.addSubview(extraInput)
        extraInput.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.leading.equalTo(titleLabel.snp.trailing).offset(8)
            make.trailing.equalToSuperview().offset(-12)
        }
        
        return extraView
    }
    
    private func buildWalletInfo() -> UIView {
        let container = UIView()
        container.isUserInteractionEnabled = false
        container.backgroundColor = .fill
        container.layer.cornerRadius = 12
        container.snp.makeConstraints { make in
            make.height.equalTo(66)
        }
        
        let icon = UIImageView()
        icon.image = .icWalletWithBg
        container.addSubview(icon)
        icon.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.leading.equalToSuperview().offset(12)
        }
        
        let infoView = UIView()
        container.addSubview(infoView)
        infoView.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.leading.equalTo(icon.snp.trailing).offset(6)
        }
        
        let titleLabel = UILabel()
        titleLabel.text = .init(key: "A00126")
        titleLabel.font = .heading_h5
        titleLabel.textColor = .text_5
        infoView.addSubview(titleLabel)
        titleLabel.snp.makeConstraints { make in
            make.leading.top.equalToSuperview()
            make.trailing.equalToSuperview()
        }
        
        curCoinLabel.text = myWalletInfo.coin.toDisplay
        curCoinLabel.font = .body_m
        curCoinLabel.textColor = .text_3
        infoView.addSubview(curCoinLabel)
        curCoinLabel.snp.makeConstraints { make in
            make.trailing.bottom.equalToSuperview()
            make.top.equalTo(titleLabel.snp.bottom).offset(2)
        }
        
        let coin = UIImageView.coinImageView()
        infoView.addSubview(coin)
        coin.snp.makeConstraints { make in
            make.centerY.equalTo(curCoinLabel)
            make.leading.equalToSuperview()
            make.trailing.equalTo(curCoinLabel.snp.leading).offset(-2)
            make.width.height.equalTo(16)
        }
        
        let check = UIImageView()
        check.image = .icCheck
        container.addSubview(check)
        check.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalToSuperview().offset(-12)
            make.width.height.equalTo(22)
        }
        
        return container
    }
}

#if DEBUG

import SwiftUI

struct LNCreateOrderPanelPreview: UIViewRepresentable {
    func makeUIView(context: Context) -> some UIView {
        let container = UIView()
        container.backgroundColor = .lightGray
        
        let view = LNCreateOrderPanel()
        view.popup(container)
        
        return container
    }
    
    func updateUIView(_ uiView: UIViewType, context: Context) { }
}

#Preview(body: {
    LNCreateOrderPanelPreview()
})
#endif // DEBUG
