import Foundation
import UIKit

class ExportService {
    static let shared = ExportService()

    private init() {}

    // MARK: - Export Formats

    enum ExportFormat: String, CaseIterable, Identifiable {
        case csv = "CSV"
        case json = "JSON"

        var id: String { rawValue }

        var fileExtension: String {
            switch self {
            case .csv: return "csv"
            case .json: return "json"
            }
        }

        var mimeType: String {
            switch self {
            case .csv: return "text/csv"
            case .json: return "application/json"
            }
        }
    }

    // MARK: - Export Data

    func exportToCSV(
        sources: [InvestmentSource],
        categories: [Category]
    ) -> String {
        let currencyCode = AppSettings.getOrCreate(in: CoreDataStack.shared.viewContext).currency
        var csv = "Account,Category,Source,Date,Value (\(currencyCode)),Contribution (\(currencyCode)),Notes\n"

        for source in sources.sorted(by: { $0.name < $1.name }) {
            let accountName = source.account?.name ?? "Default"
            let categoryName = source.category?.name ?? "Uncategorized"

            for snapshot in source.snapshotsArray {
                let date = formatDate(snapshot.date)
                let value = formatDecimal(snapshot.decimalValue)
                let contribution = snapshot.contribution != nil
                    ? formatDecimal(snapshot.decimalContribution)
                    : ""
                let notes = escapeCSV(snapshot.notes ?? "")

                csv += "\(escapeCSV(accountName)),\(escapeCSV(categoryName)),\(escapeCSV(source.name)),\(date),\(value),\(contribution),\(notes)\n"
            }
        }

        return csv
    }

    func exportToJSON(
        sources: [InvestmentSource],
        categories: [Category]
    ) -> String {
        var exportData: [String: Any] = [:]
        exportData["exportDate"] = ISO8601DateFormatter().string(from: Date())
        exportData["version"] = 2
        exportData["currency"] = AppSettings.getOrCreate(in: CoreDataStack.shared.viewContext).currency

        let accounts = Dictionary(grouping: sources) { $0.account?.id.uuidString ?? "default" }
        var accountsArray: [[String: Any]] = []

        for (_, accountSources) in accounts {
            let account = accountSources.first?.account
            var accountDict: [String: Any] = [
                "name": account?.name ?? "Default",
                "currency": account?.currency ?? exportData["currency"] as? String ?? "EUR",
                "inputMode": account?.inputMode ?? InputMode.simple.rawValue,
                "notificationFrequency": account?.notificationFrequency ?? NotificationFrequency.monthly.rawValue,
                "customFrequencyMonths": account?.customFrequencyMonths ?? 1
            ]

            // Export categories for this account
            let categoriesById = Dictionary(uniqueKeysWithValues: categories.map { ($0.id, $0) })
            let sourcesByCategory = Dictionary(grouping: accountSources) { $0.category?.id ?? UUID() }
            var categoriesArray: [[String: Any]] = []

            for (categoryId, categorySources) in sourcesByCategory {
                let category = categoriesById[categoryId]
                var categoryDict: [String: Any] = [
                    "name": category?.name ?? "Uncategorized",
                    "color": category?.colorHex ?? "#3B82F6",
                    "icon": category?.icon ?? "chart.pie.fill"
                ]

                var sourcesArray: [[String: Any]] = []
                for source in categorySources {
                    var sourceDict: [String: Any] = [
                        "name": source.name,
                        "isActive": source.isActive,
                        "notificationFrequency": source.notificationFrequency
                    ]

                    var snapshotsArray: [[String: Any]] = []
                    for snapshot in source.snapshotsArray {
                        var snapshotDict: [String: Any] = [
                            "date": ISO8601DateFormatter().string(from: snapshot.date),
                            "value": NSDecimalNumber(decimal: snapshot.decimalValue).doubleValue
                        ]

                        if snapshot.contribution != nil {
                            snapshotDict["contribution"] = NSDecimalNumber(
                                decimal: snapshot.decimalContribution
                            ).doubleValue
                        }

                        if let notes = snapshot.notes, !notes.isEmpty {
                            snapshotDict["notes"] = notes
                        }

                        snapshotsArray.append(snapshotDict)
                    }

                    sourceDict["snapshots"] = snapshotsArray
                    sourcesArray.append(sourceDict)
                }

                categoryDict["sources"] = sourcesArray
                categoriesArray.append(categoryDict)
            }

            accountDict["categories"] = categoriesArray
            accountsArray.append(accountDict)
        }

        exportData["accounts"] = accountsArray

        // Add summary
        let totalValue = sources.reduce(Decimal.zero) { $0 + $1.latestValue }
        exportData["summary"] = [
            "totalSources": sources.count,
            "totalCategories": categories.count,
            "totalValue": NSDecimalNumber(decimal: totalValue).doubleValue,
            "totalSnapshots": sources.reduce(0) { $0 + $1.snapshotCount }
        ]

        // Convert to JSON
        do {
            let jsonData = try JSONSerialization.data(
                withJSONObject: exportData,
                options: [.prettyPrinted, .sortedKeys]
            )
            return String(data: jsonData, encoding: .utf8) ?? "{}"
        } catch {
            print("JSON export error: \(error)")
            return "{}"
        }
    }

    // MARK: - Share

    func share(
        format: ExportFormat,
        sources: [InvestmentSource],
        categories: [Category],
        from viewController: UIViewController
    ) {
        let content: String
        let fileName: String

        switch format {
        case .csv:
            content = exportToCSV(sources: sources, categories: categories)
            fileName = "investment_tracker_export.csv"
        case .json:
            content = exportToJSON(sources: sources, categories: categories)
            fileName = "investment_tracker_export.json"
        }

        // Create temporary file
        let tempURL = FileManager.default.temporaryDirectory
            .appendingPathComponent(fileName)

        do {
            try content.write(to: tempURL, atomically: true, encoding: .utf8)

            let activityVC = UIActivityViewController(
                activityItems: [tempURL],
                applicationActivities: nil
            )

            // iPad support
            if let popover = activityVC.popoverPresentationController {
                popover.sourceView = viewController.view
                popover.sourceRect = CGRect(
                    x: viewController.view.bounds.midX,
                    y: viewController.view.bounds.midY,
                    width: 0,
                    height: 0
                )
            }

            viewController.present(activityVC, animated: true) {
                FirebaseService.shared.logExportAttempt(
                    format: format.rawValue,
                    success: true
                )
            }
        } catch {
            print("Export error: \(error)")
            FirebaseService.shared.logExportAttempt(
                format: format.rawValue,
                success: false
            )
        }
    }

    // MARK: - Helpers

    private func formatDate(_ date: Date) -> String {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        return formatter.string(from: date)
    }

    private func formatDecimal(_ decimal: Decimal) -> String {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        formatter.minimumFractionDigits = 2
        formatter.maximumFractionDigits = 2
        formatter.decimalSeparator = "."
        formatter.groupingSeparator = ""
        return formatter.string(from: decimal as NSDecimalNumber) ?? "0.00"
    }

    private func escapeCSV(_ value: String) -> String {
        var escaped = value
        if escaped.contains("\"") || escaped.contains(",") || escaped.contains("\n") {
            escaped = escaped.replacingOccurrences(of: "\"", with: "\"\"")
            escaped = "\"\(escaped)\""
        }
        return escaped
    }
}

// MARK: - Import Service (Future)

extension ExportService {
    func importFromCSV(_ content: String) -> (sources: [ImportedSource], errors: [String]) {
        // Future implementation for importing data
        return ([], ["Import not yet implemented"])
    }

    struct ImportedSource {
        let name: String
        let categoryName: String
        let snapshots: [(date: Date, value: Decimal, contribution: Decimal?, notes: String?)]
    }
}
