//
//  LNOrderDetailViewController.swift
//  Lanu
//
//  Created by OneeChan on 2025/11/19.
//

import Foundation
import UIKit
import SnapKit


extension UIView {
    func pushToOrderDetail(orderId: String) {
        let vc = LNOrderDetailViewController(orderId: orderId)
        navigationController?.pushViewController(vc, animated: true)
    }
}


class LNOrderDetailViewController: LNViewController {
    private let orderId: String
    
    private let backgroundIc = UIImageView()
    
    private let starView = LNFiveStarScoreView()
    private let stateIc = UIImageView()
    private let stateLabel = UILabel()
    
    private var timer: Timer?
    private let countDownLabel = UILabel()
    
    private let detailView = LNOrderDetailCardView()
    
    private let cancelButton = UIButton()
    private let refundButton = UIButton()
    private let commentButton = UIButton()
    private let completeView = UIView()
    
    private let refundView = LNOrderRefundInfoView()
    
    private var curDetail: LNOrderDetailResponse?
    
    init(orderId: String) {
        self.orderId = orderId
        super.init(nibName: nil, bundle: nil)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupViews()
        
        LNEventDeliver.addObserver(self)
        reloadDetail()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension LNOrderDetailViewController: LNOrderManagerNotify {
    func onOrderInfoChanged(orderId: String) {
        guard orderId == self.orderId else { return }
        reloadDetail()
    }
}

extension LNOrderDetailViewController {
    private func reloadDetail() {
        LNOrderManager.shared.getOrderDetail(orderId: orderId) { [weak self] detail in
            guard let self else { return }
            guard let detail else { return }
            curDetail = detail
            update(detail)
        }
    }
}

extension LNOrderDetailViewController {
    private func startCountDown() {
        stopCountDown()
            
        updateRemain()
        let timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ in
            guard let self else { return }
            if updateRemain() {
                stopCountDown()
                reloadDetail()
            }
        }
        RunLoop.current.add(timer, forMode: .common)
        self.timer = timer
    }
        
    private func stopCountDown() {
        timer?.invalidate()
        timer = nil
    }
        
    @discardableResult
    private func updateRemain() -> Bool {
        guard let curDetail else { return true }
        let remain = 3600 - (Int(curTime) - curDetail.orderInfo.createTime / 1_000)
        let countDownText = remain.timeCountDisplay
        
        let text: String = .init(key: "A00134", countDownText)
        let attr = NSMutableAttributedString(string: text)
        let range = (text as NSString).range(of: countDownText)
        attr.addAttributes([.font: UIFont.heading_h4,
                            .foregroundColor: UIColor.primary_5], range: range)
        countDownLabel.attributedText = attr
        
        return remain <= 0
    }
}

extension LNOrderDetailViewController {
    private func update(_ item: LNOrderDetailResponse) {
        starView.isHidden = true
        countDownLabel.isHidden = true
        cancelButton.isHidden = true
        commentButton.isHidden = true
        completeView.isHidden = true
        refundButton.isHidden = true
        stopCountDown()
        
        detailView.update(item)
        refundView.update(item)
        
        if item.orderInfo.refundApply {
            backgroundIc.image = .icOrderCancelledBg
            stateIc.image = .icOrderStatusInProgress
            stateLabel.text = .init(key: "A00135")
            return
        }
        
        switch item.orderInfo.status {
        case .created:
            break
        case .waitingForAccept:
            backgroundIc.image = .icOrderNormalBg
            stateIc.image = .icOrderStatusInProgress
            stateLabel.text = .init(key: "A00136")
            countDownLabel.isHidden = false
            cancelButton.isHidden = false
            startCountDown()
        case .completed:
            backgroundIc.image = .icOrderNormalBg
            stateIc.image = .icOrderStatusComplete
            stateLabel.text = .init(key: "A00137")
            starView.isHidden = item.orderInfo.star == 0
            starView.score = item.orderInfo.star
            commentButton.isHidden = item.orderInfo.star != 0
        case .refunded:
            backgroundIc.image = .icOrderCancelledBg
            stateIc.image = .icOrderStatusRefund
            stateLabel.text = .init(key: "A00138")
        case .accepted:
            backgroundIc.image = .icOrderNormalBg
            stateIc.image = .icOrderStatusWaiting
            stateLabel.text = .init(key: "A00139")
            
            refundButton.isHidden = false
        case .rejected:
            backgroundIc.image = .icOrderCancelledBg
            stateIc.image = .icOrderStatusCancel
            stateLabel.text = .init(key: "A00140")
        case .servicing:
            backgroundIc.image = .icOrderNormalBg
            stateIc.image = .icOrderStatusInProgress
            stateLabel.text = .init(key: "A00141")
            
            refundButton.isHidden = false
        case .serviceDone:
            backgroundIc.image = .icOrderNormalBg
            stateIc.image = .icOrderStatusInProgress
            stateLabel.text = .init(key: "A00141")
            completeView.isHidden = false
        case .cancelled:
            backgroundIc.image = .icOrderCancelledBg
            stateIc.image = .icOrderStatusCancel
            stateLabel.text = .init(key: "A00152")
        }
    }
    
    private func setupViews() {
        view.backgroundColor = .primary_1
        title = .init(key: "A00143")
        
        view.addSubview(backgroundIc)
        backgroundIc.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.top.equalToSuperview()
        }
        
        let bottomMenu = buildBottomMenu()
        view.addSubview(bottomMenu)
        bottomMenu.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(16)
            make.bottom.equalToSuperview().offset(-view.safeBottomInset - 10)
            make.height.equalTo(0).priority(.low)
        }
        
        let scrollView = UIScrollView()
        scrollView.showsVerticalScrollIndicator = false
        scrollView.showsHorizontalScrollIndicator = false
        view.addSubview(scrollView)
        scrollView.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.top.equalToSuperview()
            make.bottom.equalTo(bottomMenu.snp.top)
        }
        
        let fakeView = UIView()
        scrollView.addSubview(fakeView)
        fakeView.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview()
            make.top.equalToSuperview()
            make.width.equalToSuperview()
            make.height.equalTo(0)
        }
        
        let statusView = buildStatusView()
        scrollView.addSubview(statusView)
        statusView.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(24)
            make.top.equalToSuperview().offset(44)
        }
         
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.spacing = 10
        scrollView.addSubview(stackView)
        stackView.snp.makeConstraints { make in
            make.horizontalEdges.equalToSuperview().inset(16)
            make.bottom.equalToSuperview()
            make.top.equalTo(statusView.snp.bottom).offset(30)
        }
        
        stackView.addArrangedSubview(detailView)
        
        refundView.isHidden = true
        stackView.addArrangedSubview(refundView)
    }
    
    private func buildStatusView() -> UIView {
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.spacing = 7
        stackView.alignment = .center
        
        starView.icSize = 30
        starView.spacing = 14
        starView.startType = .whiteBorder
        stackView.addArrangedSubview(starView)
        
        let stateView = UIView()
        stateView.addSubview(stateIc)
        stateIc.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.leading.equalToSuperview()
            make.width.height.equalTo(24)
        }
        
        stateLabel.font = .heading_h1
        stateLabel.textColor = .text_5
        stateLabel.numberOfLines = 0
        stateView.addSubview(stateLabel)
        stateLabel.snp.makeConstraints { make in
            make.verticalEdges.equalToSuperview()
            make.trailing.equalToSuperview()
            make.leading.equalTo(stateIc.snp.trailing).offset(8)
        }
        stackView.addArrangedSubview(stateView)
        
        countDownLabel.font = .body_s
        countDownLabel.textColor = .text_5
        stackView.addArrangedSubview(countDownLabel)
        
        return stackView
    }
    
    private func buildBottomMenu() -> UIView {
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.spacing = 0
        stackView.snp.makeConstraints { make in
            make.height.equalTo(0).priority(.low)
        }
        
        cancelButton.isHidden = true
        cancelButton.setTitle(.init(key: "A00003"), for: .normal)
        cancelButton.setTitleColor(.text_3, for: .normal)
        cancelButton.titleLabel?.font = .heading_h3
        cancelButton.layer.cornerRadius = 23.5
        cancelButton.layer.borderWidth = 1
        cancelButton.layer.borderColor = UIColor.text_2.cgColor
        cancelButton.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            LNCommonAlertView.showCancelOrderAlert(orderId: orderId)
        }), for: .touchUpInside)
        stackView.addArrangedSubview(cancelButton)
        cancelButton.snp.makeConstraints { make in
            make.height.equalTo(47)
        }
        
        refundButton.isHidden = true
        refundButton.setTitle(.init(key: "A00144"), for: .normal)
        refundButton.setTitleColor(.text_3, for: .normal)
        refundButton.titleLabel?.font = .heading_h3
        refundButton.layer.cornerRadius = 23.5
        refundButton.layer.borderWidth = 1
        refundButton.layer.borderColor = UIColor.text_2.cgColor
        refundButton.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            view.pushToOrderRefund(orderId)
        }), for: .touchUpInside)
        stackView.addArrangedSubview(refundButton)
        refundButton.snp.makeConstraints { make in
            make.height.equalTo(47)
        }
        
        let cover = UIView()
        cover.backgroundColor = .fill
        cover.layer.cornerRadius = 23
        cover.isUserInteractionEnabled = false
        commentButton.addSubview(cover)
        cover.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(1)
        }
        
        commentButton.isHidden = true
        commentButton.setBackgroundImage(.primary_7, for: .normal)
        commentButton.setTitle(.init(key: "A00145"), for: .normal)
        commentButton.setTitleColor(.text_6, for: .normal)
        commentButton.titleLabel?.font = .heading_h3
        commentButton.layer.cornerRadius = 23.5
        commentButton.clipsToBounds = true
        commentButton.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            guard let curDetail else { return }
            let panel = LNOrderCommentPanel()
            panel.update(curDetail.orderInfo.avatar, orderId: orderId)
            panel.popup()
        }), for: .touchUpInside)
        stackView.addArrangedSubview(commentButton)
        commentButton.snp.makeConstraints { make in
            make.height.equalTo(47)
        }
        
        completeView.isHidden = true
        stackView.addArrangedSubview(completeView)
        completeView.snp.makeConstraints { make in
            make.height.equalTo(47)
        }
        let refundButton = UIButton()
        refundButton.layer.cornerRadius = 23.5
        refundButton.setTitle(.init(key: "A00144"), for: .normal)
        refundButton.setTitleColor(.text_3, for: .normal)
        refundButton.titleLabel?.font = .heading_h3
        refundButton.layer.borderColor = UIColor.text_2.cgColor
        refundButton.layer.borderWidth = 1
        refundButton.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            view.pushToOrderRefund(orderId)
        }), for: .touchUpInside)
        completeView.addSubview(refundButton)
        refundButton.snp.makeConstraints { make in
            make.leading.equalToSuperview()
            make.verticalEdges.equalToSuperview()
            make.width.equalToSuperview().multipliedBy(1.0/3.0)
        }
        
        let completeButton = UIButton()
        completeButton.layer.cornerRadius = 23.5
        completeButton.setTitle(.init(key: "A00025"), for: .normal)
        completeButton.setTitleColor(.text_1, for: .normal)
        completeButton.titleLabel?.font = .heading_h3
        completeButton.layer.cornerRadius = 23.5
        completeButton.setBackgroundImage(.primary_8, for: .normal)
        completeButton.clipsToBounds = true
        completeButton.addAction(UIAction(handler: { [weak self] _ in
            guard let self else { return }
            LNCommonAlertView.showFinishOrderAlert(orderId: orderId, completion: nil)
        }), for: .touchUpInside)
        completeView.addSubview(completeButton)
        completeButton.snp.makeConstraints { make in
            make.verticalEdges.equalToSuperview()
            make.leading.equalTo(refundButton.snp.trailing).offset(10)
            make.trailing.equalToSuperview()
        }
        
        return stackView
    }
}

#if DEBUG

import SwiftUI

struct LNOrderDetailViewControllerPreview: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> some UIViewController {
        LNOrderDetailViewController(orderId: "")
    }
    
    func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) { }
}

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