import Foundation
import SwiftUI

/// Shown after a successful `/api/scan` call. Lets the user review/correct
/// the AI-extracted fields before persisting the receipt via
/// `ReceiptsAPI.sync(...)`. Edits are kept in a local `@State` copy so a
/// failed save never loses what the user typed.
struct ReceiptReviewView: View {
    @State private var receipt: Receipt

    @State private var isSaving = false
    @State private var saveErrorMessage: String?

    @Environment(\.dismiss) private var dismiss

    init(receipt: Receipt) {
        _receipt = State(initialValue: receipt)
    }

    var body: some View {
        ZStack {
            Color.zenithBg.ignoresSafeArea()

            ScrollView {
                VStack(alignment: .leading, spacing: ZenithSpacing.md) {
                    ZenithStatusBadge(receipt)

                    // MARK: Belegdaten (Händler / Datum / Betrag)
                    VStack(alignment: .leading, spacing: ZenithSpacing.sm) {
                        HStack(alignment: .bottom, spacing: ZenithSpacing.xs) {
                            ZenithTextField(label: "Händlername", text: $receipt.merchant.name)
                            confidenceIndicator(receipt.merchant.confidence)
                        }

                        ZenithDivider()

                        HStack(alignment: .bottom, spacing: ZenithSpacing.xs) {
                            LabeledFieldShell(label: "Datum") {
                                DatePicker("", selection: dateBinding, displayedComponents: [.date])
                                    .labelsHidden()
                                    .datePickerStyle(.compact)
                                    .tint(.zenithBlack)
                            }
                            confidenceIndicator(receipt.date.confidence)
                        }

                        ZenithDivider()

                        HStack(alignment: .bottom, spacing: ZenithSpacing.xs) {
                            ZenithAmountField(label: "Betrag", value: totalAmountBinding)
                            Text(receipt.currency)
                                .zenithLabelMdStyle(color: .zenithMuted)
                                .padding(.bottom, ZenithSpacing.unit * 2)
                            confidenceIndicator(receipt.totalAmount.confidence)
                        }
                    }
                    .zenithCard()

                    // MARK: Kategorie / Zahlungsart
                    VStack(alignment: .leading, spacing: ZenithSpacing.sm) {
                        LabeledFieldShell(label: "Kategorie") {
                            Menu {
                                ForEach(Receipt.ReceiptCategory.allCases, id: \.self) { category in
                                    Button(category.rawValue) { receipt.suggestedCategory = category }
                                }
                            } label: {
                                menuLabel(receipt.suggestedCategory.rawValue)
                            }
                        }

                        ZenithDivider()

                        LabeledFieldShell(label: "Zahlungsart") {
                            Menu {
                                Button("Keine Angabe") { receipt.paymentMethod = nil }
                                ForEach(Receipt.PaymentMethod.allCases, id: \.self) { method in
                                    Button(method.rawValue) { receipt.paymentMethod = method }
                                }
                            } label: {
                                menuLabel(receipt.paymentMethod?.rawValue ?? "Keine Angabe")
                            }
                        }
                    }
                    .zenithCard()

                    // MARK: Positionen
                    VStack(alignment: .leading, spacing: ZenithSpacing.sm) {
                        Text("Positionen").zenithLabelCapsStyle()

                        ForEach(receipt.lineItems.indices, id: \.self) { index in
                            if index > 0 { ZenithDivider() }
                            HStack(spacing: ZenithSpacing.xs) {
                                TextField("Beschreibung", text: $receipt.lineItems[index].description)
                                    .font(.zenithBodyMd)
                                    .foregroundStyle(.zenithText)
                                Spacer(minLength: ZenithSpacing.unit)
                                TextField("Preis", value: $receipt.lineItems[index].price, format: .number)
                                    .keyboardType(.decimalPad)
                                    .multilineTextAlignment(.trailing)
                                    .frame(width: 72)
                                    .zenithLabelMdStyle()
                                Button {
                                    receipt.lineItems.remove(at: index)
                                } label: {
                                    Image(systemName: "xmark.circle")
                                        .foregroundStyle(.zenithSubtle)
                                }
                            }
                            .padding(.vertical, ZenithSpacing.unit)
                        }

                        Button {
                            receipt.lineItems.append(Receipt.LineItem(description: "", quantity: 1, price: 0))
                        } label: {
                            Label("Position hinzufügen", systemImage: "plus")
                        }
                        .buttonStyle(.zenithPlain)
                        .padding(.top, ZenithSpacing.unit)
                    }
                    .zenithCard()

                    // MARK: Save

                    Button {
                        Task { await save() }
                    } label: {
                        if isSaving {
                            ProgressView()
                                .tint(.white)
                        } else {
                            Text("Speichern")
                        }
                    }
                    .buttonStyle(.zenithPrimary)
                    .disabled(isSaving)

                    if let saveErrorMessage {
                        Text(saveErrorMessage)
                            .zenithBodySmStyle(color: .zenithError)
                    }
                }
                .padding(ZenithSpacing.sm)
            }
        }
        .navigationTitle("Beleg prüfen")
        .navigationBarTitleDisplayMode(.inline)
    }

    // MARK: - Confidence indicator

    /// Small colored dot + percentage, shown only for fields the backend
    /// flagged as low-confidence (< 70%) — mirrors what the web dashboard
    /// highlights for manual review.
    @ViewBuilder
    private func confidenceIndicator(_ confidence: Double) -> some View {
        if confidence < 0.7 {
            HStack(spacing: 4) {
                Circle()
                    .fill(Color.zenithPendingDot)
                    .frame(width: 8, height: 8)
                Text("\(Int((confidence * 100).rounded()))%")
                    .zenithLabelMdStyle(color: .zenithPendingText)
            }
            .padding(.bottom, ZenithSpacing.unit * 2)
        }
    }

    /// Text + chevron shown as a `Menu`'s label, styled to match
    /// `ZenithTextField`'s body text instead of the system default.
    private func menuLabel(_ text: String) -> some View {
        HStack {
            Text(text).zenithBodyStyle()
            Spacer()
            Image(systemName: "chevron.up.chevron.down")
                .font(.system(size: 11, weight: .medium))
                .foregroundStyle(.zenithSubtle)
        }
    }

    // MARK: - Date <-> String("yyyy-MM-dd") binding

    private static let isoDateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.calendar = Calendar(identifier: .gregorian)
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.timeZone = TimeZone(identifier: "UTC")
        formatter.dateFormat = "yyyy-MM-dd"
        return formatter
    }()

    private var dateBinding: Binding<Date> {
        Binding<Date>(
            get: { Self.isoDateFormatter.date(from: receipt.date.isoDate) ?? Date() },
            set: { newValue in receipt.date.isoDate = Self.isoDateFormatter.string(from: newValue) }
        )
    }

    // MARK: - Total amount Double <-> Double? binding (for ZenithAmountField)

    private var totalAmountBinding: Binding<Double?> {
        Binding<Double?>(
            get: { receipt.totalAmount.value },
            set: { newValue in
                if let newValue { receipt.totalAmount.value = newValue }
            }
        )
    }

    // MARK: - Save

    private func save() async {
        isSaving = true
        saveErrorMessage = nil
        defer { isSaving = false }

        do {
            try await ReceiptsAPI.sync([receipt])
            dismiss()
        } catch let error as APIError {
            saveErrorMessage = error.localizedDescription
        } catch {
            saveErrorMessage = error.localizedDescription
        }
    }
}

/// Local layout helper: reproduces `ZenithTextField`'s "label-caps text
/// above a hairline-bottom-border field" shell for non-`TextField` controls
/// (`DatePicker`, the category/payment `Menu`s) so they read as part of the
/// same field system instead of falling back to stock iOS control chrome.
private struct LabeledFieldShell<Content: View>: View {
    let label: String
    let content: Content

    init(label: String, @ViewBuilder content: () -> Content) {
        self.label = label
        self.content = content()
    }

    var body: some View {
        VStack(alignment: .leading, spacing: ZenithSpacing.unit) {
            Text(label).zenithLabelCapsStyle()

            content
                .padding(.vertical, ZenithSpacing.unit * 2)
                .overlay(alignment: .bottom) {
                    Rectangle()
                        .fill(Color.zenithBorder)
                        .frame(height: 1)
                }
        }
    }
}
