import SwiftUI
import Charts

struct AnalyticsView: View {
    @EnvironmentObject var linkViewModel: LinkViewModel
    @State private var selectedTimeRange: TimeRange = .oneMonth
    @State private var selectedMetric: Metric = .clicks
    @State private var showingExport = false

    enum TimeRange: String, CaseIterable {
        case oneWeek = "1w"
        case oneMonth = "1m"
        case threeMonths = "3m"
        case sixMonths = "6m"
        case oneYear = "1y"
        case allTime = "all"

        var displayName: String {
            switch self {
            case .oneWeek:
                return NSLocalizedString("1_week", comment: "1 week")
            case .oneMonth:
                return NSLocalizedString("1_month", comment: "1 month")
            case .threeMonths:
                return NSLocalizedString("3_months", comment: "3 months")
            case .sixMonths:
                return NSLocalizedString("6_months", comment: "6 months")
            case .oneYear:
                return NSLocalizedString("1_year", comment: "1 year")
            case .allTime:
                return NSLocalizedString("all_time", comment: "All time")
            }
        }

        var dateRange: DateInterval? {
            let calendar = Calendar.current
            let endDate = Date()

            switch self {
            case .oneWeek:
                let startDate = calendar.date(byAdding: .weekOfYear, value: -1, to: endDate)!
                return DateInterval(start: startDate, end: endDate)
            case .oneMonth:
                let startDate = calendar.date(byAdding: .month, value: -1, to: endDate)!
                return DateInterval(start: startDate, end: endDate)
            case .threeMonths:
                let startDate = calendar.date(byAdding: .month, value: -3, to: endDate)!
                return DateInterval(start: startDate, end: endDate)
            case .sixMonths:
                let startDate = calendar.date(byAdding: .month, value: -6, to: endDate)!
                return DateInterval(start: startDate, end: endDate)
            case .oneYear:
                let startDate = calendar.date(byAdding: .year, value: -1, to: endDate)!
                return DateInterval(start: startDate, end: endDate)
            case .allTime:
                return nil
            }
        }
    }

    enum Metric: String, CaseIterable {
        case clicks = "clicks"
        case links = "links"
        case topLinks = "top_links"

        var displayName: String {
            switch self {
            case .clicks:
                return NSLocalizedString("clicks_over_time", comment: "Clicks over time")
            case .links:
                return NSLocalizedString("links_created", comment: "Links created")
            case .topLinks:
                return NSLocalizedString("top_links", comment: "Top links")
            }
        }
    }

    var analyticsData: AnalyticsData {
        return AnalyticsCalculator.calculateAnalytics(
            for: linkViewModel.links,
            timeRange: selectedTimeRange,
            metric: selectedMetric
        )
    }

    var body: some View {
        NavigationView {
            ScrollView {
                VStack(alignment: .leading, spacing: 20) {
                    timeRangePicker
                    overviewCards
                    metricSelector
                    mainChart
                    topLinksSection
                    linkTypeDistributionSection
                    recentActivitySection
                }
                .padding()
            }
            .navigationTitle("analytics")
            .navigationBarTitleDisplayMode(.large)
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    analyticsToolbar
                }
            }
        }
        .sheet(isPresented: $showingExport) {
            ExportView(analyticsData: analyticsData)
        }
    }

    private var timeRangePicker: some View {
        VStack(alignment: .leading) {
            Text("time_range")
                .font(.headline)

            Picker("time_range", selection: $selectedTimeRange) {
                ForEach(TimeRange.allCases, id: \.self) { range in
                    Text(range.displayName).tag(range)
                }
            }
            .pickerStyle(SegmentedPickerStyle())
        }
    }

    private var overviewCards: some View {
        LazyVGrid(columns: [
            GridItem(.flexible()),
            GridItem(.flexible())
        ], spacing: 16) {
            OverviewCard(
                title: "total_links",
                value: "\(analyticsData.totalLinks)",
                change: analyticsData.linksChange,
                icon: "link"
            )

            OverviewCard(
                title: "total_clicks",
                value: "\(analyticsData.totalClicks)",
                change: analyticsData.clicksChange,
                icon: "hand.tap"
            )

            OverviewCard(
                title: "avg_clicks_per_link",
                value: String(format: "%.1f", analyticsData.averageClicksPerLink),
                change: analyticsData.avgClicksChange,
                icon: "chart.bar"
            )

            OverviewCard(
                title: "active_links",
                value: "\(analyticsData.activeLinks)",
                change: analyticsData.activeLinksChange,
                icon: "bolt"
            )
        }
    }

    private var metricSelector: some View {
        VStack(alignment: .leading) {
            Text("metric")
                .font(.headline)

            Picker("metric", selection: $selectedMetric) {
                ForEach(Metric.allCases, id: \.self) { metric in
                    Text(metric.displayName).tag(metric)
                }
            }
            .pickerStyle(SegmentedPickerStyle())
        }
    }

    private var mainChart: some View {
        VStack(alignment: .leading) {
            Text(selectedMetric.displayName)
                .font(.headline)

            if analyticsData.chartData.isEmpty {
                Text("no_data_available")
                    .font(.body)
                    .foregroundColor(.secondary)
                    .frame(height: 200)
                    .frame(maxWidth: .infinity)
                    .background(Color(.systemGray6))
                    .cornerRadius(12)
            } else {
                Chart(analyticsData.chartData) { dataPoint in
                    switch selectedMetric {
                    case .clicks:
                        LineMark(
                            x: .value("Date", dataPoint.date),
                            y: .value("Clicks", dataPoint.count)
                        )
                        .foregroundStyle(.blue)
                    case .links:
                        BarMark(
                            x: .value("Date", dataPoint.date),
                            y: .value("Links", dataPoint.count)
                        )
                        .foregroundStyle(.green)
                    case .topLinks:
                        BarMark(
                            x: .value("Link", dataPoint.label),
                            y: .value("Clicks", dataPoint.count)
                        )
                        .foregroundStyle(.orange)
                    }
                }
                .frame(height: 200)
                .chartXAxisLabel(selectedMetric == .topLinks ? "Links" : "Date")
                .chartYAxisLabel(selectedMetric == .links ? "Links Created" : "Clicks")
            }
        }
    }

    private var topLinksSection: some View {
        VStack(alignment: .leading) {
            Text("top_performing_links")
                .font(.headline)

            ForEach(analyticsData.topLinks, id: \.link.id) { linkData in
                TopLinkRow(linkData: linkData)
            }
        }
    }

    private var linkTypeDistributionSection: some View {
        VStack(alignment: .leading) {
            Text("link_type_distribution")
                .font(.headline)

            if !analyticsData.linkTypeDistribution.isEmpty {
                Chart(analyticsData.linkTypeDistribution, id: \.type) { data in
                    SectorMark(
                        angle: .value("Count", data.count),
                        innerRadius: .ratio(0.5),
                        angularInset: 2
                    )
                    .foregroundStyle(linkTypeColor(data.type))
                }
                .frame(height: 200)
            }

            LazyVGrid(columns: [
                GridItem(.flexible()),
                GridItem(.flexible()),
                GridItem(.flexible())
            ], spacing: 12) {
                ForEach(analyticsData.linkTypeDistribution, id: \.type) { data in
                    VStack {
                        Text(data.type.displayName)
                            .font(.caption)
                            .foregroundColor(.secondary)
                        Text("\(data.count)")
                            .font(.headline)
                            .foregroundColor(linkTypeColor(data.type))
                    }
                    .frame(maxWidth: .infinity)
                    .padding()
                    .background(Color(.systemGray6))
                    .cornerRadius(8)
                }
            }
        }
    }

    private var recentActivitySection: some View {
        VStack(alignment: .leading) {
            Text("recent_activity")
                .font(.headline)

            ForEach(analyticsData.recentActivity.prefix(10), id: \.id) { activity in
                RecentActivityRow(activity: activity)
            }
        }
    }

    private var analyticsToolbar: some View {
        Menu {
            Button("export_data") {
                showingExport = true
            }

            Button("refresh_data") {
                linkViewModel.fetchLinks()
            }
        } label: {
            Image(systemName: "ellipsis.circle")
        }
    }

    private func linkTypeColor(_ linkType: LinkType) -> Color {
        switch linkType {
        case .link:
            return .blue
        case .custom:
            return .green
        case .template:
            return .orange
        }
    }
}

struct OverviewCard: View {
    let title: String
    let value: String
    let change: Double?
    let icon: String

    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            HStack {
                Image(systemName: icon)
                    .foregroundColor(.blue)
                Text(title)
                    .font(.caption)
                    .foregroundColor(.secondary)
                Spacer()
            }

            Text(value)
                .font(.title2)
                .fontWeight(.semibold)

            if let change = change {
                HStack {
                    Image(systemName: change >= 0 ? "arrow.up.right" : "arrow.down.right")
                        .font(.caption2)
                    Text(String(format: "%.1f%%", abs(change)))
                        .font(.caption2)
                }
                .foregroundColor(change >= 0 ? .green : .red)
            }
        }
        .padding()
        .frame(maxWidth: .infinity, alignment: .leading)
        .background(Color(.systemGray6))
        .cornerRadius(12)
    }
}

struct TopLinkRow: View {
    let linkData: TopLinkData

    var body: some View {
        HStack {
            VStack(alignment: .leading) {
                Text(linkData.link.alias)
                    .font(.body)
                    .fontWeight(.medium)

                if let url = linkData.link.originalURL {
                    Text(url)
                        .font(.caption)
                        .foregroundColor(.secondary)
                        .lineLimit(1)
                }
            }

            Spacer()

            VStack(alignment: .trailing) {
                Text("\(linkData.clicks)")
                    .font(.headline)
                    .foregroundColor(.blue)

                Text("clicks")
                    .font(.caption)
                    .foregroundColor(.secondary)
            }
        }
        .padding()
        .background(Color(.systemGray6))
        .cornerRadius(8)
    }
}

struct RecentActivityRow: View {
    let activity: RecentActivity

    var body: some View {
        HStack {
            Image(systemName: activity.type.icon)
                .foregroundColor(activity.type.color)
                .frame(width: 24)

            VStack(alignment: .leading) {
                Text(activity.description)
                    .font(.body)
                Text(activity.timestamp, format: .relative(presentation: .named))
                    .font(.caption)
                    .foregroundColor(.secondary)
            }

            Spacer()
        }
        .padding(.vertical, 4)
    }
}

struct ExportView: View {
    let analyticsData: AnalyticsData
    @Environment(\.presentationMode) var presentationMode
    @State private var exportFormat: ExportFormat = .json
    @State private var includeChartData = true
    @State private var includeTopLinks = true
    @State private var isExporting = false

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

        var displayName: String {
            return rawValue
        }
    }

    var body: some View {
        NavigationView {
            Form {
                Section("export_options") {
                    Picker("format", selection: $exportFormat) {
                        ForEach(ExportFormat.allCases, id: \.self) { format in
                            Text(format.displayName).tag(format)
                        }
                    }

                    Toggle("include_chart_data", isOn: $includeChartData)
                    Toggle("include_top_links", isOn: $includeTopLinks)
                }

                Section("preview") {
                    Text("total_links: \(analyticsData.totalLinks)")
                    Text("total_clicks: \(analyticsData.totalClicks)")
                    Text("chart_data_points: \(analyticsData.chartData.count)")
                    Text("top_links: \(analyticsData.topLinks.count)")
                }
            }
            .navigationTitle("export_analytics")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button("cancel") {
                        presentationMode.wrappedValue.dismiss()
                    }
                }

                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("export") {
                        exportData()
                    }
                    .disabled(isExporting)
                }
            }
        }
    }

    private func exportData() {
        isExporting = true

        // Implementation would depend on the specific export requirements
        // For now, we'll just simulate the export
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            isExporting = false
            presentationMode.wrappedValue.dismiss()
        }
    }
}

#Preview {
    AnalyticsView()
        .environmentObject(LinkViewModel())
}
