//
//  ScenicApplicationViewController.swift
//  suixinkan
//

import PhotosUI
import SnapKit
import UIKit

/// 景区申请页，对齐 Android `ScenicApplicationScreen`。
final class ScenicApplicationViewController: BaseViewController {

    private let viewModel: ScenicApplicationViewModel
    private let homeAPI: HomeAPI
    private let profileAPI: ProfileAPI
    private let ossUploadService: OSSUploadService

    private let scrollView = UIScrollView()
    private let outerStack = UIStackView()
    private let paddedStack = UIStackView()
    private let auditCard = ScenicApplicationAuditStatusView()
    private let warmReminder = ScenicApplicationWarmReminderView()
    private let formCard = UIView()
    private let formStack = UIStackView()

    private let scenicNameField = ScenicApplicationFieldStyle.makeTextField(placeholder: "请输入景区名称")
    private let scenicNameSection = ScenicApplicationFormFieldView(title: "景区名称")
    private let imageSection = ScenicApplicationFormFieldView(title: "景区图片 (已添加 0/20)")
    private let imageUploadView = ScenicApplicationImageUploadView()
    private let provinceSelector = ScenicApplicationLocationSelector()
    private let citySelector = ScenicApplicationLocationSelector()
    private let cooperationStack = UIStackView()
    private var cooperationOptions: [ScenicApplicationCooperationOptionView] = []
    private let remarksView = ScenicApplicationPlaceholderTextView(placeholder: "请输入备注信息")
    private let remarksSection = ScenicApplicationFormFieldView(title: "备注信息 (0/50)")

    private let bottomBar = UIView()
    private let agreementView = ScenicApplicationAgreementView()
    private let submitButton = ScenicApplicationSubmitButton()
    private let uploadProgressView = ScenicApplicationUploadProgressView()

    init(
        viewModel: ScenicApplicationViewModel = ScenicApplicationViewModel(),
        homeAPI: HomeAPI? = nil,
        profileAPI: ProfileAPI? = nil,
        ossUploadService: OSSUploadService? = nil
    ) {
        self.viewModel = viewModel
        self.homeAPI = homeAPI ?? NetworkServices.shared.homeAPI
        self.profileAPI = profileAPI ?? NetworkServices.shared.profileAPI
        self.ossUploadService = ossUploadService ?? NetworkServices.shared.ossUploadService
        super.init(nibName: nil, bundle: nil)
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func setupNavigationBar() {
        title = "景区申请"
    }

    override func setupUI() {
        outerStack.axis = .vertical
        outerStack.spacing = 0

        paddedStack.axis = .vertical
        paddedStack.spacing = 12

        formCard.backgroundColor = .white
        formCard.layer.cornerRadius = 8
        formStack.axis = .vertical
        formStack.spacing = 20
        formCard.addSubview(formStack)
        formStack.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(16)
        }

        scenicNameSection.setContent(scenicNameField)
        imageSection.setContent(imageUploadView)

        let locationRow = UIStackView(arrangedSubviews: [provinceSelector, citySelector])
        locationRow.axis = .horizontal
        locationRow.spacing = 12
        locationRow.distribution = .fillEqually
        let locationSection = ScenicApplicationFormFieldView(title: "景区位置")
        locationSection.setContent(locationRow)

        cooperationStack.axis = .vertical
        cooperationStack.spacing = 8
        ScenicCooperationType.allCases.forEach { type in
            let option = ScenicApplicationCooperationOptionView(title: type.displayName)
            option.tag = type.rawValue
            option.addTarget(self, action: #selector(cooperationTypeTapped(_:)), for: .touchUpInside)
            cooperationOptions.append(option)
            cooperationStack.addArrangedSubview(option)
        }
        let cooperationSection = ScenicApplicationFormFieldView(title: "合作类型")
        cooperationSection.setContent(cooperationStack)

        remarksView.text = ""
        remarksSection.setContent(remarksView)

        formStack.addArrangedSubview(scenicNameSection)
        formStack.addArrangedSubview(imageSection)
        formStack.addArrangedSubview(locationSection)
        formStack.addArrangedSubview(cooperationSection)
        formStack.addArrangedSubview(remarksSection)

        paddedStack.addArrangedSubview(warmReminder)
        paddedStack.addArrangedSubview(formCard)

        outerStack.addArrangedSubview(auditCard)
        outerStack.addArrangedSubview(paddedStack)
        auditCard.isHidden = true

        scrollView.addSubview(outerStack)
        view.addSubview(scrollView)
        view.addSubview(bottomBar)
        view.addSubview(uploadProgressView)

        bottomBar.backgroundColor = .white
        let bottomStack = UIStackView(arrangedSubviews: [agreementView, submitButton])
        bottomStack.axis = .vertical
        bottomStack.spacing = 4
        bottomBar.addSubview(bottomStack)
        bottomStack.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(UIEdgeInsets(top: 12, left: 16, bottom: 18, right: 16))
        }

        uploadProgressView.isHidden = true
        uploadProgressView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
    }

    override func setupConstraints() {
        scrollView.snp.makeConstraints { make in
            make.top.leading.trailing.equalTo(view.safeAreaLayoutGuide)
            make.bottom.equalTo(bottomBar.snp.top)
        }
        outerStack.snp.makeConstraints { make in
            make.edges.equalToSuperview()
            make.width.equalTo(scrollView)
        }
        paddedStack.snp.makeConstraints { make in
            make.leading.trailing.equalToSuperview().inset(16)
        }
        paddedStack.layoutMargins = UIEdgeInsets(top: 12, left: 0, bottom: 16, right: 0)
        paddedStack.isLayoutMarginsRelativeArrangement = true
        bottomBar.snp.makeConstraints { make in
            make.leading.trailing.equalToSuperview()
            make.bottom.equalTo(view.safeAreaLayoutGuide)
        }
    }

    override func bindActions() {
        viewModel.onStateChange = { [weak self] in
            Task { @MainActor in self?.applyViewModel() }
        }
        viewModel.onShowMessage = { [weak self] message in
            Task { @MainActor in self?.showToast(message) }
        }
        viewModel.onSubmitSuccess = { [weak self] in
            Task { @MainActor in self?.navigationController?.popViewController(animated: true) }
        }

        scenicNameField.addTarget(self, action: #selector(scenicNameChanged), for: .editingChanged)
        remarksView.onTextChange = { [weak self] text in
            self?.viewModel.onRemarksChange(text)
        }
        provinceSelector.addTarget(self, action: #selector(provinceTapped), for: .touchUpInside)
        citySelector.addTarget(self, action: #selector(cityTapped), for: .touchUpInside)
        agreementView.onToggle = { [weak self] in self?.viewModel.toggleAgreement() }
        submitButton.addTarget(self, action: #selector(submitTapped), for: .touchUpInside)

        imageUploadView.onAdd = { [weak self] in self?.pickImages() }
        imageUploadView.onDelete = { [weak self] index in self?.viewModel.deleteImage(at: index) }
        imageUploadView.onRetry = { [weak self] index in
            guard let self else { return }
            self.viewModel.retryUpload(at: index)
            Task { await self.startUploadIfNeeded() }
        }

        Task { await loadInitial() }
        applyViewModel()
    }

    private func loadInitial() async {
        showLoading()
        defer { hideLoading() }
        await viewModel.loadInitial(profileAPI: profileAPI, homeAPI: homeAPI)
    }

    private func applyViewModel() {
        if viewModel.shouldShowAuditCard, let pending = viewModel.pendingApplication {
            auditCard.apply(pending: pending)
            auditCard.isHidden = false
        } else {
            auditCard.isHidden = true
        }

        let editable = viewModel.isEditable
        let readOnly = viewModel.isReadOnly

        scenicNameField.text = viewModel.scenicName
        scenicNameField.isEnabled = editable
        scenicNameField.isUserInteractionEnabled = editable && !readOnly

        imageSection.updateTitle("景区图片 (已添加 \(viewModel.selectedImages.count)/20)")
        imageUploadView.apply(images: viewModel.selectedImages, isReadOnly: readOnly)

        provinceSelector.setValue(viewModel.selectedProvince, placeholder: "省份")
        citySelector.setValue(viewModel.selectedCity, placeholder: "城市")
        provinceSelector.isEnabled = editable
        citySelector.isEnabled = editable

        cooperationOptions.forEach { option in
            let type = ScenicCooperationType(rawValue: option.tag) ?? .photographer
            option.isSelected = type == viewModel.selectedCooperationType
            option.isEnabled = editable
        }

        if remarksView.text != viewModel.remarks {
            remarksView.text = viewModel.remarks
        }
        remarksView.isEditable = editable && !readOnly
        remarksSection.updateTitle("备注信息 (\(viewModel.remarks.count)/50)")

        agreementView.isHidden = !editable
        agreementView.setChecked(viewModel.isAgreed)

        submitButton.apply(
            canSubmit: viewModel.canSubmit,
            isSubmitting: viewModel.isSubmitting,
            isReadOnly: readOnly
        )

        uploadProgressView.apply(state: viewModel.uploadDialogState)
    }

    @objc private func scenicNameChanged() {
        viewModel.onScenicNameChange(scenicNameField.text ?? "")
    }

    @objc private func cooperationTypeTapped(_ sender: ScenicApplicationCooperationOptionView) {
        guard viewModel.isEditable else { return }
        guard let type = ScenicCooperationType(rawValue: sender.tag) else { return }
        viewModel.onCooperationTypeSelected(type)
    }

    @objc private func provinceTapped() {
        guard viewModel.isEditable else { return }
        presentAreaPicker(title: "选择省份", names: viewModel.provinceList.map(\.name)) { [weak self] name in
            self?.viewModel.onProvinceSelected(name)
        }
    }

    @objc private func cityTapped() {
        guard viewModel.isEditable else { return }
        guard !viewModel.selectedProvince.isEmpty else {
            showToast("请先选择省份")
            return
        }
        presentAreaPicker(title: "选择城市", names: viewModel.cityList.map(\.name)) { [weak self] name in
            self?.viewModel.onCitySelected(name)
        }
    }

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

    @objc private func submitTapped() {
        Task {
            showLoading()
            defer { hideLoading() }
            await viewModel.submit(homeAPI: homeAPI)
        }
    }

    private func pickImages() {
        guard viewModel.isEditable, !viewModel.isReadOnly else { return }
        let remaining = 20 - viewModel.selectedImages.count
        guard remaining > 0 else {
            showToast("最多只能选择20张图片")
            return
        }

        var configuration = PHPickerConfiguration(photoLibrary: .shared())
        configuration.filter = .images
        configuration.selectionLimit = remaining
        let picker = PHPickerViewController(configuration: configuration)
        picker.delegate = self
        present(picker, animated: true)
    }

    private func startUploadIfNeeded() async {
        let scenicId = AppStore.shared.session.currentScenicId
        await viewModel.processPendingUploads(uploader: ossUploadService, scenicId: scenicId)
    }
}

extension ScenicApplicationViewController: PHPickerViewControllerDelegate {
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        picker.dismiss(animated: true)
        guard !results.isEmpty else { return }

        var loadedItems = [ScenicApplicationImageItem?](repeating: nil, count: results.count)
        let group = DispatchGroup()

        for (index, result) in results.enumerated() {
            let provider = result.itemProvider
            guard provider.canLoadObject(ofClass: UIImage.self) else { continue }
            group.enter()
            provider.loadObject(ofClass: UIImage.self) { object, _ in
                defer { group.leave() }
                guard let image = object as? UIImage, let data = image.jpegData(compressionQuality: 0.9) else { return }
                let fileName = "scenic_apply_\(Int(Date().timeIntervalSince1970))_\(index).jpg"
                loadedItems[index] = ScenicApplicationImageItem.fromLocal(data: data, fileName: fileName)
            }
        }

        group.notify(queue: .main) { [weak self] in
            guard let self else { return }
            let items = loadedItems.compactMap { $0 }
            guard !items.isEmpty else { return }
            self.viewModel.addLocalImages(items)
            Task { await self.startUploadIfNeeded() }
        }
    }
}
