import SwiftUI

struct AusgabenView: View {
    @State private var expenses: [Expense] = []
    @State private var isLoading = false
    @State private var errorMessage: String?
    @State private var showAdd = false

    private static let dateFormatter: DateFormatter = {
        let f = DateFormatter()
        f.locale = Locale(identifier: "de_DE")
        f.dateStyle = .medium
        return f
    }()

    private let parseFormatter: DateFormatter = {
        let f = DateFormatter()
        f.locale = Locale(identifier: "en_US_POSIX")
        f.dateFormat = "yyyy-MM-dd"
        return f
    }()

    var body: some View {
        content
            .navigationTitle("Ausgaben")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .topBarTrailing) {
                    Button { showAdd = true } label: { Image(systemName: "plus") }
                }
            }
            .sheet(isPresented: $showAdd) {
                AddExpenseSheet { Task { await load() } }
            }
            .task { await load() }
            .refreshable { await load() }
    }

    @ViewBuilder
    private var content: some View {
        if isLoading && expenses.isEmpty {
            ProgressView()
        } else if let errorMessage, expenses.isEmpty {
            ContentUnavailableView("Konnte Ausgaben nicht laden", systemImage: "wifi.slash", description: Text(errorMessage))
        } else if expenses.isEmpty {
            ContentUnavailableView("Noch keine Ausgaben", systemImage: "eurosign.circle", description: Text("Tippe oben rechts auf +, um eine Ausgabe hinzuzufügen."))
        } else {
            List {
                Section {
                    LabeledContent("Gesamt", value: totalLabel)
                        .font(.headline)
                }
                Section {
                    ForEach(expenses) { e in
                        ExpenseRow(expense: e, dateLabel: formatDate(e.datum))
                    }
                }
            }
        }
    }

    private var totalLabel: String {
        let total = expenses.reduce(0) { $0 + $1.betrag }
        return String(format: "%.2f €", total)
    }

    private func formatDate(_ s: String) -> String {
        if let d = parseFormatter.date(from: String(s.prefix(10))) {
            return Self.dateFormatter.string(from: d)
        }
        return s
    }

    private func load() async {
        isLoading = true
        errorMessage = nil
        defer { isLoading = false }
        do {
            expenses = try await APIClient.shared.get("/api/expenses")
        } catch {
            errorMessage = error.localizedDescription
        }
    }
}

private struct ExpenseRow: View {
    let expense: Expense
    let dateLabel: String

    var body: some View {
        HStack(spacing: 12) {
            Image(systemName: icon(for: expense.kategorie))
                .foregroundStyle(Color.accentColor)
                .frame(width: 28)
            VStack(alignment: .leading, spacing: 2) {
                Text(expense.kategorie).font(.subheadline.bold())
                HStack(spacing: 6) {
                    Text(dateLabel)
                    if let dog = expense.dogName {
                        Text("• \(dog)")
                    }
                }
                .font(.caption)
                .foregroundStyle(.secondary)
                if let n = expense.notiz, !n.isEmpty {
                    Text(n).font(.caption).foregroundStyle(.secondary).lineLimit(1)
                }
            }
            Spacer()
            Text(String(format: "%.2f €", expense.betrag))
                .font(.subheadline.monospacedDigit().bold())
        }
        .padding(.vertical, 4)
    }

    private func icon(for kategorie: String) -> String {
        switch kategorie.lowercased() {
        case "futter", "essen":        return "fork.knife"
        case "tierarzt":               return "stethoscope"
        case "versicherung":           return "shield.lefthalf.filled"
        case "spielzeug":              return "tennisball.fill"
        case "pflege", "fellpflege":   return "scissors"
        case "training", "hundeschule": return "graduationcap.fill"
        case "leckerli", "snacks":     return "carrot.fill"
        default:                       return "eurosign.circle"
        }
    }
}

private struct AddExpenseSheet: View {
    @Environment(\.dismiss) private var dismiss
    let onSaved: () -> Void

    @State private var kategorie = "Futter"
    @State private var betrag = ""
    @State private var date = Date()
    @State private var notiz = ""
    @State private var dogs: [Dog] = []
    @State private var dogId: Int?
    @State private var isSaving = false
    @State private var errorMessage: String?

    private let kategorien = ["Futter", "Tierarzt", "Versicherung", "Spielzeug", "Pflege", "Training", "Leckerli", "Sonstiges"]

    var body: some View {
        NavigationStack {
            Form {
                Section("Kategorie") {
                    Picker("Kategorie", selection: $kategorie) {
                        ForEach(kategorien, id: \.self) { Text($0) }
                    }
                }
                Section("Betrag") {
                    TextField("0,00", text: $betrag)
                        .keyboardType(.decimalPad)
                }
                Section("Datum") {
                    DatePicker("Datum", selection: $date, displayedComponents: .date)
                        .environment(\.locale, Locale(identifier: "de_DE"))
                }
                Section("Hund (optional)") {
                    Picker("Hund", selection: $dogId) {
                        Text("Ohne Hund").tag(Int?.none)
                        ForEach(dogs) { dog in
                            Text(dog.name).tag(Int?.some(dog.id))
                        }
                    }
                }
                Section("Notiz (optional)") {
                    TextField("Notiz", text: $notiz, axis: .vertical)
                        .lineLimit(2...4)
                }
                if let errorMessage {
                    Section { Text(errorMessage).font(.footnote).foregroundStyle(.red) }
                }
            }
            .navigationTitle("Neue Ausgabe")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("Abbrechen") { dismiss() }.disabled(isSaving)
                }
                ToolbarItem(placement: .confirmationAction) {
                    if isSaving { ProgressView() }
                    else { Button("Sichern") { Task { await save() } }.disabled(!canSave) }
                }
            }
            .task { await loadDogs() }
        }
    }

    private var canSave: Bool {
        Double(betrag.replacingOccurrences(of: ",", with: ".")) != nil
    }

    private func loadDogs() async {
        dogs = (try? await APIClient.shared.get("/api/dogs")) ?? []
    }

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

        guard let betragValue = Double(betrag.replacingOccurrences(of: ",", with: ".")) else {
            errorMessage = "Ungültiger Betrag."
            return
        }

        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        let body = ExpenseCreateBody(
            dogId: dogId,
            kategorie: kategorie,
            betrag: betragValue,
            datum: formatter.string(from: date),
            notiz: notiz.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ? nil : notiz
        )

        do {
            let _: Expense = try await APIClient.shared.post("/api/expenses", body: body)
            onSaved()
            dismiss()
        } catch {
            errorMessage = error.localizedDescription
        }
    }
}
