//
//  TaskAddViews.swift
//  suixinkan
//

import Kingfisher
import SnapKit
import UIKit

/// 添加任务素材网格区。
final class TaskAddMediaSectionView: UIView {

    var onCloudImport: (() -> Void)?
    var onLocalImport: (() -> Void)?
    var onFileTap: ((TaskFileItem) -> Void)?
    var onDeleteFile: ((TaskFileItem) -> Void)?

    private var files: [TaskFileItem] = []
    private var collectionHeightConstraint: Constraint?

    private enum Section { case main }
    private enum Item: Hashable { case add; case file(String) }

    private lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewCompositionalLayout { _, environment in
            let columns = 3
            let spacing: CGFloat = 8
            let inset = AppSpacing.md * 2
            let availableWidth = environment.container.effectiveContentSize.width - inset
            let totalSpacing = spacing * CGFloat(columns - 1)
            let itemWidth = max(0, (availableWidth - totalSpacing) / CGFloat(columns))
            let itemHeight = itemWidth / 1.77
            let itemSize = NSCollectionLayoutSize(
                widthDimension: .absolute(itemWidth),
                heightDimension: .absolute(itemHeight)
            )
            let item = NSCollectionLayoutItem(layoutSize: itemSize)
            let groupSize = NSCollectionLayoutSize(
                widthDimension: .fractionalWidth(1),
                heightDimension: .absolute(itemHeight)
            )
            let group = NSCollectionLayoutGroup.horizontal(
                layoutSize: groupSize,
                repeatingSubitem: item,
                count: columns
            )
            group.interItemSpacing = .fixed(spacing)
            let section = NSCollectionLayoutSection(group: group)
            section.interGroupSpacing = spacing
            return section
        }
        let view = UICollectionView(frame: .zero, collectionViewLayout: layout)
        view.backgroundColor = .clear
        view.isScrollEnabled = false
        return view
    }()

    private lazy var dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collectionView) {
        [weak self] collectionView, indexPath, item in
        switch item {
        case .add:
            let cell = collectionView.dequeueReusableCell(
                withReuseIdentifier: TaskAddAddMediaCell.reuseIdentifier,
                for: indexPath
            ) as! TaskAddAddMediaCell
            return cell
        case .file(let id):
            let cell = collectionView.dequeueReusableCell(
                withReuseIdentifier: TaskAddMediaCell.reuseIdentifier,
                for: indexPath
            ) as! TaskAddMediaCell
            if let file = self?.files.first(where: { $0.id == id }) {
                cell.apply(file: file)
                cell.onDelete = { self?.onDeleteFile?(file) }
            }
            return cell
        }
    }

    private let titleLabel = UILabel()
    private let tipsLabel = UILabel()
    private let cloudButton = UIButton(type: .system)

    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .white
        layer.cornerRadius = AppRadius.md

        titleLabel.text = "添加图片"
        titleLabel.font = .app(.bodyMedium)
        titleLabel.textColor = AppColor.textPrimary

        tipsLabel.text = "(点击图片或视频可添加备注)"
        tipsLabel.font = .app(.caption)
        tipsLabel.textColor = AppColor.textPrimary

        cloudButton.setTitle("云盘导入", for: .normal)
        cloudButton.setTitleColor(AppColor.primary, for: .normal)
        cloudButton.titleLabel?.font = .app(.caption)
        cloudButton.addTarget(self, action: #selector(cloudTapped), for: .touchUpInside)

        collectionView.register(TaskAddMediaCell.self, forCellWithReuseIdentifier: TaskAddMediaCell.reuseIdentifier)
        collectionView.register(TaskAddAddMediaCell.self, forCellWithReuseIdentifier: TaskAddAddMediaCell.reuseIdentifier)
        collectionView.delegate = self

        addSubview(titleLabel)
        addSubview(tipsLabel)
        addSubview(cloudButton)
        addSubview(collectionView)

        titleLabel.snp.makeConstraints { make in
            make.top.leading.equalToSuperview().offset(AppSpacing.md)
        }
        tipsLabel.snp.makeConstraints { make in
            make.leading.equalTo(titleLabel.snp.trailing).offset(AppSpacing.xxs)
            make.centerY.equalTo(titleLabel)
        }
        cloudButton.snp.makeConstraints { make in
            make.trailing.equalToSuperview().inset(AppSpacing.md)
            make.centerY.equalTo(titleLabel)
        }
        collectionView.snp.makeConstraints { make in
            make.top.equalTo(titleLabel.snp.bottom).offset(AppSpacing.sm)
            make.leading.trailing.equalToSuperview().inset(AppSpacing.md)
            make.bottom.equalToSuperview().inset(AppSpacing.md)
            collectionHeightConstraint = make.height.equalTo(88).constraint
        }
    }

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

    func apply(files: [TaskFileItem]) {
        self.files = files
        var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
        snapshot.appendSections([.main])
        snapshot.appendItems(files.map { Item.file($0.id) } + [.add])
        dataSource.apply(snapshot, animatingDifferences: false)
        collectionView.layoutIfNeeded()
        let height = max(88, collectionView.collectionViewLayout.collectionViewContentSize.height)
        collectionHeightConstraint?.update(offset: height)
    }

    @objc private func cloudTapped() {
        onCloudImport?()
    }
}

extension TaskAddMediaSectionView: UICollectionViewDelegate {
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        guard let item = dataSource.itemIdentifier(for: indexPath) else { return }
        switch item {
        case .add:
            onLocalImport?()
        case .file(let id):
            guard let file = files.first(where: { $0.id == id }) else { return }
            onFileTap?(file)
        }
    }
}

/// 素材缩略图 cell。
final class TaskAddMediaCell: UICollectionViewCell {

    static let reuseIdentifier = "TaskAddMediaCell"

    var onDelete: (() -> Void)?

    private let imageView = UIImageView()
    private let overlayView = UIView()
    private let progressLabel = UILabel()
    private let deleteButton = UIButton(type: .system)
    private let playIconView = UIImageView()

    override init(frame: CGRect) {
        super.init(frame: frame)
        contentView.backgroundColor = AppColor.inputBackground
        contentView.layer.cornerRadius = AppRadius.sm
        contentView.clipsToBounds = true

        imageView.contentMode = .scaleAspectFill
        imageView.clipsToBounds = true

        overlayView.backgroundColor = UIColor.black.withAlphaComponent(0.35)
        overlayView.isHidden = true

        progressLabel.font = .app(.captionMedium)
        progressLabel.textColor = .white
        progressLabel.textAlignment = .center

        deleteButton.setImage(UIImage(systemName: "xmark.circle.fill"), for: .normal)
        deleteButton.tintColor = .white
        deleteButton.addTarget(self, action: #selector(deleteTapped), for: .touchUpInside)

        playIconView.image = UIImage(systemName: "play.circle.fill")
        playIconView.tintColor = .white
        playIconView.isHidden = true

        contentView.addSubview(imageView)
        contentView.addSubview(overlayView)
        contentView.addSubview(playIconView)
        contentView.addSubview(progressLabel)
        contentView.addSubview(deleteButton)

        imageView.snp.makeConstraints { make in make.edges.equalToSuperview() }
        overlayView.snp.makeConstraints { make in make.edges.equalToSuperview() }
        playIconView.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.width.height.equalTo(28)
        }
        progressLabel.snp.makeConstraints { make in make.center.equalToSuperview() }
        deleteButton.snp.makeConstraints { make in
            make.top.trailing.equalToSuperview().inset(AppSpacing.xxs)
            make.width.height.equalTo(22)
        }
    }

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

    override func prepareForReuse() {
        super.prepareForReuse()
        onDelete = nil
        imageView.kf.cancelDownloadTask()
        imageView.image = nil
    }

    func apply(file: TaskFileItem) {
        let urlString = file.previewURLString
        if let url = URL(string: urlString), !urlString.isEmpty {
            imageView.kf.setImage(with: url)
        } else {
            imageView.image = UIImage(systemName: "photo")
            imageView.tintColor = AppColor.textTertiary
        }
        playIconView.isHidden = file.fileType != 1
        if file.isUploading {
            overlayView.isHidden = false
            progressLabel.text = "\(file.uploadProgress)%"
        } else {
            overlayView.isHidden = true
            progressLabel.text = nil
        }
    }

    @objc private func deleteTapped() {
        onDelete?()
    }
}

/// 本地导入占位 cell。
final class TaskAddAddMediaCell: UICollectionViewCell {

    static let reuseIdentifier = "TaskAddAddMediaCell"

    private let iconView = UIImageView()
    private let titleLabel = UILabel()

    override init(frame: CGRect) {
        super.init(frame: frame)
        contentView.backgroundColor = AppColor.inputBackground
        contentView.layer.cornerRadius = AppRadius.sm

        iconView.image = UIImage(systemName: "plus")
        iconView.tintColor = AppColor.textTabInactive

        titleLabel.text = "本地导入"
        titleLabel.font = .app(.caption)
        titleLabel.textColor = AppColor.textTabInactive

        contentView.addSubview(iconView)
        contentView.addSubview(titleLabel)
        iconView.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.centerY.equalToSuperview().offset(-8)
            make.width.height.equalTo(24)
        }
        titleLabel.snp.makeConstraints { make in
            make.top.equalTo(iconView.snp.bottom).offset(2)
            make.centerX.equalToSuperview()
        }
    }

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

/// 任务优先级选择区。
final class TaskPrioritySectionView: UIView {

    var onUrgentHourChange: ((Int) -> Void)?
    var onCustomHourTextChange: ((String) -> Void)?

    private let titleLabel = UILabel()
    private let noneButton = UIButton(type: .system)
    private let twoHourButton = UIButton(type: .system)
    private let customButton = UIButton(type: .system)
    private let customField = UITextField()

    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .white
        layer.cornerRadius = AppRadius.md

        titleLabel.text = "优先级"
        titleLabel.font = .app(.bodyMedium)
        titleLabel.textColor = AppColor.textPrimary

        configureOptionButton(noneButton, title: "不加急")
        configureOptionButton(twoHourButton, title: "加急(2小时)")
        configureOptionButton(customButton, title: "自定义")

        noneButton.addTarget(self, action: #selector(noneTapped), for: .touchUpInside)
        twoHourButton.addTarget(self, action: #selector(twoHourTapped), for: .touchUpInside)
        customButton.addTarget(self, action: #selector(customTapped), for: .touchUpInside)

        customField.placeholder = "请输入小时数"
        customField.font = .app(.body)
        customField.textColor = AppColor.textPrimary
        customField.keyboardType = .numberPad
        customField.borderStyle = .roundedRect
        customField.isHidden = true
        customField.addTarget(self, action: #selector(customFieldChanged), for: .editingChanged)

        let row = UIStackView(arrangedSubviews: [noneButton, twoHourButton, customButton])
        row.axis = .horizontal
        row.spacing = AppSpacing.xs
        row.distribution = .fillEqually

        addSubview(titleLabel)
        addSubview(row)
        addSubview(customField)

        titleLabel.snp.makeConstraints { make in
            make.top.leading.equalToSuperview().offset(AppSpacing.md)
        }
        row.snp.makeConstraints { make in
            make.top.equalTo(titleLabel.snp.bottom).offset(AppSpacing.sm)
            make.leading.trailing.equalToSuperview().inset(AppSpacing.md)
            make.height.equalTo(42)
        }
        customField.snp.makeConstraints { make in
            make.top.equalTo(row.snp.bottom).offset(AppSpacing.sm)
            make.leading.trailing.equalToSuperview().inset(AppSpacing.md)
            make.bottom.equalToSuperview().inset(AppSpacing.md)
            make.height.equalTo(40)
        }
    }

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

    func apply(urgentHour: Int) {
        let isCustom = urgentHour > 0 && urgentHour != 2
        styleOption(noneButton, selected: urgentHour == 0)
        styleOption(twoHourButton, selected: urgentHour == 2)
        styleOption(customButton, selected: isCustom)
        customField.isHidden = !isCustom
        if isCustom {
            customField.text = "\(urgentHour)"
        } else {
            customField.text = ""
        }
    }

    private func configureOptionButton(_ button: UIButton, title: String) {
        button.setTitle(title, for: .normal)
        button.titleLabel?.font = .app(.caption)
        button.layer.cornerRadius = AppRadius.xs
        button.clipsToBounds = true
    }

    private func styleOption(_ button: UIButton, selected: Bool) {
        button.backgroundColor = selected ? AppColor.primary : AppColor.inputBackground
        button.setTitleColor(selected ? .white : AppColor.textSecondary, for: .normal)
    }

    @objc private func noneTapped() { onUrgentHourChange?(0) }
    @objc private func twoHourTapped() { onUrgentHourChange?(2) }
    @objc private func customTapped() {
        onUrgentHourChange?(1)
        onCustomHourTextChange?("1")
    }
    @objc private func customFieldChanged() {
        onCustomHourTextChange?(customField.text ?? "")
    }
}

/// 关联订单选择按钮。
final class TaskOrderSelectButton: UIControl {

    private let titleLabel = UILabel()
    private let arrowView = UIImageView(image: UIImage(systemName: "chevron.down"))

    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .white
        layer.cornerRadius = AppRadius.sm
        layer.borderWidth = 1
        layer.borderColor = AppColor.border.cgColor

        titleLabel.font = .app(.bodyMedium)
        titleLabel.textColor = AppColor.textTabInactive
        titleLabel.text = "关联订单（可选）"

        arrowView.tintColor = AppColor.textTabInactive

        addSubview(titleLabel)
        addSubview(arrowView)
        titleLabel.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(AppSpacing.sm)
            make.centerY.equalToSuperview()
        }
        arrowView.snp.makeConstraints { make in
            make.trailing.equalToSuperview().inset(AppSpacing.sm)
            make.centerY.equalToSuperview()
        }
        snp.makeConstraints { make in make.height.equalTo(44) }
    }

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

    func apply(orderNumber: String?) {
        if let orderNumber, !orderNumber.isEmpty {
            titleLabel.text = orderNumber
            titleLabel.textColor = AppColor.textPrimary
        } else {
            titleLabel.text = "关联订单（可选）"
            titleLabel.textColor = AppColor.textTabInactive
        }
    }
}

/// 任务素材备注弹窗。
final class TaskFileRemarkDialogView: UIView {

    var onCancel: (() -> Void)?
    var onConfirm: (() -> Void)?

    private let containerView = UIView()
    private let titleLabel = UILabel()
    private let previewView = UIImageView()
    private let textView = UITextView()
    private let countLabel = UILabel()
    private let cancelButton = UIButton(type: .system)
    private let confirmButton = UIButton(type: .system)

    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = AppColor.overlayScrim

        containerView.backgroundColor = .white
        containerView.layer.cornerRadius = AppRadius.md

        titleLabel.text = "备注信息"
        titleLabel.font = .app(.title)

        previewView.contentMode = .scaleAspectFill
        previewView.clipsToBounds = true
        previewView.layer.cornerRadius = AppRadius.sm
        previewView.backgroundColor = AppColor.inputBackground

        textView.font = .app(.body)
        textView.layer.borderWidth = 1
        textView.layer.borderColor = AppColor.border.cgColor
        textView.layer.cornerRadius = AppRadius.sm
        textView.delegate = self

        countLabel.font = .app(.caption)
        countLabel.textColor = AppColor.textTertiary
        countLabel.text = "0/50"

        cancelButton.setTitle("取消", for: .normal)
        cancelButton.setTitleColor(AppColor.textSecondary, for: .normal)
        cancelButton.backgroundColor = AppColor.inputBackground
        cancelButton.layer.cornerRadius = AppRadius.xs
        cancelButton.addTarget(self, action: #selector(cancelTapped), for: .touchUpInside)

        confirmButton.setTitle("确定", for: .normal)
        confirmButton.setTitleColor(.white, for: .normal)
        confirmButton.backgroundColor = AppColor.primary
        confirmButton.layer.cornerRadius = AppRadius.xs
        confirmButton.addTarget(self, action: #selector(confirmTapped), for: .touchUpInside)

        addSubview(containerView)
        containerView.addSubview(titleLabel)
        containerView.addSubview(previewView)
        containerView.addSubview(textView)
        containerView.addSubview(countLabel)
        containerView.addSubview(cancelButton)
        containerView.addSubview(confirmButton)

        containerView.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.leading.trailing.equalToSuperview().inset(AppSpacing.lg)
        }
        titleLabel.snp.makeConstraints { make in
            make.top.leading.equalToSuperview().offset(AppSpacing.md)
        }
        previewView.snp.makeConstraints { make in
            make.top.equalTo(titleLabel.snp.bottom).offset(AppSpacing.sm)
            make.leading.trailing.equalToSuperview().inset(AppSpacing.md)
            make.height.equalTo(160)
        }
        textView.snp.makeConstraints { make in
            make.top.equalTo(previewView.snp.bottom).offset(AppSpacing.sm)
            make.leading.trailing.equalToSuperview().inset(AppSpacing.md)
            make.height.equalTo(80)
        }
        countLabel.snp.makeConstraints { make in
            make.top.equalTo(textView.snp.bottom).offset(AppSpacing.xxs)
            make.trailing.equalTo(textView)
        }
        cancelButton.snp.makeConstraints { make in
            make.top.equalTo(countLabel.snp.bottom).offset(AppSpacing.md)
            make.leading.bottom.equalToSuperview().inset(AppSpacing.md)
            make.height.equalTo(36)
            make.width.equalTo(72)
        }
        confirmButton.snp.makeConstraints { make in
            make.centerY.equalTo(cancelButton)
            make.trailing.equalToSuperview().inset(AppSpacing.md)
            make.height.equalTo(36)
            make.width.equalTo(72)
        }
    }

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

    func apply(file: TaskFileItem, text: String) {
        textView.text = text
        countLabel.text = "\(text.count)/50"
        let urlString = file.previewURLString
        if let url = URL(string: urlString), !urlString.isEmpty {
            previewView.kf.setImage(with: url)
        } else {
            previewView.image = UIImage(systemName: "photo")
            previewView.tintColor = AppColor.textTertiary
        }
    }

    @objc private func cancelTapped() { onCancel?() }
    @objc private func confirmTapped() { onConfirm?() }

    /// 当前输入的备注文本。
    var inputText: String { textView.text ?? "" }
}

extension TaskFileRemarkDialogView: UITextViewDelegate {
    func textViewDidChange(_ textView: UITextView) {
        if textView.text.count > 50 {
            textView.text = String(textView.text.prefix(50))
        }
        countLabel.text = "\(textView.text.count)/50"
    }
}

/// 带边框的单行输入框。
final class TaskBorderTextField: UIView {

    let textField = UITextField()

    init(placeholder: String) {
        super.init(frame: .zero)
        backgroundColor = .white
        layer.cornerRadius = AppRadius.sm
        layer.borderWidth = 1
        layer.borderColor = AppColor.border.cgColor

        textField.placeholder = placeholder
        textField.font = .app(.body)
        textField.textColor = AppColor.textPrimary
        addSubview(textField)
        textField.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(UIEdgeInsets(top: 10, left: 12, bottom: 10, right: 12))
        }
        snp.makeConstraints { make in make.height.equalTo(44) }
    }

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

/// 带边框的多行输入框。
final class TaskBorderTextView: UIView {

    let textView = UITextView()

    init(placeholder: String) {
        super.init(frame: .zero)
        backgroundColor = .white
        layer.cornerRadius = AppRadius.sm
        layer.borderWidth = 1
        layer.borderColor = AppColor.border.cgColor

        textView.font = .app(.body)
        textView.textColor = AppColor.textPrimary
        textView.text = placeholder
        textView.textColor = AppColor.textTertiary
        addSubview(textView)
        textView.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(AppSpacing.xs)
        }
        snp.makeConstraints { make in make.height.equalTo(80) }
    }

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