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

import Foundation
import UIKit
import SnapKit
import Combine


extension UIView {
    func pushToCreateOrder(_ skillDetail: LNGameMateSkillDetailVO, count: Int = 1) {
        let vc = LNCreateOrderViewController()
        vc.loadSkill(skillDetail, count: count)
        navigationController?.pushViewController(vc, animated: true)
    }
    
    func pushToCreateOrder(_ qrCode: LNQRCodeDetailResponse) {
        let vc = LNCreateOrderViewController()
        vc.loadQRData(qrCode)
        navigationController?.pushViewController(vc, animated: true)
    }
}


class LNCreateOrderViewController: LNViewController {
    private var skill: LNGameMateSkillDetailVO?
    private var qrDetail: LNQRCodeDetailResponse?
    
    private let avatar = UIImageView()
    private let nameLabel = UILabel()
    private let starLabel = UILabel()
    
    private let skillIc = UIImageView()
    private let skillNameLabel = UILabel()
    private let skillPriceLabel = UILabel()
    private let skillUnitLabel = UILabel()
    
    private let countLabel = UILabel()
    private let minuButton = UIButton()
    private let addButton = UIButton()
    private var curCount = 1 {
        didSet {
            countLabel.text = "\(curCount)"
            if curCount <= 1 {
                minuButton.isEnabled = false
            } else {
                minuButton.isEnabled = true
            }
            updateCost()
        }
    }
    
    private let extraInput = UITextField()
    
    private let costLabel = UILabel()
    private let orderButton = UIButton()
    
    private let emptyDiscountView = UIView()
    private let newbieDiscountView = UIView()
    private let discountView = LNNewbieDiscountView()
    private let discountCoinLabel = UILabel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupViews()
    }
    
    func loadSkill(_ detail: LNGameMateSkillDetailVO, count: Int) {
        skill = detail
        updateContent(detail)
        
        curCount = count
    }
    
    func loadQRData(_ data: LNQRCodeDetailResponse) {
        qrDetail = data
        updateContent(data)
    }
}

extension LNCreateOrderViewController: 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 LNCreateOrderViewController {
    private func updateContent(_ detail: LNGameMateSkillDetailVO) {
        avatar.showAvatar(detail.avatar)
        nameLabel.text = detail.nickname
        starLabel.text = "\(detail.star)"
        
        let skill = LNGameMateManager.shared.gameCategory(for: detail.categoryCode)
        skillIc.sd_setImage(with: URL(string: skill?.icon ?? ""))
        skillNameLabel.text = detail.categoryName
        
        skillPriceLabel.text = "\(detail.price.toDisplay)"
        skillUnitLabel.text = "/\(detail.unit)"
        curCount = 1
        
        if let discount = LNOrderManager.shared.discountFor(detail.price) {
            emptyDiscountView.isHidden = true
            newbieDiscountView.isHidden = false
            discountView.update(1 - discount)
            discountCoinLabel.text = "-\((1 - discount) * detail.price)"
        } else {
            emptyDiscountView.isHidden = false
            newbieDiscountView.isHidden = true
        }
        
        orderButton.isEnabled = true
    }
    
    private func updateContent(_ detail: LNQRCodeDetailResponse) {
        avatar.showAvatar(detail.avatar)
        nameLabel.text = detail.nickname
        starLabel.text = "\(detail.star)"
        
        skillIc.sd_setImage(with: URL(string: detail.bizCategoryIcon))
        skillNameLabel.text = detail.bizCategoryName
        
        skillPriceLabel.text = "\(detail.price.toDisplay)"
        skillUnitLabel.text = "/\(detail.unit)"
        curCount = detail.purchaseQty
        if detail.type != .normal {
            minuButton.isEnabled = false
            addButton.isEnabled = false
        }
        
        if let discount = LNOrderManager.shared.discountFor(detail.price) {
            emptyDiscountView.isHidden = true
            newbieDiscountView.isHidden = false
            discountView.update(1 - discount)
            discountCoinLabel.text = "-\((1 - discount) * detail.price)"
        } else {
            emptyDiscountView.isHidden = false
            newbieDiscountView.isHidden = true
        }
        
        orderButton.isEnabled = !detail.sellerUserNo.isMyUid
    }
    
    private func updateCost() {
        let price: Double = if let skill {
            skill.price
        } else if let qrDetail {
            qrDetail.price
        } else {
            0
        }
        let cost = price * Double(curCount)
        
        if let discount = LNOrderManager.shared.discountFor(price) {
            costLabel.text = (cost - (1 - discount) * price).toDisplay
        } else {
            costLabel.text = cost.toDisplay
        }
//        orderUnitLabel.text = "/\(curCount) \(unit)"
    }
    
    private func setupViews() {
        title = .init(key: "A00127")
        view.backgroundColor = .primary_1
        view.onTap { [weak self] in
            guard let self else { return }
            view.endEditing(true)
        }
        
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.spacing = 10
        view.addSubview(stackView)
        stackView.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(16)
            make.top.equalToSuperview().offset(16)
        }
        
        stackView.addArrangedSubview(buildUserInfo())
        stackView.addArrangedSubview(buildSkillInfo())
        stackView.addArrangedSubview(buildExtra())
        
        let menu = buildMenu()
        view.addSubview(menu)
        menu.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.bottom.equalToSuperview()
        }
    }
    
    private func buildUserInfo() -> UIView {
        let container = UIView()
        container.backgroundColor = .fill
        container.layer.cornerRadius = 12
        container.snp.makeConstraints { make in
            make.height.equalTo(60)
        }
        
        let starView = UIView()
        container.addSubview(starView)
        starView.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalToSuperview().offset(-12)
        }
        
        let star = UIImageView()
        star.image = .icStarFill
        starView.addSubview(star)
        star.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.leading.equalToSuperview()
            make.width.height.equalTo(16)
        }
        
        starLabel.font = .heading_h3
        starLabel.textColor = .text_5
        starView.addSubview(starLabel)
        starLabel.snp.makeConstraints { make in
            make.verticalEdges.equalToSuperview()
            make.leading.equalTo(star.snp.trailing).offset(4)
            make.trailing.equalToSuperview()
        }
        
        avatar.layer.cornerRadius = 20
        avatar.clipsToBounds = true
        container.addSubview(avatar)
        avatar.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(12)
            make.centerY.equalToSuperview()
            make.width.height.equalTo(40)
        }
        
        nameLabel.font = .heading_h4
        nameLabel.textColor = .text_5
        container.addSubview(nameLabel)
        nameLabel.snp.makeConstraints { make in
            make.leading.equalTo(avatar.snp.trailing).offset(8)
            make.centerY.equalToSuperview()
            make.trailing.lessThanOrEqualTo(starView.snp.leading).offset(-12)
        }
        
        return container
    }
    
    private func buildSkillInfo() -> UIView {
        let container = UIStackView()
        container.axis = .vertical
        container.spacing = 0
        container.backgroundColor = .fill
        container.layer.cornerRadius = 12
        
        container.addArrangedSubview(buildInfoView())
        container.addArrangedSubview(buildPriceView())
        container.addArrangedSubview(buildCountView())
        container.addArrangedSubview(buildDiscount())
        
        let emptyView = UIView()
        emptyView.snp.makeConstraints { make in
            make.height.equalTo(10)
        }
        container.addArrangedSubview(emptyView)
        
        return container
    }
    
    private func buildInfoView() -> UIView {
        let infoView = UIView()
        infoView.snp.makeConstraints { make in
            make.height.equalTo(40)
        }
        
        skillIc.layer.cornerRadius = 13
        skillIc.clipsToBounds = true
        infoView.addSubview(skillIc)
        skillIc.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(12)
            make.centerY.equalToSuperview()
            make.width.height.equalTo(26)
        }
        
        skillNameLabel.font = .heading_h5
        skillNameLabel.textColor = .text_5
        infoView.addSubview(skillNameLabel)
        skillNameLabel.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.leading.equalTo(skillIc.snp.trailing).offset(2)
        }
        
        let line = UIView()
        line.backgroundColor = .fill_2
        infoView.addSubview(line)
        line.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(11)
            make.bottom.equalToSuperview()
            make.height.equalTo(1)
        }
        
        return infoView
    }
    
    private func buildPriceView() -> UIView {
        let priceView = UIView()
        priceView.snp.makeConstraints { make in
            make.height.equalTo(38)
        }
        
        let priceTitleLabel = UILabel()
        priceTitleLabel.font = .heading_h5
        priceTitleLabel.textColor = .text_5
        priceTitleLabel.text = .init(key: "A00128")
        priceView.addSubview(priceTitleLabel)
        priceTitleLabel.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(12)
            make.centerY.equalToSuperview()
        }
        
        skillUnitLabel.font = .body_s
        skillUnitLabel.textColor = .text_4
        priceView.addSubview(skillUnitLabel)
        skillUnitLabel.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalToSuperview().offset(-12)
        }
        
        skillPriceLabel.font = .heading_h3
        skillPriceLabel.textColor = .text_5
        priceView.addSubview(skillPriceLabel)
        skillPriceLabel.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalTo(skillUnitLabel.snp.leading)
        }
        
        let coinIc = UIImageView.coinImageView()
        priceView.addSubview(coinIc)
        coinIc.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalTo(skillPriceLabel.snp.leading).offset(-2)
            make.width.height.equalTo(20)
        }
        
        return priceView
    }
    
    private func buildCountView() -> UIView {
        let countView = UIView()
        countView.snp.makeConstraints { make in
            make.height.equalTo(38)
        }
        
        let countTitleLabel = UILabel()
        countTitleLabel.font = .heading_h5
        countTitleLabel.textColor = .text_5
        countTitleLabel.text = .init(key: "A00122")
        countView.addSubview(countTitleLabel)
        countTitleLabel.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(12)
            make.centerY.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)
        countView.addSubview(addButton)
        addButton.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalToSuperview().offset(-12)
            make.width.height.equalTo(24)
        }
        
        countLabel.font = .body_m
        countLabel.textColor = .text_5
        countView.addSubview(countLabel)
        countLabel.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)
        countView.addSubview(minuButton)
        minuButton.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalTo(countLabel.snp.leading).offset(-10)
            make.width.height.equalTo(24)
        }
        
        return countView
    }
    
    private func buildDiscount() -> UIView {
        let discountView = UIView()
        discountView.snp.makeConstraints { make in
            make.height.equalTo(38)
        }
        
        let discountTitleLabel = UILabel()
        discountTitleLabel.font = .heading_h5
        discountTitleLabel.textColor = .text_5
        discountTitleLabel.text = .init(key: "A00129")
        discountView.addSubview(discountTitleLabel)
        discountTitleLabel.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(12)
            make.centerY.equalToSuperview()
        }
        
        emptyDiscountView.isHidden = true
        discountView.addSubview(emptyDiscountView)
        emptyDiscountView.snp.makeConstraints { make in
            make.verticalEdges.equalToSuperview()
            make.trailing.equalToSuperview()
        }
        
        let discountArrow = UIImageView.arrowImageView(size: 14)
        discountArrow.tintColor = .text_2
        emptyDiscountView.addSubview(discountArrow)
        discountArrow.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalToSuperview().offset(-12)
        }
        
        let discountDescLabel = UILabel()
        discountDescLabel.font = .body_s
        discountDescLabel.text = .init(key: "A00130")
        discountDescLabel.textColor = .text_2
        emptyDiscountView.addSubview(discountDescLabel)
        discountDescLabel.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalTo(discountArrow.snp.leading).offset(-3)
            make.leading.equalToSuperview()
        }
        
        let newbieView = buildNewbieDiscountView()
        discountView.addSubview(newbieView)
        newbieView.snp.makeConstraints { make in
            make.verticalEdges.equalToSuperview()
            make.trailing.equalToSuperview()
        }
        
        return discountView
    }
    
    private func buildNewbieDiscountView() -> UIView {
        discountCoinLabel.font = .heading_h3
        discountCoinLabel.textColor = .init(hex: "#FF6F32")
        newbieDiscountView.addSubview(discountCoinLabel)
        discountCoinLabel.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalToSuperview().offset(-10)
        }
        
        let coin = UIImageView(image: .icCoin)
        newbieDiscountView.addSubview(coin)
        coin.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalTo(discountCoinLabel.snp.leading).offset(-2)
            make.width.height.equalTo(20)
        }
        
        newbieDiscountView.addSubview(discountView)
        discountView.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalTo(coin.snp.leading).offset(-4)
        }
        
        return newbieDiscountView
    }
    
    private func buildExtra() -> UIView {
        let container = UIView()
        container.backgroundColor = .fill
        container.layer.cornerRadius = 12
        container.snp.makeConstraints { make in
            make.height.equalTo(50)
        }
        
        let titleLabel = UILabel()
        titleLabel.font = .heading_h5
        titleLabel.textColor = .text_5
        titleLabel.text = .init(key: "A00086")
        titleLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal)
        container.addSubview(titleLabel)
        titleLabel.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.leading.equalToSuperview().offset(12)
        }
        
        extraInput.font = .body_s
        extraInput.textColor = .text_5
        extraInput.placeholder = .init(key: "A00125", LNOrderManager.orderExtraMaxLength)
        extraInput.clearButtonMode = .whileEditing
        extraInput.delegate = self
        container.addSubview(extraInput)
        extraInput.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.leading.equalTo(titleLabel.snp.trailing).offset(8)
            make.trailing.equalToSuperview().offset(-12)
        }
        
        return container
    }
    
    private func buildMenu() -> UIView {
        let holder = UIView()
        
        let bottomGradient = CAGradientLayer()
        bottomGradient.colors = [
            UIColor.white.withAlphaComponent(0).cgColor,
            UIColor.white.cgColor,
            UIColor.white.cgColor
        ]
        bottomGradient.locations = [0, 0.5, 1]
        bottomGradient.startPoint = .init(x: 0, y: 0)
        bottomGradient.endPoint = .init(x: 0, y: 1)
        holder.layer.addSublayer(bottomGradient)
        holder.publisher(for: \.bounds).removeDuplicates().sink { [weak bottomGradient] newValue in
            guard let bottomGradient else { return }
            bottomGradient.frame = newValue
        }.store(in: &cancellables)
        
        let container = UIView()
        container.backgroundColor = .init(hex: "#ECF6FF")
        container.layer.cornerRadius = 23.5
        holder.addSubview(container)
        container.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(16)
            make.top.equalToSuperview().offset(16)
            make.bottom.equalToSuperview().offset(-view.safeBottomInset - 10)
        }
        
        orderButton.setBackgroundImage(.icSkillOrderLong, for: .normal)
        orderButton.setTitle(.init(key: "A00041"), for: .normal)
        orderButton.setTitleColor(.text_1, for: .normal)
        orderButton.titleLabel?.font = .heading_h3
        orderButton.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            let panel = LNCreateOrderPanel()
            if let skill {
                panel.update(skill, count: curCount, extra: extraInput.text ?? "")
            } else if let qrDetail {
                panel.update(qrDetail, count: curCount, extra: extraInput.text ?? "")
            } else { return }
            panel.completionHandler = { [weak self] orderId in
                guard let self else { return }
                navigationController?.viewControllers.removeAll { $0 is LNCreateOrderViewController }
            }
            panel.popup()
        }), for: .touchUpInside)
        container.addSubview(orderButton)
        orderButton.snp.makeConstraints { make in
            make.trailing.equalToSuperview()
            make.verticalEdges.equalToSuperview()
        }
        
        let descView = UIView()
        container.addSubview(descView)
        descView.snp.makeConstraints { make in
            make.leading.verticalEdges.equalToSuperview()
            make.trailing.equalTo(orderButton.snp.leading)
        }
        
        let priceView = UIView()
        descView.addSubview(priceView)
        priceView.snp.makeConstraints { make in
            make.center.equalToSuperview()
        }
        
        let coin = UIImageView.coinImageView()
        priceView.addSubview(coin)
        coin.snp.makeConstraints { make in
            make.leading.centerY.equalToSuperview()
            make.width.height.equalTo(20)
        }
        
        costLabel.font = .heading_h2
        costLabel.textColor = .text_5
        priceView.addSubview(costLabel)
        costLabel.snp.makeConstraints { make in
            make.verticalEdges.equalToSuperview()
            make.leading.equalTo(coin.snp.trailing).offset(4)
            make.trailing.equalToSuperview()
        }
        
        return holder
    }
}

#if DEBUG

import SwiftUI

struct LNCreateOrderViewControllerPreview: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> some UIViewController {
        LNCreateOrderViewController()
    }
    
    func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) { }
}

#Preview(body: {
    LNCreateOrderViewControllerPreview()
})
#endif
