//
//  LNOrderRecordCell.swift
//  Lanu
//
//  Created by OneeChan on 2025/12/24.
//

import Foundation
import UIKit
import SnapKit


class LNOrderRecordCell: UITableViewCell {
    private let dateLabel = UILabel()
    private let stateLabel = UILabel()
    
    private let gameIc = UIImageView()
    private let gameNameLabel = UILabel()
    private let orderIdLabel = UILabel()
    
    private let discountView = UIView()
    private let totalLabel = UILabel()
    private let countLabel = UILabel()
    
    private let avatar = UIImageView()
    private let nameLabel = UILabel()
    private let genderView = UIImageView()
    
    private let requestLine = UIView()
    private let requestView = UIView()
    private let requestLabel = UILabel()
    
    private let menuView = UIView()
    private let rejectButton = UIButton()
    private let acceptButton = UIButton()
    private let startButton = UIButton()
    private let completeButton = UIButton()
    private let commitButton = UIButton()

    private var curItem: LNOrderRecordItemVO?
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        setupViews()
    }
    
    func update(_ item: LNOrderRecordItemVO) {
        gameIc.sd_setImage(with: URL(string: item.categoryIcon))
        dateLabel.text = TimeInterval(item.createTime / 1_000).formattedFullDateWithTime()
        gameNameLabel.text = item.bizCategoryName
        orderIdLabel.text = item.orderId
        
        discountView.isHidden = item.totalAmount >= item.price * Double(item.purchaseQty)
        totalLabel.text = item.totalAmount.toDisplay
        countLabel.text = "\(item.unit) x \(item.purchaseQty)"
        
        avatar.showAvatar(item.avatar)
        nameLabel.text = item.nickname
        genderView.image = switch item.gender {
        case .unknow: nil
        case .male: .icGenderMale
        case .female: .icGenderFemale
        }
        requestLabel.text = item.customerRemark
        requestLine.isHidden = item.customerRemark.isEmpty
        requestView.isHidden = item.customerRemark.isEmpty
        
        curItem = item
        
        updateByStateChanged()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension LNOrderRecordCell {
    private func updateByStateChanged() {
        guard let curItem else { return }
        
        menuView.isHidden = true
        rejectButton.isHidden = true
        acceptButton.isHidden = true
        startButton.isHidden = true
        completeButton.isHidden = true
        commitButton.isHidden = true
        
        if curItem.refundApply {
            stateLabel.text = .init(key: "A00052")
            stateLabel.textColor = .init(hex: "#F23051")
            
            menuView.isHidden = false
            commitButton.isHidden = false
            return
        }
        
        switch curItem.status {
        case .created, .waitingForAccept:
            stateLabel.text = .init(key: "A00055")
            stateLabel.textColor = .init(hex: "#FFB836")
            
            menuView.isHidden = false
            rejectButton.isHidden = false
            acceptButton.isHidden = false
        case .completed:
            stateLabel.text = .init(key: "A00137")
            stateLabel.textColor = .text_6
        case .refunded:
            stateLabel.text = .init(key: "A00138")
            stateLabel.textColor = .text_3
        case .accepted:
            stateLabel.text = .init(key: "A00165")
            stateLabel.textColor = .text_6
            
            menuView.isHidden = false
            startButton.isHidden = false
        case .rejected:
            stateLabel.text = .init(key: "A00140")
            stateLabel.textColor = .text_3
        case .servicing:
            stateLabel.text = .init(key: "A00080")
            stateLabel.textColor = .init(hex: "#FFB836")
            
            menuView.isHidden = false
            completeButton.isHidden = false
        case .serviceDone:
            stateLabel.text = .init(key: "A00137")
            stateLabel.textColor = .text_6
        case .cancelled:
            stateLabel.text = .init(key: "A00152")
            stateLabel.textColor = .text_3
        }
    }
    
    private func setupViews() {
        backgroundColor = .clear
        
        let container = UIView()
        container.backgroundColor = .fill
        container.layer.cornerRadius = 12
        contentView.addSubview(container)
        container.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(16)
            make.top.equalToSuperview().offset(10)
            make.bottom.equalToSuperview()
        }
        
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.spacing = 0
        container.addSubview(stackView)
        stackView.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(12)
            make.top.equalToSuperview().offset(2)
            make.bottom.equalToSuperview().offset(-8).priority(.medium)
        }
        
        let top = buildTopView()
        stackView.addArrangedSubview(top)
        
        let line = UIView()
        line.backgroundColor = .fill_2
        line.snp.makeConstraints { make in
            make.height.equalTo(0.5).priority(.medium)
        }
        stackView.addArrangedSubview(line)
        
        let orderInfo = buildOrderInfo()
        stackView.addArrangedSubview(orderInfo)
        
        let userInfo = buildUserInfoView()
        stackView.addArrangedSubview(userInfo)
        
        let menu = buildBottomView()
        stackView.addArrangedSubview(menu)
    }
    
    private func buildTopView() -> UIView {
        let container = UIView()
        container.snp.makeConstraints { make in
            make.height.equalTo(30)
        }
        
        stateLabel.font = .heading_h5
        container.addSubview(stateLabel)
        stateLabel.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalToSuperview()
            make.width.height.equalTo(0).priority(.low)
        }
        
        dateLabel.font = .body_xs
        dateLabel.textColor = .text_3
        container.addSubview(dateLabel)
        dateLabel.snp.makeConstraints { make in
            make.leading.equalToSuperview()
            make.centerY.equalToSuperview()
            make.trailing.lessThanOrEqualTo(stateLabel.snp.leading).offset(-5)
        }
        
        return container
    }
    
    private func buildOrderInfo() -> UIView {
        let container = UIView()
        container.snp.makeConstraints { make in
            make.height.equalTo(54)
        }
        
        let price = buildPriceView()
        container.addSubview(price)
        price.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalToSuperview()
        }
        
        let infoView = buildGameInfoView()
        container.addSubview(infoView)
        infoView.snp.makeConstraints { make in
            make.leading.equalToSuperview()
            make.centerY.equalToSuperview().inset(4)
            make.trailing.lessThanOrEqualTo(price.snp.leading).offset(-12)
        }
        
        return container
    }
    
    private func buildUserInfoView() -> UIView {
        let container = UIView()
        container.backgroundColor = .fill_1
        container.layer.cornerRadius = 12
        
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.spacing = 4
        container.addSubview(stackView)
        stackView.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(8)
        }
        
        let userView = UIView()
        userView.onTap { [weak self] in
            guard let self else { return }
            guard let curItem else { return }
            pushToProfile(uid: curItem.buyerUserNo)
        }
        userView.snp.makeConstraints { make in
            make.height.equalTo(23).priority(.medium)
        }
        stackView.addArrangedSubview(userView)
        
        avatar.layer.cornerRadius = 11.5
        avatar.clipsToBounds = true
        userView.addSubview(avatar)
        avatar.snp.makeConstraints { make in
            make.leading.equalToSuperview()
            make.centerY.equalToSuperview()
            make.width.height.equalTo(23)
        }
        
        nameLabel.font = .body_s
        nameLabel.textColor = .text_5
        userView.addSubview(nameLabel)
        nameLabel.snp.makeConstraints { make in
            make.centerY.equalTo(avatar)
            make.leading.equalTo(avatar.snp.trailing).offset(8)
        }
        
        userView.addSubview(genderView)
        genderView.snp.makeConstraints { make in
            make.centerY.equalTo(avatar)
            make.leading.equalTo(nameLabel.snp.trailing).offset(3)
            make.width.height.equalTo(14)
        }
        
        requestLine.backgroundColor = .fill_3
        requestLine.snp.makeConstraints { make in
            make.height.equalTo(0.5)
        }
        stackView.addArrangedSubview(requestLine)
        
        stackView.addArrangedSubview(requestView)
        
        let titleLabel = UILabel()
        titleLabel.font = .heading_h5
        titleLabel.textColor = .text_4
        titleLabel.text = .init(key: "A00167")
        requestView.addSubview(titleLabel)
        titleLabel.snp.makeConstraints { make in
            make.leading.equalToSuperview()
            make.top.equalToSuperview()
        }
        
        requestLabel.font = .body_xs
        requestLabel.textColor = .text_4
        requestLabel.numberOfLines = 0
        requestLabel.setContentHuggingPriority(.defaultHigh, for: .vertical)
        requestLabel.setContentCompressionResistancePriority(.defaultHigh , for: .vertical)
        requestView.addSubview(requestLabel)
        requestLabel.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.top.equalTo(titleLabel.snp.bottom)
            make.bottom.equalToSuperview()
        }
        
        return container
    }
    
    private func buildBottomView() -> UIView {
        menuView.snp.makeConstraints { make in
            make.height.equalTo(38)
        }
        
        let stackView = UIStackView()
        stackView.axis = .horizontal
        stackView.spacing = 6
        menuView.addSubview(stackView)
        stackView.snp.makeConstraints { make in
            make.trailing.equalToSuperview()
            make.bottom.equalToSuperview()
        }
        
        rejectButton.setTitle(.init(key: "A00168"), for: .normal)
        rejectButton.setTitleColor(.text_3, for: .normal)
        rejectButton.titleLabel?.font = .heading_h5
        rejectButton.layer.cornerRadius = 15
        rejectButton.layer.borderWidth = 1
        rejectButton.layer.borderColor = UIColor.fill_3.cgColor
        rejectButton.contentEdgeInsets = .init(top: 8, left: 18, bottom: 8, right: 18)
        rejectButton.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            guard let curItem else { return }
            LNOrderManager.shared.rejectOrder(orderId: curItem.orderId) { [weak self] success in
                guard let self else { return }
                guard success else { return }
                curItem.status = .rejected
                updateByStateChanged()
            }
        }), for: .touchUpInside)
        rejectButton.snp.makeConstraints { make in
            make.height.equalTo(30)
        }
        stackView.addArrangedSubview(rejectButton)
        
        acceptButton.setTitle(.init(key: "A00169"), for: .normal)
        acceptButton.setTitleColor(.text_1, for: .normal)
        acceptButton.titleLabel?.font = .heading_h5
        acceptButton.layer.cornerRadius = 15
        acceptButton.setBackgroundImage(.primary_8, for: .normal)
        acceptButton.contentEdgeInsets = .init(top: 8, left: 10, bottom: 8, right: 10)
        acceptButton.clipsToBounds = true
        acceptButton.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            guard let curItem else { return }
            LNOrderManager.shared.acceptOrder(orderId: curItem.orderId) { [weak self] success in
                guard let self else { return }
                guard success else { return }
                curItem.status = .accepted
                updateByStateChanged()
            }
        }), for: .touchUpInside)
        acceptButton.snp.makeConstraints { make in
            make.height.equalTo(30)
        }
        stackView.addArrangedSubview(acceptButton)
        
        startButton.setTitle(.init(key: "A00064"), for: .normal)
        startButton.setTitleColor(.text_1, for: .normal)
        startButton.titleLabel?.font = .heading_h5
        startButton.layer.cornerRadius = 15
        startButton.setBackgroundImage(.primary_8, for: .normal)
        startButton.contentEdgeInsets = .init(top: 8, left: 10, bottom: 8, right: 10)
        startButton.clipsToBounds = true
        startButton.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            guard let curItem else { return }
            LNOrderManager.shared.startOrderService(orderId: curItem.orderId) { [weak self] success in
                guard let self else { return }
                guard success else { return }
                curItem.status = .servicing
                updateByStateChanged()
            }
        }), for: .touchUpInside)
        startButton.snp.makeConstraints { make in
            make.height.equalTo(30)
        }
        stackView.addArrangedSubview(startButton)
        
        completeButton.setTitle(.init(key: "A00151"), for: .normal)
        completeButton.setTitleColor(.text_1, for: .normal)
        completeButton.titleLabel?.font = .heading_h5
        completeButton.layer.cornerRadius = 15
        completeButton.setBackgroundImage(.primary_8, for: .normal)
        completeButton.contentEdgeInsets = .init(top: 8, left: 10, bottom: 8, right: 10)
        completeButton.clipsToBounds = true
        completeButton.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            guard let curItem else { return }
            LNOrderManager.shared.finishOrderService(orderId: curItem.orderId) { [weak self] success in
                guard let self else { return }
                guard success else { return }
                curItem.status = .serviceDone
                updateByStateChanged()
            }
        }), for: .touchUpInside)
        completeButton.snp.makeConstraints { make in
            make.height.equalTo(30)
        }
        stackView.addArrangedSubview(completeButton)
        
        commitButton.setTitle(.init(key: "A00170"), for: .normal)
        commitButton.setTitleColor(.text_6, for: .normal)
        commitButton.titleLabel?.font = .heading_h5
        commitButton.layer.cornerRadius = 15
        commitButton.setBackgroundImage(.primary_7, for: .normal)
        commitButton.contentEdgeInsets = .init(top: 8, left: 10, bottom: 8, right: 10)
        commitButton.clipsToBounds = true
        commitButton.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            guard let curItem else { return }
            pushToProtest(curItem.orderId) { [weak self] in
                guard let self else { return }
                curItem.status = .serviceDone
                updateByStateChanged()
            }
        }), for: .touchUpInside)
        commitButton.snp.makeConstraints { make in
            make.height.equalTo(30)
        }
        stackView.addArrangedSubview(commitButton)
        
        let cover = UIView()
        cover.backgroundColor = .fill
        cover.layer.cornerRadius = 14
        cover.isUserInteractionEnabled = false
        commitButton.insertSubview(cover, at: 0)
        cover.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(1)
        }
        
        return menuView
    }
    
    private func buildGameInfoView() -> UIView {
        let container = UIView()
        
        gameIc.layer.cornerRadius = 20
        gameIc.clipsToBounds = true
        container.addSubview(gameIc)
        gameIc.snp.makeConstraints { make in
            make.leading.equalToSuperview()
            make.verticalEdges.equalToSuperview()
            make.width.height.equalTo(50)
        }
        
        let textInfo = UIView()
        container.addSubview(textInfo)
        textInfo.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.leading.equalTo(gameIc.snp.trailing).offset(8)
            make.trailing.equalToSuperview()
        }
        
        gameNameLabel.textColor = .text_5
        gameNameLabel.font = .heading_h4
        textInfo.addSubview(gameNameLabel)
        gameNameLabel.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.top.equalToSuperview()
        }
        
        orderIdLabel.font = .body_xs
        orderIdLabel.textColor = .text_5
        textInfo.addSubview(orderIdLabel)
        orderIdLabel.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.bottom.equalToSuperview()
            make.top.equalTo(gameNameLabel.snp.bottom).offset(2)
        }
        
        return container
    }
    
    private func buildPriceView() -> UIView {
        let container = UIView()
        
        totalLabel.font = .heading_h3
        totalLabel.textColor = .text_5
        container.addSubview(totalLabel)
        totalLabel.snp.makeConstraints { make in
            make.top.trailing.equalToSuperview()
        }
        
        let coin = UIImageView.coinImageView()
        container.addSubview(coin)
        coin.snp.makeConstraints { make in
            make.centerY.equalTo(totalLabel)
            make.trailing.equalTo(totalLabel.snp.leading)
            make.width.height.equalTo(16)
        }
        
        let discount = buildDiscount()
        container.addSubview(discount)
        discount.snp.makeConstraints { make in
            make.centerY.equalTo(coin)
            make.leading.equalToSuperview()
            make.trailing.equalTo(coin.snp.leading).offset(-4)
        }
        
        countLabel.font = .body_m
        countLabel.textColor = .text_5
        countLabel.textAlignment = .right
        countLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal)
        countLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
        container.addSubview(countLabel)
        countLabel.snp.makeConstraints { make in
            make.trailing.bottom.equalToSuperview()
            make.top.equalTo(totalLabel.snp.bottom)
        }
        
        return container
    }
    
    private func buildDiscount() -> UIView {
        discountView.layer.cornerRadius = 4
        discountView.backgroundColor = .init(hex: "#FF6F32")
        
        let titleLabel = UILabel()
        titleLabel.text = .init(key: "A00129")
        titleLabel.font = .body_xs
        titleLabel.textColor = .text_1
        discountView.addSubview(titleLabel)
        titleLabel.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(5)
            make.verticalEdges.equalToSuperview().inset(2)
        }
        
        return discountView
    }
}

#if DEBUG

import SwiftUI

struct LNOrderRecordCellPreview: UIViewRepresentable {
    func makeUIView(context: Context) -> some UIView {
        let container = UIView()
        container.backgroundColor = .lightGray
        
        let view = LNOrderRecordCell()
        container.addSubview(view)
        view.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.centerY.equalToSuperview()
            make.height.equalTo(133)
        }
        
        return container
    }
    
    func updateUIView(_ uiView: UIViewType, context: Context) { }
}

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