//
//  PermissionApplyViewController.swift
//  suixinkan
//

import SnapKit
import UIKit

/// 权限申请页，严格对齐 Android `PermissionApplyScreen`。
@MainActor
final class PermissionApplyViewController: BaseViewController {

    private let viewModel: PermissionApplyViewModel
    private let homeAPI: HomeAPI
    private let pendingData: RoleApplyPendingResponse?

    private let bannerView = PermissionApplyBannerView()
    private let scrollView = UIScrollView()
    private let cardView = UIView()
    private let roleSelector = PermissionFormSelectorRow(
        title: "角色信息",
        tag: "单选",
        description: "请选择您需要申请权限的角色",
        placeholder: "请选择角色"
    )
    private let newRoleTags = PermissionSelectedTagsView()
    private let scenicSelector = PermissionFormSelectorRow(
        title: "选择景区",
        tag: "可多选",
        description: "请选择您需要申请权限的景区",
        placeholder: "请选择景区"
    )
    private let selectedScenicTags = PermissionSelectedTagsView()
    private let existingRoleList = PermissionExistingRoleListView()
    private let bottomBar = UIView()
    private let submitButton = PermissionSubmitButton()

    private weak var roleDropdown: PermissionDropdownViewController?
    private weak var scenicDropdown: PermissionDropdownViewController?

    /// 创建新增或驳回编辑状态的权限申请页。
    init(
        pendingData: RoleApplyPendingResponse? = nil,
        viewModel: PermissionApplyViewModel = PermissionApplyViewModel(),
        homeAPI: HomeAPI? = nil
    ) {
        self.pendingData = pendingData
        self.viewModel = viewModel
        self.homeAPI = homeAPI ?? NetworkServices.shared.homeAPI
        super.init(nibName: nil, bundle: nil)
    }

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

    override func setupNavigationBar() {
        title = "申请权限"
        navigationItem.backButtonDisplayMode = .minimal
    }

    override func setupUI() {
        view.backgroundColor = PermissionApplyUITokens.pageBackground
        scrollView.keyboardDismissMode = .onDrag
        cardView.backgroundColor = .white
        cardView.layer.cornerRadius = 8
        bottomBar.backgroundColor = .white

        let roleSection = UIStackView(arrangedSubviews: [roleSelector, newRoleTags])
        roleSection.axis = .vertical
        roleSection.spacing = 12

        let scenicSection = UIStackView(arrangedSubviews: [scenicSelector, selectedScenicTags, existingRoleList])
        scenicSection.axis = .vertical
        scenicSection.spacing = 12

        let formStack = UIStackView(arrangedSubviews: [roleSection, scenicSection])
        formStack.axis = .vertical
        formStack.spacing = 20

        view.addSubview(bannerView)
        view.addSubview(scrollView)
        scrollView.addSubview(cardView)
        cardView.addSubview(formStack)
        view.addSubview(bottomBar)
        bottomBar.addSubview(submitButton)

        bannerView.snp.makeConstraints { make in
            make.top.leading.trailing.equalTo(view.safeAreaLayoutGuide)
        }
        bottomBar.snp.makeConstraints { make in
            make.leading.trailing.bottom.equalToSuperview()
        }
        submitButton.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(16)
            make.leading.trailing.equalToSuperview().inset(16)
            make.bottom.equalTo(view.safeAreaLayoutGuide).offset(-16)
        }
        scrollView.snp.makeConstraints { make in
            make.top.equalTo(bannerView.snp.bottom)
            make.leading.trailing.equalToSuperview()
            make.bottom.equalTo(bottomBar.snp.top)
        }
        cardView.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(16)
            make.width.equalTo(scrollView).offset(-32)
        }
        formStack.snp.makeConstraints { make in make.edges.equalToSuperview().inset(16) }

        newRoleTags.isHidden = true
        selectedScenicTags.isHidden = true
        existingRoleList.isHidden = true
    }

    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?.handleSubmitSuccess() }
        }

        bannerView.onApplyNewScenic = { [weak self] in
            self?.navigationController?.pushViewController(ScenicApplicationViewController(), animated: true)
        }
        roleSelector.onTap = { [weak self] in self?.viewModel.showRolePickerSheet() }
        scenicSelector.onTap = { [weak self] in
            guard let self else { return }
            self.viewModel.showScenicPickerSheet()
            if self.viewModel.showScenicPicker, self.viewModel.availableScenics.isEmpty {
                Task { await self.viewModel.loadAvailableScenics(api: self.homeAPI) }
            }
        }
        existingRoleList.onShowAllScenics = { [weak self] roleName, scenics in
            self?.viewModel.showScenicList(roleName: roleName, scenics: scenics)
        }
        submitButton.addTarget(self, action: #selector(submitTapped), for: .touchUpInside)

        if let pendingData {
            viewModel.initWithPendingData(pendingData)
            Task { await viewModel.loadAvailableScenics(api: homeAPI) }
        }
        applyViewModel()
    }

    @MainActor
    private func applyViewModel() {
        if viewModel.selectedRoleName.isEmpty {
            roleSelector.setValue("请选择角色", isPlaceholder: true)
        } else {
            roleSelector.setValue(viewModel.selectedRoleName, isPlaceholder: false)
        }
        newRoleTags.apply(title: "新增角色", names: viewModel.selectedRoleName.isEmpty ? [] : [viewModel.selectedRoleName]) {
            [weak self] _ in self?.viewModel.clearRoleSelection()
        }

        let scenicValue: String
        switch viewModel.selectedScenicNames.count {
        case 0: scenicValue = "请选择景区"
        case 1: scenicValue = viewModel.selectedScenicNames[0]
        default: scenicValue = "已选中\(viewModel.selectedScenicNames.count)个景区"
        }
        scenicSelector.setValue(scenicValue, isPlaceholder: viewModel.selectedScenicNames.isEmpty)
        selectedScenicTags.apply(title: "新增景区", names: viewModel.selectedScenicNames) { [weak self] index in
            guard let self,
                  self.viewModel.selectedScenicIds.indices.contains(index),
                  self.viewModel.selectedScenicNames.indices.contains(index) else { return }
            self.viewModel.removeSelectedScenic(
                id: self.viewModel.selectedScenicIds[index],
                name: self.viewModel.selectedScenicNames[index]
            )
        }
        existingRoleList.apply(rolePermissions: viewModel.rolePermissionList)
        submitButton.applyState(canSubmit: viewModel.canSubmit, submitting: viewModel.isSubmitting)

        if viewModel.isSubmitting { showLoading() } else { hideLoading() }
        scenicDropdown?.updateScenics(viewModel.filteredScenics, isLoading: viewModel.isLoadingScenics)
        presentRolePickerIfNeeded()
        presentScenicPickerIfNeeded()
        presentDeletionIfNeeded()
        presentScenicListIfNeeded()
    }

    private func presentRolePickerIfNeeded() {
        guard viewModel.showRolePicker, roleDropdown == nil, presentedViewController == nil else { return }
        let dropdown = PermissionDropdownViewController(
            anchor: roleSelector.selectorControl,
            mode: .roles(viewModel.availableRoles)
        )
        dropdown.onRoleSelect = { [weak self] role in self?.viewModel.selectRole(role) }
        dropdown.onDismiss = { [weak self, weak dropdown] in
            self?.viewModel.hideRolePickerSheet()
            if self?.roleDropdown === dropdown { self?.roleDropdown = nil }
        }
        roleDropdown = dropdown
        present(dropdown, animated: true)
    }

    private func presentScenicPickerIfNeeded() {
        guard viewModel.showScenicPicker, scenicDropdown == nil, presentedViewController == nil else { return }
        let dropdown = PermissionDropdownViewController(
            anchor: scenicSelector.selectorControl,
            mode: .scenics(viewModel.filteredScenics, isLoading: viewModel.isLoadingScenics)
        )
        dropdown.onScenicToggle = { [weak self] scenic in self?.viewModel.toggleScenic(scenic) }
        dropdown.onSearchChange = { [weak self] query in self?.viewModel.updateScenicSearchQuery(query) }
        dropdown.onDismiss = { [weak self, weak dropdown] in
            self?.viewModel.hideScenicPickerSheet()
            if self?.scenicDropdown === dropdown { self?.scenicDropdown = nil }
        }
        scenicDropdown = dropdown
        present(dropdown, animated: true)
    }

    private func presentDeletionIfNeeded() {
        guard let target = viewModel.pendingDeletion, presentedViewController == nil else { return }
        present(
            PermissionDeleteDialogViewController(
                target: target,
                onCancel: { [weak self] in self?.viewModel.cancelDeletion() },
                onConfirm: { [weak self] in self?.viewModel.confirmDeletion() }
            ),
            animated: true
        )
    }

    private func presentScenicListIfNeeded() {
        guard viewModel.showScenicListDialog, presentedViewController == nil else { return }
        present(
            PermissionScenicListDialogViewController(
                roleName: viewModel.dialogRoleName,
                scenics: viewModel.dialogScenicList,
                onDismiss: { [weak self] in self?.viewModel.hideScenicList() }
            ),
            animated: true
        )
    }

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

    private func handleSubmitSuccess() {
        hideLoading()
        guard let navigationController else {
            showToast("提交成功")
            return
        }
        navigationController.popViewController(animated: true)
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { [weak navigationController] in
            (navigationController?.topViewController as? BaseViewController)?.showToast("提交成功")
        }
    }
}
