import UIKit

extension UIViewController {
    func promptForSearchText(title: String, current: String, apply: @escaping (String) -> Void) {
        let alert = UIAlertController(title: title, message: nil, preferredStyle: .alert)
        alert.addTextField { field in
            field.text = current
            field.placeholder = "Search text"
            field.accessibilityLabel = "Search text"
            field.clearButtonMode = .whileEditing
            field.returnKeyType = .search
        }
        alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
        alert.addAction(UIAlertAction(title: "Apply", style: .default) { [weak alert] _ in
            apply(alert?.textFields?.first?.text ?? "")
        })
        present(alert, animated: true)
    }
}
@MainActor
protocol IssueSwipeActionHost: AnyObject {
    var context: AppContext { get }
    var owner: String { get }
    var repository: String { get }
    var issueMutationTask: Task<Void, Never>? { get set }
    func reloadIssuesAfterMutation()
}

extension IssueSwipeActionHost where Self: UIViewController {
    func issueSwipeActions(for row: IssueRow) -> UISwipeActionsConfiguration {
        let close = row.state != .closed
        let stateAction = UIContextualAction(
            style: .normal,
            title: close ? "Close" : "Open"
        ) { [weak self] _, _, completion in
            self?.setIssue(row, closed: close, completion: completion) ?? completion(false)
        }
        stateAction.image = context.symbol(close ? "checkmark.circle" : "arrow.uturn.left.circle")
        stateAction.backgroundColor = close ? .systemPurple : .systemGreen

        let deleteAction = UIContextualAction(style: .destructive, title: "Delete") {
            [weak self] _, _, completion in
            self?.confirmDeleteIssue(row, completion: completion) ?? completion(false)
        }
        deleteAction.image = context.symbol("trash")

        let configuration = UISwipeActionsConfiguration(actions: [stateAction, deleteAction])
        configuration.performsFirstActionWithFullSwipe = true
        return configuration
    }

    private func setIssue(
        _ row: IssueRow,
        closed: Bool,
        completion: @escaping (Bool) -> Void
    ) {
        issueMutationTask?.cancel()
        issueMutationTask = Task {
            do {
                try await context.core.setIssueClosed(
                    owner: owner,
                    repository: repository,
                    number: row.number,
                    closed: closed
                )
                guard !Task.isCancelled else {
                    completion(false)
                    return
                }
                completion(true)
                reloadIssuesAfterMutation()
            } catch {
                completion(false)
                if !Task.isCancelled { show(error: error) }
            }
        }
    }

    private func confirmDeleteIssue(_ row: IssueRow, completion: @escaping (Bool) -> Void) {
        let alert = UIAlertController(
            title: "Delete Issue #\(row.number)?",
            message: "“\(row.title)” will be permanently deleted. This can’t be undone.",
            preferredStyle: .alert
        )
        alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in completion(false) })
        alert.addAction(UIAlertAction(title: "Delete", style: .destructive) { [weak self] _ in
            guard let self else {
                completion(false)
                return
            }
            self.issueMutationTask?.cancel()
            self.issueMutationTask = Task {
                do {
                    try await self.context.core.deleteIssue(
                        owner: self.owner,
                        repository: self.repository,
                        number: row.number
                    )
                    guard !Task.isCancelled else {
                        completion(false)
                        return
                    }
                    completion(true)
                    self.reloadIssuesAfterMutation()
                } catch {
                    completion(false)
                    if !Task.isCancelled { self.show(error: error) }
                }
            }
        })
        present(alert, animated: true)
    }
}
