//
//  CloudDriveActionSheetViewController.swift
//  suixinkan
//

import SnapKit
import UIKit

/// 云盘底部操作弹层，严格同步 Android 上传与文件操作菜单。
final class CloudDriveActionSheetViewController: UIViewController {
    /// 云盘弹层内容布局。
    enum Layout {
        case upload
        case controls
    }

    /// 云盘底部弹层操作项。
    struct Item {
        /// 操作文案。
        let title: String
        /// 操作图标。
        let image: UIImage?
        /// 是否展示为危险操作。
        let isDestructive: Bool
        /// 点击后的业务动作。
        let handler: () -> Void
    }

    private let sheetTitle: String
    private let layout: Layout
    private let items: [Item]
    private let dimView = UIView()
    private let panelView = UIView()
    private let contentStack = UIStackView()

    /// 初始化 Android 风格云盘底部弹层。
    init(title: String, layout: Layout, items: [Item]) {
        sheetTitle = title
        self.layout = layout
        self.items = items
        super.init(nibName: nil, bundle: nil)
        modalPresentationStyle = .overFullScreen
    }

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

    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        setupConstraints()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        dimView.alpha = 0
        panelView.transform = CGAffineTransform(translationX: 0, y: 420)
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        UIView.animate(withDuration: 0.24, delay: 0, options: [.curveEaseOut]) {
            self.dimView.alpha = 1
            self.panelView.transform = .identity
        }
    }

    private func setupUI() {
        view.backgroundColor = .clear
        dimView.backgroundColor = UIColor.black.withAlphaComponent(0.35)
        dimView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(cancelTapped)))

        panelView.backgroundColor = .white
        panelView.layer.cornerRadius = 16
        panelView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
        panelView.clipsToBounds = true

        contentStack.axis = .vertical
        contentStack.spacing = 0

        view.addSubview(dimView)
        view.addSubview(panelView)
        panelView.addSubview(contentStack)

        let titleContainer = UIView()
        let titleLabel = UILabel()
        titleLabel.text = sheetTitle
        titleLabel.font = .systemFont(ofSize: 18, weight: .semibold)
        titleLabel.textColor = .black
        titleLabel.textAlignment = .left
        titleContainer.addSubview(titleLabel)
        titleContainer.snp.makeConstraints { make in make.height.equalTo(52) }
        titleLabel.snp.makeConstraints { make in
            make.leading.trailing.equalToSuperview().inset(16)
            make.centerY.equalToSuperview()
        }
        contentStack.addArrangedSubview(titleContainer)

        let titleDivider = UIView()
        titleDivider.backgroundColor = UIColor(hex: 0xEEEEEE)
        titleDivider.snp.makeConstraints { make in make.height.equalTo(0.5) }
        contentStack.addArrangedSubview(titleDivider)

        switch layout {
        case .upload:
            contentStack.addArrangedSubview(makeUploadContent())
        case .controls:
            contentStack.addArrangedSubview(makeControlsContent())
        }

        let divider = UIView()
        divider.backgroundColor = UIColor(hex: 0xEEEEEE)
        divider.snp.makeConstraints { make in make.height.equalTo(0.5) }
        contentStack.addArrangedSubview(divider)
        contentStack.addArrangedSubview(makeCancelArea())
        let bottomSpacer = UIView()
        bottomSpacer.snp.makeConstraints { make in make.height.equalTo(12) }
        contentStack.addArrangedSubview(bottomSpacer)
    }

    private func setupConstraints() {
        dimView.snp.makeConstraints { make in make.edges.equalToSuperview() }
        panelView.snp.makeConstraints { make in
            make.leading.trailing.bottom.equalToSuperview()
            make.top.greaterThanOrEqualTo(view.safeAreaLayoutGuide).offset(20)
        }
        contentStack.snp.makeConstraints { make in
            make.top.leading.trailing.equalToSuperview()
            make.bottom.equalTo(view.safeAreaLayoutGuide)
        }
    }

    private func makeUploadContent() -> UIView {
        let container = UIView()
        let stack = UIStackView()
        stack.axis = .vertical
        stack.spacing = 12
        container.addSubview(stack)
        stack.snp.makeConstraints { make in make.edges.equalToSuperview().inset(16) }

        items.enumerated().forEach { index, item in
            let row = UIView()
            row.layer.cornerRadius = 8
            row.layer.borderWidth = 1
            row.layer.borderColor = UIColor(hex: 0xF4F4F4).cgColor

            let iconView = UIImageView(image: item.image?.withRenderingMode(.alwaysOriginal))
            iconView.contentMode = .scaleAspectFit
            let label = UILabel()
            label.text = item.title
            label.font = .systemFont(ofSize: 14, weight: .bold)
            label.textColor = .black
            let button = UIButton(type: .custom)
            button.tag = index
            button.accessibilityLabel = item.title
            button.addTarget(self, action: #selector(itemTapped(_:)), for: .touchUpInside)

            row.addSubview(iconView)
            row.addSubview(label)
            row.addSubview(button)
            iconView.snp.makeConstraints { make in
                make.leading.equalToSuperview().offset(16)
                make.centerY.equalToSuperview()
                make.width.height.equalTo(32)
            }
            label.snp.makeConstraints { make in
                make.leading.equalTo(iconView.snp.trailing).offset(12)
                make.centerY.equalToSuperview()
                make.trailing.lessThanOrEqualToSuperview().inset(16)
            }
            button.snp.makeConstraints { make in make.edges.equalToSuperview() }
            row.snp.makeConstraints { make in make.height.equalTo(56) }
            stack.addArrangedSubview(row)
        }
        return container
    }

    private func makeControlsContent() -> UIView {
        let row = UIStackView()
        row.axis = .horizontal
        row.distribution = .fillEqually

        items.enumerated().forEach { index, item in
            let container = UIView()
            let iconView = UIImageView(image: item.image?.withRenderingMode(.alwaysOriginal))
            iconView.contentMode = .scaleAspectFit
            let label = UILabel()
            label.text = item.title
            label.font = .systemFont(ofSize: 14)
            label.textColor = UIColor(hex: 0x4B5563)
            label.textAlignment = .center
            let button = UIButton(type: .custom)
            button.tag = index
            button.accessibilityLabel = item.title
            button.addTarget(self, action: #selector(itemTapped(_:)), for: .touchUpInside)

            container.addSubview(iconView)
            container.addSubview(label)
            container.addSubview(button)
            iconView.snp.makeConstraints { make in
                make.top.equalToSuperview().offset(28)
                make.centerX.equalToSuperview()
                make.width.height.equalTo(24)
            }
            label.snp.makeConstraints { make in
                make.top.equalTo(iconView.snp.bottom).offset(8)
                make.leading.trailing.equalToSuperview().inset(4)
            }
            button.snp.makeConstraints { make in make.edges.equalToSuperview() }
            container.snp.makeConstraints { make in make.height.equalTo(105) }
            row.addArrangedSubview(container)
        }
        return row
    }

    private func makeCancelArea() -> UIView {
        let container = UIView()
        let button = UIButton(type: .system)
        button.setTitle("取消", for: .normal)
        button.setTitleColor(UIColor(hex: 0x4B5563), for: .normal)
        button.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium)
        button.backgroundColor = UIColor(hex: 0xF4F4F4)
        button.layer.cornerRadius = 12
        button.addTarget(self, action: #selector(cancelTapped), for: .touchUpInside)
        container.addSubview(button)
        button.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(16)
            make.height.equalTo(48)
        }
        return container
    }

    private func close(completion: (() -> Void)? = nil) {
        UIView.animate(withDuration: 0.2, delay: 0, options: [.curveEaseIn]) {
            self.dimView.alpha = 0
            self.panelView.transform = CGAffineTransform(translationX: 0, y: self.panelView.bounds.height + 40)
        } completion: { _ in
            self.dismiss(animated: false, completion: completion)
        }
    }

    @objc private func itemTapped(_ sender: UIButton) {
        guard items.indices.contains(sender.tag) else { return }
        let handler = items[sender.tag].handler
        close(completion: handler)
    }

    @objc private func cancelTapped() {
        close()
    }
}

/// 云盘居中对话框基类，提供 Android 风格遮罩、圆角和转场。
class CloudDriveOverlayDialogViewController: UIViewController {
    let dimView = UIView()
    let cardView = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()
        modalPresentationStyle = .overFullScreen
        view.backgroundColor = .clear
        dimView.backgroundColor = UIColor.black.withAlphaComponent(0.35)
        cardView.backgroundColor = .white
        cardView.layer.cornerRadius = 12
        cardView.clipsToBounds = true
        view.addSubview(dimView)
        view.addSubview(cardView)
        dimView.snp.makeConstraints { make in make.edges.equalToSuperview() }
        dimView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(cancelOverlay)))
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        dimView.alpha = 0
        cardView.alpha = 0
        cardView.transform = CGAffineTransform(scaleX: 0.94, y: 0.94)
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        UIView.animate(withDuration: 0.2) {
            self.dimView.alpha = 1
            self.cardView.alpha = 1
            self.cardView.transform = .identity
        }
    }

    func dismissOverlay(completion: (() -> Void)? = nil) {
        UIView.animate(withDuration: 0.16) {
            self.dimView.alpha = 0
            self.cardView.alpha = 0
            self.cardView.transform = CGAffineTransform(scaleX: 0.96, y: 0.96)
        } completion: { _ in
            self.dismiss(animated: false, completion: completion)
        }
    }

    @objc private func cancelOverlay() {
        dismissOverlay()
    }
}

/// Android `WeDialog` 对齐的云盘删除确认对话框。
final class CloudDriveConfirmationDialogViewController: CloudDriveOverlayDialogViewController {
    private let dialogTitle: String
    private let message: String
    private let onConfirm: () -> Void

    /// 创建删除确认对话框。
    init(title: String, message: String, onConfirm: @escaping () -> Void) {
        dialogTitle = title
        self.message = message
        self.onConfirm = onConfirm
        super.init(nibName: nil, bundle: nil)
        modalPresentationStyle = .overFullScreen
    }

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

    override func viewDidLoad() {
        super.viewDidLoad()

        let titleLabel = UILabel()
        titleLabel.text = dialogTitle
        titleLabel.font = .systemFont(ofSize: 17, weight: .bold)
        titleLabel.textColor = .black
        titleLabel.textAlignment = .center
        let messageLabel = UILabel()
        messageLabel.text = message
        messageLabel.font = .systemFont(ofSize: 17)
        messageLabel.textColor = .black
        messageLabel.textAlignment = .center
        messageLabel.numberOfLines = 0
        let divider = UIView()
        divider.backgroundColor = UIColor(hex: 0xD1D5DB)
        let verticalDivider = UIView()
        verticalDivider.backgroundColor = UIColor(hex: 0xD1D5DB)
        let cancelButton = makeDialogButton(title: "取消", color: .black, action: #selector(cancelTapped))
        let confirmButton = makeDialogButton(title: "确定", color: AppColor.primary, action: #selector(confirmTapped))

        [titleLabel, messageLabel, divider, cancelButton, verticalDivider, confirmButton].forEach(cardView.addSubview)
        cardView.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.width.equalToSuperview().multipliedBy(0.8)
        }
        titleLabel.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(32)
            make.leading.trailing.equalToSuperview().inset(24)
        }
        messageLabel.snp.makeConstraints { make in
            make.top.equalTo(titleLabel.snp.bottom).offset(16)
            make.leading.trailing.equalToSuperview().inset(24)
        }
        divider.snp.makeConstraints { make in
            make.top.equalTo(messageLabel.snp.bottom).offset(32)
            make.leading.trailing.equalToSuperview()
            make.height.equalTo(0.5)
        }
        cancelButton.snp.makeConstraints { make in
            make.top.equalTo(divider.snp.bottom)
            make.leading.bottom.equalToSuperview()
            make.height.equalTo(56)
        }
        confirmButton.snp.makeConstraints { make in
            make.top.bottom.width.equalTo(cancelButton)
            make.leading.equalTo(cancelButton.snp.trailing)
            make.trailing.equalToSuperview()
        }
        verticalDivider.snp.makeConstraints { make in
            make.top.equalTo(divider.snp.bottom)
            make.bottom.equalToSuperview()
            make.centerX.equalToSuperview()
            make.width.equalTo(0.5)
        }
    }

    private func makeDialogButton(title: String, color: UIColor, action: Selector) -> UIButton {
        let button = UIButton(type: .system)
        button.setTitle(title, for: .normal)
        button.setTitleColor(color, for: .normal)
        button.titleLabel?.font = .systemFont(ofSize: 17, weight: .bold)
        button.addTarget(self, action: action, for: .touchUpInside)
        return button
    }

    @objc private func cancelTapped() {
        dismissOverlay()
    }

    @objc private func confirmTapped() {
        dismissOverlay(completion: onConfirm)
    }
}

/// Android `AddFolderDialog` 对齐的新建文件夹输入对话框。
final class CloudDriveTextInputDialogViewController: CloudDriveOverlayDialogViewController {
    private let dialogTitle: String
    private let placeholder: String
    private let onConfirm: (String) -> Void
    private let textField = UITextField()
    private let confirmButton = UIButton(type: .system)

    /// 创建文本输入对话框。
    init(title: String, placeholder: String, onConfirm: @escaping (String) -> Void) {
        dialogTitle = title
        self.placeholder = placeholder
        self.onConfirm = onConfirm
        super.init(nibName: nil, bundle: nil)
        modalPresentationStyle = .overFullScreen
    }

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

    override func viewDidLoad() {
        super.viewDidLoad()
        cardView.layer.cornerRadius = 16
        let titleLabel = UILabel()
        titleLabel.text = dialogTitle
        titleLabel.font = .systemFont(ofSize: 18, weight: .bold)
        titleLabel.textColor = .black
        let divider = UIView()
        divider.backgroundColor = UIColor(hex: 0xEEEEEE)

        textField.placeholder = placeholder
        textField.font = .systemFont(ofSize: 14)
        textField.textColor = UIColor(hex: 0x333333)
        textField.backgroundColor = UIColor(hex: 0xF4F4F4)
        textField.layer.cornerRadius = 8
        textField.leftView = UIView(frame: CGRect(x: 0, y: 0, width: 12, height: 1))
        textField.leftViewMode = .always
        textField.clearButtonMode = .whileEditing
        textField.returnKeyType = .done
        textField.addTarget(self, action: #selector(textChanged), for: .editingChanged)
        textField.addTarget(self, action: #selector(confirmTapped), for: .editingDidEndOnExit)

        let cancelButton = UIButton(type: .system)
        cancelButton.setTitle("取消", for: .normal)
        cancelButton.setTitleColor(AppColor.primary, for: .normal)
        cancelButton.titleLabel?.font = .systemFont(ofSize: 14)
        cancelButton.backgroundColor = UIColor(hex: 0xEFF6FF)
        cancelButton.layer.cornerRadius = 8
        cancelButton.addTarget(self, action: #selector(cancelTapped), for: .touchUpInside)

        confirmButton.setTitle("确定", for: .normal)
        confirmButton.setTitleColor(.white, for: .normal)
        confirmButton.titleLabel?.font = .systemFont(ofSize: 14)
        confirmButton.layer.cornerRadius = 8
        confirmButton.addTarget(self, action: #selector(confirmTapped), for: .touchUpInside)
        confirmButton.isEnabled = false
        updateConfirmAppearance()

        [titleLabel, divider, textField, cancelButton, confirmButton].forEach(cardView.addSubview)
        cardView.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.leading.trailing.equalToSuperview().inset(28)
        }
        titleLabel.snp.makeConstraints { make in
            make.top.equalToSuperview()
            make.leading.trailing.equalToSuperview().inset(16)
            make.height.equalTo(52)
        }
        divider.snp.makeConstraints { make in
            make.top.equalTo(titleLabel.snp.bottom)
            make.leading.trailing.equalToSuperview()
            make.height.equalTo(1)
        }
        textField.snp.makeConstraints { make in
            make.top.equalTo(divider.snp.bottom).offset(16)
            make.leading.trailing.equalToSuperview().inset(16)
            make.height.equalTo(48)
        }
        confirmButton.snp.makeConstraints { make in
            make.top.equalTo(textField.snp.bottom).offset(20)
            make.trailing.bottom.equalToSuperview().inset(16)
            make.width.equalTo(72)
            make.height.equalTo(38)
        }
        cancelButton.snp.makeConstraints { make in
            make.trailing.equalTo(confirmButton.snp.leading).offset(-8)
            make.centerY.width.height.equalTo(confirmButton)
        }

        NotificationCenter.default.addObserver(
            self,
            selector: #selector(keyboardFrameChanged(_:)),
            name: UIResponder.keyboardWillChangeFrameNotification,
            object: nil
        )
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    private func updateConfirmAppearance() {
        confirmButton.backgroundColor = confirmButton.isEnabled ? AppColor.primary : AppColor.buttonDisabled
    }

    @objc private func textChanged() {
        confirmButton.isEnabled = !(textField.text ?? "").trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
        updateConfirmAppearance()
    }

    @objc private func cancelTapped() {
        view.endEditing(true)
        dismissOverlay()
    }

    @objc private func confirmTapped() {
        let value = (textField.text ?? "").trimmingCharacters(in: .whitespacesAndNewlines)
        guard !value.isEmpty else { return }
        view.endEditing(true)
        dismissOverlay { [onConfirm] in onConfirm(value) }
    }

    @objc private func keyboardFrameChanged(_ notification: Notification) {
        guard let frame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }
        let frameInView = view.convert(frame, from: nil)
        let overlap = max(0, cardView.frame.maxY + 16 - frameInView.minY)
        UIView.animate(withDuration: 0.2) {
            self.cardView.transform = CGAffineTransform(translationX: 0, y: -overlap)
        }
    }
}

/// Android `MoveFileDialog` 对齐的云盘移动目标对话框。
final class CloudDriveMoveDialogViewController: CloudDriveOverlayDialogViewController, UITableViewDataSource, UITableViewDelegate {
    private let folders: [CloudFile]
    private let onConfirm: (Int) -> Void
    private let tableView = UITableView(frame: .zero, style: .plain)
    private var selectedID: Int

    /// 创建移动目标选择对话框。
    init(folders: [CloudFile], onConfirm: @escaping (Int) -> Void) {
        self.folders = folders
        self.onConfirm = onConfirm
        selectedID = folders.first?.id ?? 0
        super.init(nibName: nil, bundle: nil)
        modalPresentationStyle = .overFullScreen
    }

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

    override func viewDidLoad() {
        super.viewDidLoad()
        cardView.layer.cornerRadius = 28
        let titleLabel = UILabel()
        titleLabel.text = "移动到"
        titleLabel.font = .systemFont(ofSize: 16, weight: .semibold)
        titleLabel.textColor = UIColor(hex: 0x333333)
        let messageLabel = UILabel()
        messageLabel.text = "请选择目标文件夹"
        messageLabel.font = .systemFont(ofSize: 14)
        messageLabel.textColor = UIColor(hex: 0x666666)

        tableView.backgroundColor = .white
        tableView.separatorStyle = .none
        tableView.rowHeight = 44
        tableView.dataSource = self
        tableView.delegate = self

        let cancelButton = makeTextButton(title: "取消", color: UIColor(hex: 0x666666), action: #selector(cancelTapped))
        let confirmButton = makeTextButton(title: "确定", color: AppColor.primary, action: #selector(confirmTapped))

        [titleLabel, messageLabel, tableView, cancelButton, confirmButton].forEach(cardView.addSubview)
        cardView.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.leading.trailing.equalToSuperview().inset(28)
        }
        titleLabel.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(24)
            make.leading.trailing.equalToSuperview().inset(24)
        }
        messageLabel.snp.makeConstraints { make in
            make.top.equalTo(titleLabel.snp.bottom).offset(12)
            make.leading.trailing.equalTo(titleLabel)
        }
        tableView.snp.makeConstraints { make in
            make.top.equalTo(messageLabel.snp.bottom).offset(12)
            make.leading.trailing.equalToSuperview().inset(16)
            make.height.equalTo(min(CGFloat(max(folders.count, 1)) * 44, UIScreen.main.bounds.height * 0.6))
        }
        confirmButton.snp.makeConstraints { make in
            make.top.equalTo(tableView.snp.bottom).offset(8)
            make.trailing.bottom.equalToSuperview().inset(12)
            make.width.equalTo(64)
            make.height.equalTo(44)
        }
        cancelButton.snp.makeConstraints { make in
            make.trailing.equalTo(confirmButton.snp.leading)
            make.centerY.width.height.equalTo(confirmButton)
        }
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        folders.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let reuseIdentifier = "CloudDriveMoveFolderCell"
        let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier)
            ?? UITableViewCell(style: .default, reuseIdentifier: reuseIdentifier)
        configure(cell, folder: folders[indexPath.row])
        return cell
    }

    private func configure(_ cell: UITableViewCell, folder: CloudFile) {
        cell.textLabel?.text = folder.name
        cell.textLabel?.font = .systemFont(ofSize: 14)
        cell.textLabel?.textColor = UIColor(hex: 0x333333)
        cell.imageView?.image = UIImage(
            systemName: selectedID == folder.id ? "circle.inset.filled" : "circle",
            withConfiguration: UIImage.SymbolConfiguration(pointSize: 20)
        )
        cell.imageView?.tintColor = AppColor.primary
        cell.selectionStyle = .none
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let previousID = selectedID
        selectedID = folders[indexPath.row].id
        if let previousIndex = folders.firstIndex(where: { $0.id == previousID }),
           let previousCell = tableView.cellForRow(at: IndexPath(row: previousIndex, section: 0)) {
            configure(previousCell, folder: folders[previousIndex])
        }
        if let selectedCell = tableView.cellForRow(at: indexPath) {
            configure(selectedCell, folder: folders[indexPath.row])
        }
    }

    private func makeTextButton(title: String, color: UIColor, action: Selector) -> UIButton {
        let button = UIButton(type: .system)
        button.setTitle(title, for: .normal)
        button.setTitleColor(color, for: .normal)
        button.titleLabel?.font = .systemFont(ofSize: 14, weight: .medium)
        button.addTarget(self, action: action, for: .touchUpInside)
        return button
    }

    @objc private func cancelTapped() {
        dismissOverlay()
    }

    @objc private func confirmTapped() {
        let selectedID = selectedID
        dismissOverlay { [onConfirm] in onConfirm(selectedID) }
    }
}
