import SwiftUI

struct GoalEditorView: View {
    @Environment(\.dismiss) private var dismiss
    @State private var name = ""
    @State private var targetAmount = ""
    @State private var targetDate = Date()
    @State private var includeTargetDate = false
    @State private var didLoadGoal = false

    let account: Account?
    let goal: Goal?
    private let goalRepository = GoalRepository()

    init(account: Account?, goal: Goal? = nil) {
        self.account = account
        self.goal = goal
    }

    private var currencySymbol: String {
        if let account = account, let code = account.currency, !code.isEmpty {
            return CurrencyFormatter.symbol(for: code)
        }
        return AppSettings.getOrCreate(in: CoreDataStack.shared.viewContext).currencySymbol
    }

    private var currencyCode: String {
        if let account = account, let code = account.currency, !code.isEmpty {
            return code
        }
        return AppSettings.getOrCreate(in: CoreDataStack.shared.viewContext).currency
    }

    var body: some View {
        NavigationStack {
            Form {
                Section {
                    TextField("Goal name", text: $name)
                    HStack {
                        Text(currencySymbol)
                            .foregroundColor(.secondary)
                        TextField("Target amount", text: $targetAmount)
                            .keyboardType(.decimalPad)
                    }

                    Toggle("Add target date", isOn: $includeTargetDate)
                    if includeTargetDate {
                        DatePicker("Target date", selection: $targetDate, displayedComponents: .date)
                            .datePickerStyle(.graphical)
                    }
                } header: {
                    Text("Goal Details")
                }
            }
            .navigationTitle(goal == nil ? "New Goal" : "Edit Goal")
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button("Cancel") { dismiss() }
                }
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("Save") { saveGoal() }
                        .disabled(!isValid)
                }
            }
        }
        .presentationDetents([.medium, .large])
        .presentationDragIndicator(.visible)
        .onAppear {
            guard let goal, !didLoadGoal else { return }
            name = goal.name ?? ""
            if let amount = goal.targetAmount?.decimalValue {
                targetAmount = formatDecimalForInput(amount)
            }
            if let target = goal.targetDate {
                includeTargetDate = true
                targetDate = target
            }
            didLoadGoal = true
        }
    }

    private var isValid: Bool {
        !name.trimmingCharacters(in: .whitespaces).isEmpty && parseDecimal(targetAmount) != nil
    }

    private func saveGoal() {
        guard let value = parseDecimal(targetAmount) else { return }
        if let goal {
            goalRepository.updateGoal(
                goal,
                name: name,
                targetAmount: value,
                targetDate: includeTargetDate ? targetDate : nil,
                clearTargetDate: !includeTargetDate
            )
        } else {
            goalRepository.createGoal(
                name: name,
                targetAmount: value,
                targetDate: includeTargetDate ? targetDate : nil,
                account: account
            )
        }
        dismiss()
    }

    private func parseDecimal(_ value: String) -> Decimal? {
        let locale = CurrencyFormatter.locale(for: currencyCode)
        let stripped = value
            .replacingOccurrences(of: currencySymbol, with: "")
            .trimmingCharacters(in: .whitespaces)

        guard !stripped.isEmpty else { return nil }

        let decimalSep = locale.decimalSeparator ?? "."
        let groupingSep = locale.groupingSeparator ?? ""

        // Detect alternate decimal BEFORE removing separators
        let usesAlternateDecimal =
            (decimalSep == "," && stripped.contains(".") && !stripped.contains(",")) ||
            (decimalSep == "." && stripped.contains(",") && !stripped.contains("."))

        if usesAlternateDecimal {
            let normalized = stripped
                .replacingOccurrences(of: groupingSep, with: "")
                .replacingOccurrences(of: ",", with: ".")
            let formatter = NumberFormatter()
            formatter.numberStyle = .decimal
            formatter.locale = Locale(identifier: "en_US_POSIX")
            return formatter.number(from: normalized)?.decimalValue
        }

        let cleaned = stripped.replacingOccurrences(of: groupingSep, with: "")
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        formatter.locale = locale

        if let result = formatter.number(from: cleaned)?.decimalValue {
            return result
        }

        // Fallback for mixed locale input
        let normalized = cleaned
            .replacingOccurrences(of: decimalSep, with: ".")
            .replacingOccurrences(of: ",", with: ".")
        formatter.locale = Locale(identifier: "en_US_POSIX")
        return formatter.number(from: normalized)?.decimalValue
    }

    private func formatDecimalForInput(_ decimal: Decimal) -> String {
        let locale = CurrencyFormatter.locale(for: currencyCode)
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        formatter.locale = locale
        formatter.minimumFractionDigits = 0
        formatter.maximumFractionDigits = 2
        formatter.groupingSeparator = ""
        return formatter.string(from: decimal as NSDecimalNumber) ?? ""
    }
}

#Preview {
    GoalEditorView(account: nil)
}
