//
//  ExportView.swift
//  Reflect
//
//  Export mood data to CSV or PDF formats.
//

import SwiftUI

struct ExportView: View {

    @Environment(\.dismiss) private var dismiss
    @AppStorage(UserDefaultsStore.Keys.theme.rawValue, store: GroupUserDefaults.groupDefaults) private var theme: Theme = .system

    private var textColor: Color { theme.currentTheme.labelColor }

    @State private var selectedFormat: ExportFormat = .csv
    @State private var selectedRange: DateRange = .allTime
    @State private var isExporting = false
    @State private var exportedURL: URL?
    @State private var showShareSheet = false
    @State private var showError = false
    @State private var errorMessage = ""

    private let entries: [MoodEntryModel]

    enum ExportFormat: String, CaseIterable {
        case csv = "CSV"
        case pdf = "PDF"

        var icon: String {
            switch self {
            case .csv: return "tablecells"
            case .pdf: return "doc.richtext"
            }
        }

        var description: String {
            switch self {
            case .csv: return "Spreadsheet format for data analysis"
            case .pdf: return "Formatted report with insights"
            }
        }
    }

    enum DateRange: String, CaseIterable {
        case lastWeek = "Last 7 Days"
        case lastMonth = "Last 30 Days"
        case last3Months = "Last 3 Months"
        case lastYear = "Last Year"
        case allTime = "All Time"

        var days: Int? {
            switch self {
            case .lastWeek: return 7
            case .lastMonth: return 30
            case .last3Months: return 90
            case .lastYear: return 365
            case .allTime: return nil
            }
        }
    }

    init(entries: [MoodEntryModel]) {
        self.entries = entries
    }

    private var filteredEntries: [MoodEntryModel] {
        guard let days = selectedRange.days else {
            return entries
        }

        let cutoffDate = Calendar.current.date(byAdding: .day, value: -days, to: Date()) ?? Date()
        return entries.filter { $0.forDate >= cutoffDate }
    }

    private var validEntries: [MoodEntryModel] {
        filteredEntries.filter { ![.missing, .placeholder].contains($0.mood) }
    }

    var body: some View {
        NavigationStack {
            ScrollView {
                VStack(spacing: 24) {
                    // Preview stats
                    statsCard

                    // Format selection
                    formatSelection

                    // Date range selection
                    dateRangeSelection

                    // Export button
                    exportButton
                }
                .padding()
            }
            .background(Color(.systemGroupedBackground))
            .navigationTitle("Export Data")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("Cancel") {
                        dismiss()
                    }
                }
            }
            .sheet(isPresented: $showShareSheet) {
                if let url = exportedURL {
                    ExportShareSheet(items: [url])
                }
            }
            .alert("Export Failed", isPresented: $showError) {
                Button("OK", role: .cancel) { }
            } message: {
                Text(errorMessage)
            }
        }
    }

    private var statsCard: some View {
        VStack(spacing: 16) {
            HStack {
                Image(systemName: "chart.bar.doc.horizontal")
                    .font(.title2)
                    .foregroundColor(.accentColor)

                Text("Export Preview")
                    .font(.headline)
                    .foregroundColor(textColor)

                Spacer()
            }

            Divider()

            HStack(spacing: 32) {
                VStack(spacing: 4) {
                    Text("\(validEntries.count)")
                        .font(.title)
                        .fontWeight(.bold)
                        .foregroundColor(textColor)

                    Text("Entries")
                        .font(.caption)
                        .foregroundStyle(.secondary)
                }

                VStack(spacing: 4) {
                    Text(dateRangeText)
                        .font(.title3)
                        .fontWeight(.semibold)
                        .foregroundColor(textColor)

                    Text("Date Range")
                        .font(.caption)
                        .foregroundStyle(.secondary)
                }

                Spacer()
            }
        }
        .padding()
        .background(
            RoundedRectangle(cornerRadius: 16)
                .fill(Color(.systemBackground))
        )
    }

    private var dateRangeText: String {
        guard !validEntries.isEmpty else { return "No data" }

        let sorted = validEntries.sorted { $0.forDate < $1.forDate }
        guard let first = sorted.first, let last = sorted.last else { return "No data" }

        let formatter = DateFormatter()
        formatter.dateFormat = "MMM d"

        if Calendar.current.isDate(first.forDate, equalTo: last.forDate, toGranularity: .day) {
            return formatter.string(from: first.forDate)
        }

        return "\(formatter.string(from: first.forDate)) - \(formatter.string(from: last.forDate))"
    }

    private var formatSelection: some View {
        VStack(alignment: .leading, spacing: 12) {
            Text("Format")
                .font(.headline)
                .foregroundColor(textColor)

            ForEach(ExportFormat.allCases, id: \.self) { format in
                Button {
                    selectedFormat = format
                } label: {
                    HStack(spacing: 16) {
                        Image(systemName: format.icon)
                            .font(.title2)
                            .frame(width: 44, height: 44)
                            .background(selectedFormat == format ? Color.accentColor.opacity(0.15) : Color(.systemGray5))
                            .foregroundColor(selectedFormat == format ? .accentColor : .gray)
                            .clipShape(Circle())

                        VStack(alignment: .leading, spacing: 2) {
                            Text(format.rawValue)
                                .font(.headline)
                                .foregroundColor(textColor)

                            Text(format.description)
                                .font(.subheadline)
                                .foregroundStyle(.secondary)
                        }

                        Spacer()

                        if selectedFormat == format {
                            Image(systemName: "checkmark.circle.fill")
                                .foregroundColor(.accentColor)
                        }
                    }
                    .padding()
                    .background(
                        RoundedRectangle(cornerRadius: 14)
                            .fill(Color(.systemBackground))
                            .overlay(
                                RoundedRectangle(cornerRadius: 14)
                                    .stroke(selectedFormat == format ? Color.accentColor : Color.clear, lineWidth: 2)
                            )
                    )
                }
                .buttonStyle(.plain)
            }
        }
    }

    private var dateRangeSelection: some View {
        VStack(alignment: .leading, spacing: 12) {
            Text("Date Range")
                .font(.headline)
                .foregroundColor(textColor)

            VStack(spacing: 0) {
                ForEach(DateRange.allCases, id: \.self) { range in
                    Button {
                        selectedRange = range
                    } label: {
                        HStack {
                            Text(range.rawValue)
                                .foregroundColor(textColor)

                            Spacer()

                            if selectedRange == range {
                                Image(systemName: "checkmark")
                                    .foregroundColor(.accentColor)
                            }
                        }
                        .padding()
                        .background(Color(.systemBackground))
                    }
                    .buttonStyle(.plain)

                    if range != DateRange.allCases.last {
                        Divider()
                            .padding(.leading)
                    }
                }
            }
            .clipShape(RoundedRectangle(cornerRadius: 14))
        }
    }

    private var exportButton: some View {
        Button {
            performExport()
        } label: {
            HStack(spacing: 8) {
                if isExporting {
                    ProgressView()
                        .tint(.white)
                } else {
                    Image(systemName: "square.and.arrow.up")
                }

                Text(isExporting ? "Exporting..." : "Export \(selectedFormat.rawValue)")
                    .fontWeight(.semibold)
            }
            .frame(maxWidth: .infinity)
            .padding()
            .background(validEntries.isEmpty ? Color.gray : Color.accentColor)
            .foregroundColor(.white)
            .clipShape(RoundedRectangle(cornerRadius: 14))
        }
        .disabled(isExporting || validEntries.isEmpty)
        .padding(.top, 8)
    }

    private func performExport() {
        isExporting = true

        Task {
            let url: URL?

            switch selectedFormat {
            case .csv:
                url = ExportService.shared.exportCSV(entries: validEntries)
            case .pdf:
                url = ExportService.shared.exportPDF(entries: validEntries, title: "Reflect Mood Report")
            }

            await MainActor.run {
                isExporting = false

                if let url = url {
                    exportedURL = url
                    showShareSheet = true
                } else {
                    errorMessage = "Failed to create export file. Please try again."
                    showError = true
                }
            }
        }
    }
}

// MARK: - Export Share Sheet

struct ExportShareSheet: UIViewControllerRepresentable {
    let items: [Any]

    func makeUIViewController(context: Context) -> UIActivityViewController {
        UIActivityViewController(activityItems: items, applicationActivities: nil)
    }

    func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {}
}
