import SwiftUI
import Charts

struct PeriodComparisonChartView: View {
    @ObservedObject var viewModel: ChartsViewModel

    var body: some View {
        VStack(alignment: .leading, spacing: 16) {
            Text("Period vs Period")
                .font(.headline)

            periodPickersSection
            chartContent
        }
        .padding()
        .background(Color(.systemBackground))
        .cornerRadius(AppConstants.UI.cornerRadius)
        .shadow(color: .black.opacity(0.05), radius: 8, y: 2)
    }

    // MARK: - Period Pickers

    private var periodPickersSection: some View {
        VStack(spacing: 10) {
            periodRow(
                label: "Period A",
                color: Color(hex: "#3478F6") ?? .blue,
                start: $viewModel.periodAStart,
                end: $viewModel.periodAEnd
            )
            periodRow(
                label: "Period B",
                color: Color(hex: "#FF9500") ?? .orange,
                start: $viewModel.periodBStart,
                end: $viewModel.periodBEnd
            )
        }
        .padding(12)
        .background(Color(.systemGray6))
        .cornerRadius(10)
    }

    private func periodRow(
        label: String,
        color: Color,
        start: Binding<Date>,
        end: Binding<Date>
    ) -> some View {
        HStack(spacing: 8) {
            Circle()
                .fill(color)
                .frame(width: 8, height: 8)
            Text(label)
                .font(.caption.weight(.semibold))
                .foregroundColor(color)
                .frame(width: 58, alignment: .leading)

            DatePicker(
                "",
                selection: Binding<Date>(
                    get: { firstOfMonth(start.wrappedValue) },
                    set: { start.wrappedValue = firstOfMonth($0) }
                ),
                displayedComponents: [.date]
            )
            .datePickerStyle(.compact)
            .labelsHidden()
            .frame(maxWidth: .infinity)

            Text("–")
                .font(.caption)
                .foregroundColor(.secondary)

            DatePicker(
                "",
                selection: Binding<Date>(
                    get: { firstOfMonth(end.wrappedValue) },
                    set: { end.wrappedValue = firstOfMonth($0) }
                ),
                displayedComponents: [.date]
            )
            .datePickerStyle(.compact)
            .labelsHidden()
            .frame(maxWidth: .infinity)
        }
    }

    // MARK: - Chart Content

    @ViewBuilder
    private var chartContent: some View {
        if viewModel.periodComparisonData.isEmpty {
            emptyView
        } else {
            VStack(spacing: 12) {
                periodChart
                legend
            }
        }
    }

    private var emptyView: some View {
        VStack(spacing: 12) {
            Image(systemName: "calendar.badge.clock")
                .font(.system(size: 36))
                .foregroundColor(.secondary)
            Text("No data available for the selected periods.")
                .font(.subheadline)
                .foregroundColor(.secondary)
                .multilineTextAlignment(.center)
        }
        .frame(maxWidth: .infinity)
        .frame(height: 260)
    }

    // MARK: - Flat data for Chart

    private struct PeriodPoint: Identifiable {
        let id: String
        let seriesId: String
        let seriesLabel: String
        let colorHex: String
        let monthOffset: Int
        let returnPct: Double
    }

    private var flatPoints: [PeriodPoint] {
        var result: [PeriodPoint] = []
        for series in viewModel.periodComparisonData {
            for point in series.points {
                result.append(PeriodPoint(
                    id: "\(series.id)-\(point.monthOffset)",
                    seriesId: series.id,
                    seriesLabel: series.label,
                    colorHex: series.colorHex,
                    monthOffset: point.monthOffset,
                    returnPct: point.returnPct
                ))
            }
        }
        return result
    }

    private var periodChart: some View {
        let points = flatPoints
        let seriesIds = viewModel.periodComparisonData.map { $0.id }
        let seriesColors: [Color] = viewModel.periodComparisonData.map {
            Color(hex: $0.colorHex) ?? .gray
        }

        return Chart(points) { point in
            LineMark(
                x: .value("Month", point.monthOffset),
                y: .value("Return", point.returnPct),
                series: .value("Period", point.seriesLabel)
            )
            .interpolationMethod(.catmullRom)
            .foregroundStyle(by: .value("Period", point.seriesLabel))

            PointMark(
                x: .value("Month", point.monthOffset),
                y: .value("Return", point.returnPct)
            )
            .foregroundStyle(by: .value("Period", point.seriesLabel))
            .symbolSize(20)
        }
        .chartForegroundStyleScale(
            domain: viewModel.periodComparisonData.map { $0.label },
            range: seriesColors
        )
        .chartXAxis {
            AxisMarks(values: xAxisValues) { value in
                AxisGridLine(stroke: StrokeStyle(lineWidth: 0.5, dash: [3, 3]))
                    .foregroundStyle(Color.secondary.opacity(0.2))
                AxisValueLabel {
                    if let idx = value.as(Int.self) {
                        Text("M\(idx + 1)")
                            .font(.caption2)
                    }
                }
            }
        }
        .chartYAxis {
            AxisMarks(position: .leading) { value in
                AxisValueLabel {
                    if let d = value.as(Double.self) {
                        Text(String(format: "%.1f%%", d))
                            .font(.caption2)
                    }
                }
                AxisGridLine(stroke: StrokeStyle(lineWidth: 0.5, dash: [3, 3]))
                    .foregroundStyle(Color.secondary.opacity(0.15))
            }
        }
        .frame(height: 260)
        .drawingGroup()
        .onChange(of: seriesIds) { _, _ in }  // silence unused warning
    }

    private var legend: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            HStack(spacing: 16) {
                ForEach(viewModel.periodComparisonData) { series in
                    HStack(spacing: 6) {
                        RoundedRectangle(cornerRadius: 2)
                            .fill(Color(hex: series.colorHex) ?? .gray)
                            .frame(width: 20, height: 3)
                        Text(series.label)
                            .font(.caption)
                            .foregroundColor(.secondary)
                    }
                }
            }
        }
    }

    // MARK: - Helpers

    private var xAxisValues: [Int] {
        let maxOffset = viewModel.periodComparisonData
            .flatMap { $0.points }
            .map { $0.monthOffset }
            .max() ?? 0
        return Array(0...maxOffset)
    }

    private func firstOfMonth(_ date: Date) -> Date {
        let calendar = Calendar.current
        var components = calendar.dateComponents([.year, .month], from: date)
        components.day = 1
        return calendar.date(from: components) ?? date
    }
}
