//
//  LNIMChatGameMateOrderView.swift
//  Lanu
//
//  Created by OneeChan on 2025/12/31.
//

import Foundation
import UIKit
import SnapKit
import Combine


class LNIMChatGameMateOrderView: UIView {
    private let stackView = UIStackView()
    
    private let gameIc = UIImageView()
    private let titleLabel = UILabel()
    private let titleArrow = UIImageView.arrowImageView(size: 12)
    private let descLabel = UILabel()
    
    private let contentArrow = UIImageView.arrowImageView(size: 12)
    
    private let replyView = UIView()
    private let replyRemainLabel = UILabel()
    private var countDownTimer: Timer?
    
    private let goCallView = UIView()
    
    private let actionView = UIView()
    
    private let extraView = UIView()
    private let extraLabel = UILabel()
    
    private var curOrder: LNUnfinishedOrderVO?
    
    weak var viewModel: LNIMChatViewModel? {
        didSet {
            viewModel?.$myOrders.sink { [weak self] list in
                guard let self else { return }
                isHidden = list.isEmpty == true
                if let first = list.first {
                    update(first)
                }
            }.store(in: &cancellables)
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupViews()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension LNIMChatGameMateOrderView {
    private func startCountDown() {
        stopCountDown()
        
        updateRemain()
        let timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ in
            guard let self else { return }
            if updateRemain() {
                stopCountDown()
                viewModel?.getUnfinishOrder()
            }
        }
        RunLoop.current.add(timer, forMode: .common)
        countDownTimer = timer
    }
    
    private func stopCountDown() {
        countDownTimer?.invalidate()
        countDownTimer = nil
    }
    
    @discardableResult
    private func updateRemain() -> Bool {
        guard let curOrder else { return true }
        let remain = 3600 - (Int(curTime) - curOrder.createTime / 1_000)
        replyRemainLabel.text = remain.timeCountDisplay
        return remain <= 0
    }
}

extension LNIMChatGameMateOrderView {
    private func update(_ order: LNUnfinishedOrderVO) {
        curOrder = order
        
        let isCreator = order.buyerUserNo.isMyUid
        
        gameIc.sd_setImage(with: URL(string: order.categoryIcon))
        descLabel.text = "\(order.bizCategoryName)/\(order.unit) x \(order.purchaseQty)"
        extraLabel.text = .init(key: "A00056", order.customerRemark)
        
        actionView.isHidden = true
        extraView.isHidden = true
        replyView.isHidden = true
        goCallView.isHidden = true
        titleArrow.isHidden = true
        contentArrow.isHidden = true
        stopCountDown()
        
        switch order.status {
        case .created, .waitingForAccept:
            titleLabel.text = .init(key: "A00078")
            titleArrow.isHidden = false
            replyView.isHidden = false
            let remain = 3600 - (Int(curTime) - order.createTime / 1_000)
            replyRemainLabel.text = remain.timeCountDisplay
            startCountDown()
            if !isCreator {
                actionView.isHidden = false
            }
        case .accepted:
            titleLabel.text = .init(key: "A00079")
            contentArrow.isHidden = false
            if !isCreator, !order.customerRemark.isEmpty {
                extraView.isHidden = false
            }
        case .servicing:
            titleLabel.text = .init(key: "A00080")
            titleArrow.isHidden = false
            goCallView.isHidden = false
            if !isCreator, !order.customerRemark.isEmpty {
                extraView.isHidden = false
            }
        case .completed, .refunded, .rejected, .serviceDone, .cancelled:
            break
        }
        
        stackView.snp.updateConstraints { make in
            make.verticalEdges.equalToSuperview().inset((!extraView.isHidden || !actionView.isHidden) ? 6 : 11)
        }
    }
    
    private func setupViews() {
        let container = UIView()
        container.backgroundColor = .fill
        container.layer.cornerRadius = 12
        addSubview(container)
        container.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(16)
            make.bottom.equalToSuperview()
            make.top.equalToSuperview().offset(8)
        }
        
        stackView.axis = .vertical
        stackView.spacing = 6
        container.addSubview(stackView)
        stackView.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(16)
            make.verticalEdges.equalToSuperview().inset(11)
        }
        
        let orderView = buildOrderView()
        stackView.addArrangedSubview(orderView)
        
        let actionView = buildActionView()
        stackView.addArrangedSubview(actionView)
        
        let extraView = buildExtraView()
        stackView.addArrangedSubview(extraView)
    }
    
    private func buildOrderView() -> UIView {
        let stackView = UIStackView()
        stackView.spacing = 16
        stackView.snp.makeConstraints { make in
            make.height.equalTo(50)
        }
        
        let infoView = buildInfoView()
        stackView.addArrangedSubview(infoView)
        
        let replyView = buildReplyView()
        stackView.addArrangedSubview(replyView)
        
        let callView = buildCallView()
        stackView.addArrangedSubview(callView)
        
        contentArrow.tintColor = .text_4
        stackView.addSubview(contentArrow)
        contentArrow.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalToSuperview()
        }
        
        return stackView
    }
    
    private func buildInfoView() -> UIView {
        let container = UIView()
        container.onTap { [weak self] in
            guard let self else { return }
            if curOrder?.buyerUserNo.isMyUid != false {
                pushToOrderList()
            } else {
                pushToOrderRecord()
            }
        }
        
        container.addSubview(gameIc)
        gameIc.snp.makeConstraints { make in
            make.leading.equalToSuperview()
            make.verticalEdges.equalToSuperview()
            make.width.height.equalTo(50)
        }
        
        let textView = UIView()
        container.addSubview(textView)
        textView.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.leading.equalTo(gameIc.snp.trailing).offset(1)
            make.trailing.lessThanOrEqualToSuperview()
        }
        
        titleLabel.font = .heading_h5
        titleLabel.textColor = .text_5
        textView.addSubview(titleLabel)
        titleLabel.snp.makeConstraints { make in
            make.leading.equalToSuperview()
            make.top.equalToSuperview()
        }
        
        titleArrow.tintColor = .text_4
        textView.addSubview(titleArrow)
        titleArrow.snp.makeConstraints { make in
            make.leading.equalTo(titleLabel.snp.trailing).offset(5)
            make.centerY.equalTo(titleLabel)
            make.trailing.lessThanOrEqualToSuperview()
        }
        
        descLabel.font = .body_s
        descLabel.textColor = .text_3
        textView.addSubview(descLabel)
        descLabel.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.bottom.equalToSuperview()
            make.top.equalTo(titleLabel.snp.bottom).offset(2)
        }
        
        return container
    }
    
    private func buildReplyView() -> UIView {
        replyView.isHidden = true
        
        let replyTitleLabel = UILabel()
        replyTitleLabel.font = .body_s
        replyTitleLabel.text = .init(key: "A00081")
        replyTitleLabel.textColor = .text_5
        replyTitleLabel.textAlignment = .center
        replyView.addSubview(replyTitleLabel)
        replyTitleLabel.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.top.equalToSuperview()
        }
        
        replyRemainLabel.font = .heading_h5
        replyRemainLabel.textColor = .text_5
        replyView.addSubview(replyRemainLabel)
        replyRemainLabel.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.bottom.equalToSuperview()
            make.top.equalTo(replyTitleLabel.snp.bottom).offset(1)
            make.leading.greaterThanOrEqualToSuperview()
        }
        
        return replyView
    }
    
    private func buildCallView() -> UIView {
        goCallView.isHidden = true
        goCallView.onTap { [weak self] in
            guard let self else { return }
            guard let uid = viewModel?.userId else { return }
            
            LNIMManager.shared.makeVoiceCall(uid: uid)
        }
        
        let callButton = UIButton()
        callButton.setTitle(.init(key: "C00016"), for: .normal)
        callButton.contentEdgeInsets = .init(top: 0, left: 17, bottom: 0, right: 17)
        callButton.titleLabel?.font = .heading_h5
        callButton.setTitleColor(.text_1, for: .normal)
        callButton.setBackgroundImage(.primary_8, for: .normal)
        callButton.layer.cornerRadius = 12
        callButton.clipsToBounds = true
        callButton.setContentHuggingPriority(.required, for: .horizontal)
        callButton.setContentCompressionResistancePriority(.required, for: .horizontal)
        callButton.snp.makeConstraints { make in
            make.height.equalTo(24)
        }
        callButton.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            guard let uid = viewModel?.userId else { return }
            
            LNIMManager.shared.makeVoiceCall(uid: uid)
        }), for: .touchUpInside)
        
        goCallView.addSubview(callButton)
        callButton.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.centerY.equalToSuperview()
        }
        
        return goCallView
    }
    
    private func buildActionView() -> UIView {
        actionView.snp.makeConstraints { make in
            make.height.equalTo(40)
        }
        
        let reject = UIButton()
        reject.setTitle(.init(key: "A00082"), for: .normal)
        reject.setTitleColor(.text_4, for: .normal)
        reject.titleLabel?.font = .body_s
        reject.contentEdgeInsets = .init(top: 7, left: 40, bottom: 7, right: 40)
        reject.layer.cornerRadius = 15
        reject.layer.borderWidth = 1
        reject.layer.borderColor = .text_3
        reject.setContentHuggingPriority(.defaultHigh, for: .horizontal)
        reject.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            guard let curOrder else { return }
            LNOrderManager.shared.rejectOrder(orderId: curOrder.orderId) { success in }
        }), for: .touchUpInside)
        actionView.addSubview(reject)
        reject.snp.makeConstraints { make in
            make.leading.equalToSuperview()
            make.centerY.equalToSuperview()
            make.height.equalTo(30)
        }
        
        let accept = UIButton()
        accept.setTitle(.init(key: "A00083"), for: .normal)
        accept.setTitleColor(.text_1, for: .normal)
        accept.titleLabel?.font = .heading_h5
        accept.layer.cornerRadius = 15
        accept.clipsToBounds = true
        accept.setBackgroundImage(.primary_8, for: .normal)
        accept.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            guard let curOrder else { return }
            LNOrderManager.shared.acceptOrder(orderId: curOrder.orderId) { success in }
        }), for: .touchUpInside)
        actionView.addSubview(accept)
        accept.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.height.equalTo(30)
            make.leading.equalTo(reject.snp.trailing).offset(12)
            make.trailing.equalToSuperview()
        }
        
        return actionView
    }
    
    private func buildExtraView() -> UIView {
        let line = UIView()
        line.backgroundColor = .fill_2
        extraView.addSubview(line)
        line.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(-4)
            make.top.equalToSuperview()
            make.height.equalTo(0.5)
        }
        
        extraLabel.font = .body_xs
        extraLabel.textColor = .text_4
        extraLabel.numberOfLines = 0
        extraView.addSubview(extraLabel)
        extraLabel.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.top.equalTo(line.snp.bottom).offset(5)
            make.bottom.equalToSuperview().offset(-2)
        }
        
        return extraView
    }
}


#if DEBUG

import SwiftUI

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

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