import ForgejoKit
import SwiftUI

struct WorkflowRunListView: View {
    let repository: Repository
    let workflowId: String?
    @State private var authService: AuthenticationService
    @State private var pagination = PaginationState<WorkflowRun>()
    @State private var statusFilter: WorkflowRunFilter = .all

    private let workflowService: WorkflowService?

    init(
        repository: Repository,
        authService: AuthenticationService,
        workflowId: String? = nil,
    ) {
        self.repository = repository
        self.authService = authService
        self.workflowId = workflowId
        workflowService = authService.client.map { WorkflowService(client: $0) }
    }

    private var owner: String {
        repository.owner
    }

    private var repo: String {
        repository.repoName
    }

    var body: some View {
        @Bindable var pagination = pagination
        VStack(spacing: 0) {
            SegmentedPickerSection(
                title: "Status",
                selection: $statusFilter,
                options: WorkflowRunFilter.allCases.map { ($0.label, $0) },
                accessibilityIdentifier: "workflow-run-status-picker",
            )

            List {
                if pagination.isLoading, pagination.items.isEmpty {
                    LoadingListSection()
                } else if pagination.items.isEmpty {
                    ContentUnavailableView {
                        Label("No Workflow Runs", systemImage: "play.slash")
                            .foregroundStyle(.secondary)
                    } description: {
                        Text("No runs match the selected filter.")
                    }
                } else {
                    Section {
                        ForEach(pagination.items) { run in
                            NavigationLink {
                                WorkflowRunDetailView(
                                    repository: repository,
                                    runId: run.id,
                                    authService: authService,
                                )
                            } label: {
                                WorkflowRunRow(run: run)
                            }
                            .accessibilityIdentifier("workflow-run-\(run.id)")
                        }

                        if pagination.hasMore {
                            ProgressView()
                                .frame(maxWidth: .infinity)
                                .listRowBackground(Color.clear)
                                .accessibilityIdentifier("load-more-indicator")
                                .task {
                                    await loadMoreRuns()
                                }
                        }
                    }
                }
            }
            .listStyle(.insetGrouped)
            .refreshable {
                await reloadRuns().value
            }
        }
        .task {
            if !pagination.hasLoaded {
                reloadRuns()
            }
        }
        .onChange(of: statusFilter) {
            reloadRuns(clearItems: true)
        }
        .errorAlert(message: $pagination.errorMessage, isPresented: $pagination.showError)
    }

    @discardableResult
    private func reloadRuns(clearItems: Bool = false) -> Task<Void, Never> {
        guard let workflowService else { return Task {} }
        return pagination.reload(clearItems: clearItems) { [self] page, limit in
            try await workflowService.fetchRuns(
                owner: owner,
                repo: repo,
                status: statusFilter.apiStatus,
                workflowId: workflowId,
                page: page,
                limit: limit,
            )
        }
    }

    private func loadMoreRuns() async {
        guard let workflowService else { return }
        await pagination.loadMore { [self] page, limit in
            try await workflowService.fetchRuns(
                owner: owner,
                repo: repo,
                status: statusFilter.apiStatus,
                workflowId: workflowId,
                page: page,
                limit: limit,
            )
        }
    }
}
