//
//  WithdrawalSettingsViewController.swift
//  suixinkan
//

import PhotosUI
import SnapKit
import UIKit

/// 提现设置页面，两步表单绑定银行卡。
final class WithdrawalSettingsViewController: BaseViewController {

    private let viewModel = WithdrawalSettingsViewModel()
    private let profileAPI = NetworkServices.shared.profileAPI
    private let ossUploadService = NetworkServices.shared.ossUploadService

    private let scrollView = UIScrollView()
    private let contentStack = UIStackView()
    private let stepLabel = UILabel()
    private let holderNameField = UITextField()
    private let bankNoField = UITextField()
    private let frontImageView = UIImageView()
    private let backImageView = UIImageView()
    private let bankNameField = UITextField()
    private let provinceButton = UIButton(type: .system)
    private let cityButton = UIButton(type: .system)
    private let branchField = UITextField()
    private let smsCodeField = UITextField()
    private let agreeSwitch = UISwitch()
    private let actionButton = AppButton(title: "下一步")

    private var pickingSide: BankCardImageSide = .front
    private var stepTwoStack = UIStackView()

    override func setupNavigationBar() {
        title = "提现设置"
    }

    override func setupUI() {
        view.backgroundColor = UIColor(hex: 0xF7FAFF)
        contentStack.axis = .vertical
        contentStack.spacing = 16

        stepLabel.font = .systemFont(ofSize: 14, weight: .medium)
        stepLabel.textColor = AppColor.text666

        [holderNameField, bankNoField, bankNameField, branchField, smsCodeField].forEach {
            $0.borderStyle = .roundedRect
            $0.font = .systemFont(ofSize: 16)
        }
        holderNameField.placeholder = "持卡人姓名"
        bankNoField.placeholder = "银行卡号"
        bankNoField.keyboardType = .numberPad
        bankNameField.placeholder = "开户银行"
        branchField.placeholder = "支行名称"
        smsCodeField.placeholder = "短信验证码"
        smsCodeField.keyboardType = .numberPad

        provinceButton.contentHorizontalAlignment = .leading
        cityButton.contentHorizontalAlignment = .leading
        provinceButton.setTitle("请选择省份", for: .normal)
        cityButton.setTitle("请选择城市", for: .normal)

        [frontImageView, backImageView].forEach {
            $0.backgroundColor = UIColor(hex: 0xF8FAFC)
            $0.contentMode = .scaleAspectFit
            $0.layer.cornerRadius = 8
            $0.clipsToBounds = true
            $0.isUserInteractionEnabled = true
            $0.snp.makeConstraints { make in make.height.equalTo(140) }
        }
        frontImageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(pickFront)))
        backImageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(pickBack)))

        stepTwoStack.axis = .vertical
        stepTwoStack.spacing = 16
        stepTwoStack.isHidden = true
        stepTwoStack.addArrangedSubview(labeled("开户银行", bankNameField))
        stepTwoStack.addArrangedSubview(labeled("所在省份", provinceButton))
        stepTwoStack.addArrangedSubview(labeled("所在城市", cityButton))
        stepTwoStack.addArrangedSubview(labeled("支行名称", branchField))

        let smsRow = UIStackView(arrangedSubviews: [smsCodeField, sendCodeButton()])
        smsRow.axis = .horizontal
        smsRow.spacing = 8
        stepTwoStack.addArrangedSubview(labeled("短信验证码", smsRow))

        view.addSubview(scrollView)
        scrollView.addSubview(contentStack)
        view.addSubview(actionButton)

        contentStack.addArrangedSubview(stepLabel)
        contentStack.addArrangedSubview(labeled("持卡人姓名", holderNameField))
        contentStack.addArrangedSubview(labeled("银行卡号", bankNoField))
        contentStack.addArrangedSubview(labeled("银行卡正面", frontImageView))
        contentStack.addArrangedSubview(labeled("银行卡反面", backImageView))
        contentStack.addArrangedSubview(agreeRow())
        contentStack.addArrangedSubview(stepTwoStack)
    }

    override func setupConstraints() {
        scrollView.snp.makeConstraints { make in
            make.top.leading.trailing.equalToSuperview()
            make.bottom.equalTo(actionButton.snp.top).offset(-12)
        }
        contentStack.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(16)
            make.width.equalTo(scrollView).offset(-32)
        }
        actionButton.snp.makeConstraints { make in
            make.leading.trailing.equalToSuperview().inset(16)
            make.bottom.equalTo(view.safeAreaLayoutGuide).inset(14)
        }
    }

    override func bindActions() {
        viewModel.onStateChange = { [weak self] in self?.applyViewModel() }
        actionButton.addTarget(self, action: #selector(actionTapped), for: .touchUpInside)
        provinceButton.addTarget(self, action: #selector(selectProvince), for: .touchUpInside)
        cityButton.addTarget(self, action: #selector(selectCity), for: .touchUpInside)
        agreeSwitch.addTarget(self, action: #selector(agreeChanged), for: .valueChanged)
        holderNameField.addTarget(self, action: #selector(fieldsChanged), for: .editingChanged)
        bankNoField.addTarget(self, action: #selector(fieldsChanged), for: .editingChanged)
        bankNameField.addTarget(self, action: #selector(fieldsChanged), for: .editingChanged)
        branchField.addTarget(self, action: #selector(fieldsChanged), for: .editingChanged)
        smsCodeField.addTarget(self, action: #selector(fieldsChanged), for: .editingChanged)
        Task { await loadData() }
    }

    private func applyViewModel() {
        stepLabel.text = viewModel.currentStep == 1 ? "步骤 1/2：填写银行卡信息" : "步骤 2/2：完善开户信息"
        holderNameField.text = viewModel.holderName
        bankNoField.text = viewModel.bankNo
        bankNameField.text = viewModel.bankName
        branchField.text = viewModel.branchName
        smsCodeField.text = viewModel.verificationCode
        agreeSwitch.isOn = viewModel.isAgree
        stepTwoStack.isHidden = viewModel.currentStep == 1
        actionButton.setTitle(viewModel.currentStep == 1 ? "下一步" : "提交", for: .normal)
        actionButton.isEnabled = viewModel.currentStep == 1 ? viewModel.canGoNextStep : viewModel.canSubmit

        provinceButton.setTitle(viewModel.provinceName.isEmpty ? "请选择省份" : viewModel.provinceName, for: .normal)
        cityButton.setTitle(viewModel.cityName.isEmpty ? "请选择城市" : viewModel.cityName, for: .normal)

        updateImageView(frontImageView, pending: viewModel.pendingFrontImageData, url: viewModel.bankCardFrontURL)
        updateImageView(backImageView, pending: viewModel.pendingBackImageData, url: viewModel.bankCardBackURL)
    }

    private func updateImageView(_ imageView: UIImageView, pending: Data?, url: String) {
        if let pending, let image = UIImage(data: pending) {
            imageView.image = image
        } else if url != "pending" {
            imageView.loadRemoteImage(urlString: url)
        }
    }

    @objc private func fieldsChanged() {
        viewModel.updateHolderName(holderNameField.text ?? "")
        viewModel.updateBankNo(bankNoField.text ?? "")
        viewModel.updateBankName(bankNameField.text ?? "")
        viewModel.updateBranchName(branchField.text ?? "")
        viewModel.updateVerificationCode(smsCodeField.text ?? "")
    }

    @objc private func agreeChanged() {
        viewModel.updateAgree(agreeSwitch.isOn)
    }

    @objc private func actionTapped() {
        if viewModel.currentStep == 1 {
            viewModel.goNextStep()
        } else {
            Task { await submit() }
        }
    }

    @objc private func pickFront() { pickImage(side: .front) }
    @objc private func pickBack() { pickImage(side: .back) }

    private func pickImage(side: BankCardImageSide) {
        pickingSide = side
        var configuration = PHPickerConfiguration(photoLibrary: .shared())
        configuration.filter = .images
        configuration.selectionLimit = 1
        let picker = PHPickerViewController(configuration: configuration)
        picker.delegate = self
        present(picker, animated: true)
    }

    @objc private func selectProvince() {
        presentAreaPicker(title: "选择省份", options: viewModel.provinceOptions) { [weak self] area in
            self?.viewModel.selectProvince(area)
        }
    }

    @objc private func selectCity() {
        presentAreaPicker(title: "选择城市", options: viewModel.cityOptions) { [weak self] area in
            self?.viewModel.selectCity(area)
        }
    }

    private func presentAreaPicker(title: String, options: [AreasResponse], onSelect: @escaping (AreasResponse) -> Void) {
        let alert = UIAlertController(title: title, message: nil, preferredStyle: .actionSheet)
        options.forEach { area in
            alert.addAction(UIAlertAction(title: area.name, style: .default) { _ in
                onSelect(area)
            })
        }
        alert.addAction(UIAlertAction(title: "取消", style: .cancel))
        present(alert, animated: true)
    }

    private func loadData() async {
        showLoading()
        defer { hideLoading() }
        do {
            try await viewModel.load(api: profileAPI)
        } catch {
            showToast(error.localizedDescription)
        }
    }

    private func submit() async {
        let scenicId = AppStore.shared.session.currentScenicId
        guard scenicId > 0 else {
            showToast("当前景区信息缺失")
            return
        }
        showLoading()
        defer { hideLoading() }
        do {
            try await viewModel.submit(api: profileAPI, uploader: ossUploadService, scenicId: scenicId)
            showToast("提交成功")
            navigationController?.popViewController(animated: true)
        } catch {
            showToast(error.localizedDescription)
        }
    }

    private func labeled(_ title: String, _ view: UIView) -> UIStackView {
        let label = UILabel()
        label.text = title
        label.font = .systemFont(ofSize: 14)
        let stack = UIStackView(arrangedSubviews: [label, view])
        stack.axis = .vertical
        stack.spacing = 8
        return stack
    }

    private func agreeRow() -> UIStackView {
        let label = UILabel()
        label.text = "我已阅读并同意相关协议"
        label.font = .systemFont(ofSize: 14)
        let row = UIStackView(arrangedSubviews: [label, agreeSwitch])
        row.axis = .horizontal
        return row
    }

    private func sendCodeButton() -> UIButton {
        let button = UIButton(type: .system)
        button.setTitle("获取验证码", for: .normal)
        button.addAction(UIAction { [weak self] _ in
            Task {
                guard let self else { return }
                self.showLoading()
                defer { self.hideLoading() }
                do {
                    try await self.viewModel.sendCode(api: self.profileAPI)
                    self.showToast("验证码已发送")
                } catch {
                    self.showToast(error.localizedDescription)
                }
            }
        }, for: .touchUpInside)
        return button
    }
}

extension WithdrawalSettingsViewController: PHPickerViewControllerDelegate {
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        picker.dismiss(animated: true)
        guard let provider = results.first?.itemProvider, provider.canLoadObject(ofClass: UIImage.self) else { return }
        provider.loadObject(ofClass: UIImage.self) { [weak self] object, _ in
            guard let self, let image = object as? UIImage, let data = image.jpegData(compressionQuality: 0.9) else { return }
            Task { @MainActor in
                do {
                    try self.viewModel.prepareBankCardImage(data: data, side: self.pickingSide)
                } catch {
                    self.showToast(error.localizedDescription)
                }
            }
        }
    }
}
