import ForgejoKit
import SwiftUI

struct PullRequestMergeView: View {
    let repository: Repository
    let pullRequest: PullRequest
    @State private var authService: AuthenticationService
    @State private var mergeMethod = "merge"
    @State private var commitTitle = ""
    @State private var commitMessage = ""
    @State private var deleteBranch = false
    @State private var isMerging = false
    @State private var errorMessage: String?
    @State private var showError = false
    @Environment(\.dismiss) private var dismiss

    private let prService: PullRequestService?
    private let onMerged: () -> Void

    init(
        repository: Repository, pullRequest: PullRequest,
        authService: AuthenticationService,
        onMerged: @escaping () -> Void,
    ) {
        self.repository = repository
        self.pullRequest = pullRequest
        self.authService = authService
        prService = authService.client.map { PullRequestService(client: $0) }
        self.onMerged = onMerged
    }

    private var owner: String {
        repository.owner
    }

    private var repo: String {
        repository.repoName
    }

    var body: some View {
        NavigationStack {
            Form {
                Section("Merge Method") {
                    Picker("Method", selection: $mergeMethod) {
                        Text("Merge Commit").tag("merge")
                        Text("Rebase").tag("rebase")
                        Text("Squash").tag("squash")
                    }
                    .pickerStyle(.segmented)
                    .accessibilityIdentifier("merge-method-picker")
                }

                if mergeMethod != "rebase" {
                    Section("Commit Title") {
                        TextField("Title", text: $commitTitle)
                    }

                    Section("Commit Message") {
                        TextEditor(text: $commitMessage)
                            .frame(minHeight: 80)
                            .scrollContentBackground(.hidden)
                    }
                }

                Section {
                    Toggle("Delete branch after merge", isOn: $deleteBranch)
                        .accessibilityIdentifier("merge-delete-branch")
                }
            }
            .navigationTitle("Merge Pull Request")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("Cancel") { dismiss() }
                }
                ToolbarItem(placement: .confirmationAction) {
                    Button("Merge") {
                        Task { await merge() }
                    }
                    .disabled(isMerging)
                    .accessibilityIdentifier("merge-confirm")
                }
            }
            .errorAlert(message: $errorMessage, isPresented: $showError)
            .onAppear {
                if commitTitle.isEmpty {
                    commitTitle = pullRequest.title
                }
            }
        }
    }

    private func merge() async {
        guard let prService else { return }
        isMerging = true
        do {
            try await prService.mergePullRequest(
                owner: owner,
                repo: repo,
                index: pullRequest.number,
                method: mergeMethod,
                title: mergeMethod != "rebase" ? commitTitle : nil,
                message: mergeMethod != "rebase" ? commitMessage : nil,
                deleteBranch: deleteBranch,
            )
            NotificationCenter.default.post(name: .pullRequestsDidChange, object: nil)
            onMerged()
            dismiss()
        } catch {
            errorMessage = error.localizedDescription
            showError = true
        }
        isMerging = false
    }
}

#if DEBUG
    #Preview {
        PullRequestMergeView(
            repository: .preview,
            pullRequest: .preview,
            authService: .previewDefault,
        ) {}
    }
#endif
