import SwiftUI
import CoreData
import Charts

struct SourceDetailView: View {
    @StateObject private var viewModel: SourceDetailViewModel
    @Environment(\.dismiss) private var dismiss

    @State private var showingDeleteConfirmation = false
    @Environment(\.managedObjectContext) private var viewContext
    @State private var editingSnapshotSelection: SnapshotSelection?
    @State private var editingContribution = false
    @State private var contributionInput = ""
    @State private var showingContributionApplyDialog = false
    @State private var pendingContributionAmount: Decimal? = nil

    init(source: InvestmentSource, iapService: IAPService) {
        _viewModel = StateObject(wrappedValue: SourceDetailViewModel(
            source: source,
            iapService: iapService
        ))
    }

    var body: some View {
        Group {
            if viewModel.isDeleted {
                Color.clear
                    .onAppear {
                        dismiss()
                    }
            } else {
                contentView
            }
        }
    }

    private var contentView: some View {
        ZStack {
            AppBackground()

            ScrollView {
                VStack(spacing: 20) {
                    // Header Card
                    headerCard

                    // Performance Summary — full width, above quick actions
                    metricsSection

                    // Quick Actions
                    quickActions

                    // Monthly Contribution
                    monthlyContributionCard

                    // Chart
                    if !viewModel.chartData.isEmpty {
                        chartSection
                    }

                    // Snapshots List
                    snapshotsSection
                }
                .padding()
            }
        }
        .navigationTitle(viewModel.safeSourceName)
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .navigationBarTrailing) {
                Menu {
                    Button {
                        viewModel.showingEditSource = true
                    } label: {
                        Label("Edit Source", systemImage: "pencil")
                    }

                    Button(role: .destructive) {
                        showingDeleteConfirmation = true
                    } label: {
                        Label("Delete Source", systemImage: "trash")
                    }
                } label: {
                    Image(systemName: "ellipsis.circle")
                }
            }
        }
        .sheet(isPresented: $viewModel.showingAddSnapshot) {
            AddSnapshotView(source: viewModel.source)
        }
        .sheet(item: $editingSnapshotSelection) { selection in
            if let snapshot = try? viewContext.existingObject(with: selection.id) as? Snapshot {
                AddSnapshotView(source: viewModel.source, snapshot: snapshot)
            } else {
                MissingSnapshotView()
            }
        }
        .sheet(isPresented: $viewModel.showingEditSource) {
            EditSourceView(source: viewModel.source)
        }
        .sheet(isPresented: $viewModel.showingPaywall) {
            PaywallView()
        }
        .confirmationDialog(
            "Delete Source",
            isPresented: $showingDeleteConfirmation,
            titleVisibility: .visible
        ) {
            Button("Delete", role: .destructive) {
                viewModel.deleteSource()
                dismiss()
            }
        } message: {
            Text("This will permanently delete \(viewModel.safeSourceName) and all its snapshots.")
        }
        .onChange(of: viewModel.isDeleted) { _, deleted in
            if deleted {
                dismiss()
            }
        }
    }

    // MARK: - Header Card

    private var headerCard: some View {
        VStack(spacing: 12) {
            // Category badge
            HStack {
                Image(systemName: viewModel.source.category?.icon ?? "questionmark")
                Text(viewModel.categoryName)
            }
            .font(.caption)
            .foregroundColor(Color(hex: viewModel.categoryColor) ?? .gray)
            .padding(.horizontal, 12)
            .padding(.vertical, 6)
            .background((Color(hex: viewModel.categoryColor) ?? .gray).opacity(0.1))
            .cornerRadius(20)

            // Current value
            Text(viewModel.formattedCurrentValue)
                .font(.system(size: 36, weight: .bold, design: .rounded))

            // Return
            HStack(spacing: 4) {
                Image(systemName: viewModel.isPositiveReturn ? "arrow.up.right" : "arrow.down.right")
                Text(viewModel.formattedTotalReturn)
                Text("(\(viewModel.formattedPercentageReturn))")
            }
            .font(.subheadline.weight(.medium))
            .foregroundColor(viewModel.isPositiveReturn ? .positiveGreen : .negativeRed)

            // Last updated
            Text("Last updated: \(viewModel.lastUpdated)")
                .font(.caption)
                .foregroundColor(.secondary)
        }
        .frame(maxWidth: .infinity)
        .padding()
        .background(Color(.systemBackground))
        .cornerRadius(AppConstants.UI.cornerRadius)
        .shadow(color: .black.opacity(0.05), radius: 8, y: 2)
    }

    // MARK: - Quick Actions

    private var quickActions: some View {
        Button {
            viewModel.showingAddSnapshot = true
        } label: {
            Label("Add Snapshot", systemImage: "plus.circle.fill")
                .font(.subheadline.weight(.semibold))
                .frame(maxWidth: .infinity)
                .padding()
                .background(Color.appPrimary)
                .foregroundColor(.white)
                .cornerRadius(AppConstants.UI.cornerRadius)
        }
    }

    // MARK: - Monthly Contribution Card

    private var monthlyContributionCard: some View {
        let sourceId = viewModel.source.id
        let current = MonthlyContributionStore.contribution(for: sourceId)
        return VStack(alignment: .leading, spacing: 10) {
            HStack {
                Label(String(localized: "source_monthly_contribution_title"), systemImage: "arrow.down.circle.fill")
                    .font(.subheadline.weight(.semibold))
                    .foregroundColor(.primary)
                Spacer()
                Button {
                    if editingContribution {
                        if let val = CurrencyFormatter.parseUserInput(contributionInput), val > 0 {
                            MonthlyContributionStore.setContribution(val, for: sourceId)
                            pendingContributionAmount = val
                            showingContributionApplyDialog = true
                        } else if contributionInput.trimmingCharacters(in: .whitespaces).isEmpty {
                            MonthlyContributionStore.setContribution(nil, for: sourceId)
                        }
                    } else {
                        contributionInput = current.map { String(format: "%.2f", NSDecimalNumber(decimal: $0).doubleValue) } ?? ""
                    }
                    editingContribution.toggle()
                } label: {
                    Text(editingContribution ? String(localized: "done") : String(localized: "edit"))
                        .font(.caption.weight(.semibold))
                        .foregroundColor(.appPrimary)
                }
            }

            if editingContribution {
                TextField(String(localized: "source_monthly_contribution_placeholder"), text: $contributionInput)
                    .keyboardType(.decimalPad)
                    .padding(8)
                    .background(Color(.systemGray6))
                    .cornerRadius(8)
            } else {
                Text(current.map { $0.currencyString } ?? String(localized: "source_monthly_contribution_not_set"))
                    .font(.subheadline)
                    .foregroundColor(current != nil ? .primary : .secondary)
            }

            Text(String(localized: "source_monthly_contribution_hint"))
                .font(.caption2)
                .foregroundColor(.secondary)
        }
        .padding()
        .background(Color(.systemBackground))
        .cornerRadius(AppConstants.UI.cornerRadius)
        .shadow(color: .black.opacity(0.05), radius: 8, y: 2)
        .confirmationDialog(
            String(localized: "source_monthly_contribution_apply_title"),
            isPresented: $showingContributionApplyDialog,
            titleVisibility: .visible
        ) {
            Button(String(localized: "source_monthly_contribution_apply_retroactive")) {
                if let amount = pendingContributionAmount {
                    applyContributionRetroactively(amount: amount)
                }
            }
            Button(String(localized: "source_monthly_contribution_apply_forward"), role: .cancel) {}
        } message: {
            if let amount = pendingContributionAmount {
                Text(String(format: String(localized: "source_monthly_contribution_apply_message"), amount.currencyString))
            }
        }
    }

    private func applyContributionRetroactively(amount: Decimal) {
        let request = Snapshot.fetchRequest()
        request.predicate = NSPredicate(format: "source == %@ AND (contribution == nil OR contribution == 0)", viewModel.source)
        guard let snapshots = try? viewContext.fetch(request) else { return }
        for snapshot in snapshots {
            snapshot.contribution = NSDecimalNumber(decimal: amount)
        }
        try? viewContext.save()
    }

    // MARK: - Chart Section

    private var chartSection: some View {
        VStack(alignment: .leading, spacing: 12) {
            Text("Value History")
                .font(.headline)

            Chart {
                ForEach(viewModel.chartData, id: \.date) { item in
                    LineMark(
                        x: .value("Date", item.date),
                        y: .value("Value", NSDecimalNumber(decimal: item.value).doubleValue)
                    )
                    .foregroundStyle(Color.appPrimary)
                    .interpolationMethod(.catmullRom)

                    AreaMark(
                        x: .value("Date", item.date),
                        y: .value("Value", NSDecimalNumber(decimal: item.value).doubleValue)
                    )
                    .foregroundStyle(
                        LinearGradient(
                            colors: [Color.appPrimary.opacity(0.3), Color.appPrimary.opacity(0.0)],
                            startPoint: .top,
                            endPoint: .bottom
                        )
                    )
                    .interpolationMethod(.catmullRom)
                }

                if viewModel.canViewPredictions, !viewModel.predictions.isEmpty {
                    ForEach(viewModel.predictions, id: \.id) { prediction in
                        AreaMark(
                            x: .value("Prediction Date", prediction.date),
                            yStart: .value("Lower", NSDecimalNumber(decimal: prediction.confidenceInterval.lower).doubleValue),
                            yEnd: .value("Upper", NSDecimalNumber(decimal: prediction.confidenceInterval.upper).doubleValue)
                        )
                        .foregroundStyle(Color.appSecondary.opacity(0.18))

                        LineMark(
                            x: .value("Prediction Date", prediction.date),
                            y: .value("Predicted Value", NSDecimalNumber(decimal: prediction.predictedValue).doubleValue)
                        )
                        .foregroundStyle(Color.appSecondary)
                        .lineStyle(StrokeStyle(lineWidth: 2, dash: [6, 4]))
                    }

                    if let firstPrediction = viewModel.predictions.first {
                        PointMark(
                            x: .value("Forecast Start", firstPrediction.date),
                            y: .value("Forecast Value", NSDecimalNumber(decimal: firstPrediction.predictedValue).doubleValue)
                        )
                        .symbolSize(30)
                        .foregroundStyle(Color.appSecondary)
                        .annotation(position: .topTrailing) {
                            Text("Forecast")
                                .font(.caption.weight(.semibold))
                                .padding(.horizontal, 6)
                                .padding(.vertical, 4)
                                .background(Color.appSecondary.opacity(0.15))
                                .cornerRadius(8)
                        }
                    }
                }
            }
            .chartXAxis {
                AxisMarks(values: .stride(by: .month, count: 2)) { value in
                    AxisValueLabel(format: .dateTime.month(.abbreviated))
                }
            }
            .chartYAxis {
                AxisMarks(position: .leading) { value in
                    AxisValueLabel {
                        if let doubleValue = value.as(Double.self) {
                            Text(Decimal(doubleValue).shortCurrencyString)
                                .font(.caption)
                        }
                    }
                }
            }
            .frame(height: 200)

            if !viewModel.canViewPredictions && viewModel.hasEnoughDataForPredictions {
                Button {
                    viewModel.showingPaywall = true
                } label: {
                    HStack(spacing: 6) {
                        Image(systemName: "lock.fill")
                        Text("Unlock predictions on the chart")
                    }
                    .font(.caption.weight(.semibold))
                    .foregroundColor(.appPrimary)
                    .padding(.vertical, 6)
                    .padding(.horizontal, 10)
                    .background(Color.appPrimary.opacity(0.1))
                    .cornerRadius(10)
                }
                .frame(maxWidth: .infinity, alignment: .leading)
            }
        }
        .padding()
        .background(Color(.systemBackground))
        .cornerRadius(AppConstants.UI.cornerRadius)
        .shadow(color: .black.opacity(0.05), radius: 8, y: 2)
    }

    // MARK: - Metrics Section

    private var metricsSection: some View {
        VStack(alignment: .leading, spacing: 12) {
            Text("Performance Metrics")
                .font(.headline)

            LazyVGrid(columns: [
                GridItem(.flexible()),
                GridItem(.flexible())
            ], spacing: 16) {
                MetricCard(title: "CAGR", value: viewModel.metrics.formattedCAGR)
                MetricCard(title: "Volatility", value: viewModel.metrics.formattedVolatility)
                MetricCard(title: "Max Drawdown", value: viewModel.metrics.formattedMaxDrawdown)
                MetricCard(title: "Sharpe Ratio", value: viewModel.metrics.formattedSharpeRatio)
                MetricCard(title: "Win Rate", value: viewModel.metrics.formattedWinRate)
                MetricCard(title: "Avg Monthly", value: viewModel.metrics.formattedAverageMonthlyReturn)
            }
        }
        .padding()
        .background(Color(.systemBackground))
        .cornerRadius(AppConstants.UI.cornerRadius)
        .shadow(color: .black.opacity(0.05), radius: 8, y: 2)
    }

    // MARK: - Snapshots Section

    private var snapshotsSection: some View {
        VStack(alignment: .leading, spacing: 12) {
            HStack {
                Text("Snapshots")
                    .font(.headline)

                Spacer()

                Text("\(viewModel.snapshotCount)")
                    .font(.subheadline)
                    .foregroundColor(.secondary)
            }

            if viewModel.isHistoryLimited {
                HStack {
                    Image(systemName: "info.circle")
                        .foregroundColor(.appWarning)
                    Text("\(viewModel.hiddenSnapshotCount) older snapshots hidden. Upgrade for full history.")
                        .font(.caption)

                    Spacer()

                    Button("Upgrade") {
                        viewModel.showingPaywall = true
                    }
                    .font(.caption.weight(.semibold))
                }
                .padding(8)
                .background(Color.appWarning.opacity(0.1))
                .cornerRadius(AppConstants.UI.smallCornerRadius)
            }

            // Use LazyVStack for better performance with many snapshots
            LazyVStack(spacing: 0) {
                ForEach(viewModel.visibleSnapshots, id: \.objectID) { snapshot in
                    VStack(spacing: 0) {
                        SnapshotRowView(snapshot: snapshot, onEdit: {
                            editingSnapshotSelection = SnapshotSelection(id: snapshot.objectID)
                        })
                        .contentShape(Rectangle())
                        .onTapGesture {
                            editingSnapshotSelection = SnapshotSelection(id: snapshot.objectID)
                        }
                        .contextMenu {
                            Button {
                                editingSnapshotSelection = SnapshotSelection(id: snapshot.objectID)
                            } label: {
                                Label("Edit", systemImage: "pencil")
                            }
                        }
                        .swipeActions(edge: .trailing) {
                            Button {
                                editingSnapshotSelection = SnapshotSelection(id: snapshot.objectID)
                            } label: {
                                Label("Edit", systemImage: "pencil")
                            }

                            Button(role: .destructive) {
                                viewModel.deleteSnapshot(snapshot)
                            } label: {
                                Label("Delete", systemImage: "trash")
                            }
                        }

                        if snapshot.objectID != viewModel.visibleSnapshots.last?.objectID {
                            Divider()
                        }
                    }
                }
            }

            // Show "more snapshots" only for free users who have limited history
            if viewModel.isHistoryLimited && viewModel.hiddenSnapshotCount > 0 {
                Text("+ \(viewModel.hiddenSnapshotCount) older snapshots hidden")
                    .font(.caption)
                    .foregroundColor(.secondary)
            }
        }
        .padding()
        .background(Color(.systemBackground))
        .cornerRadius(AppConstants.UI.cornerRadius)
        .shadow(color: .black.opacity(0.05), radius: 8, y: 2)
    }
}

// MARK: - Metric Card

struct MetricCard: View {
    let title: String
    let value: String

    var body: some View {
        VStack(alignment: .leading, spacing: 4) {
            Text(title)
                .font(.caption)
                .foregroundColor(.secondary)

            Text(value)
                .font(.subheadline.weight(.semibold))
        }
        .frame(maxWidth: .infinity, alignment: .leading)
    }
}

// MARK: - Snapshot Row View

struct SnapshotRowView: View {
    let snapshot: Snapshot
    let onEdit: (() -> Void)?

    var body: some View {
        HStack(spacing: 12) {
            VStack(alignment: .leading, spacing: 2) {
                Text(snapshot.safeDate.friendlyDescription)
                    .font(.subheadline)

                if let notes = snapshot.notes, !notes.isEmpty {
                    Text(notes)
                        .font(.caption)
                        .foregroundColor(.secondary)
                        .lineLimit(1)
                }
            }

            Spacer()

            VStack(alignment: .trailing, spacing: 2) {
                Text(snapshot.formattedValue)
                    .font(.subheadline.weight(.medium))

                if snapshot.contribution != nil && snapshot.decimalContribution > 0 {
                    Text("+ \(snapshot.decimalContribution.currencyString)")
                        .font(.caption)
                        .foregroundColor(.appPrimary)
                }
            }

            if let onEdit = onEdit {
                Button(action: onEdit) {
                    Image(systemName: "pencil")
                        .font(.caption)
                        .foregroundColor(.secondary)
                        .padding(6)
                        .background(Color.gray.opacity(0.1))
                        .cornerRadius(8)
                }
                .buttonStyle(.plain)
            }
        }
        .padding(.vertical, 4)
    }
}

struct MetricChip: View {
    let title: String
    let value: String

    var body: some View {
        VStack(alignment: .leading, spacing: 4) {
            Text(title)
                .font(.caption)
                .foregroundColor(.secondary)

            Text(value)
                .font(.caption.weight(.semibold))
        }
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding(.vertical, 10)
        .padding(.horizontal, 12)
        .background(Color.gray.opacity(0.1))
        .cornerRadius(10)
    }
}

private struct SnapshotSelection: Identifiable {
    let id: NSManagedObjectID
}

private struct MissingSnapshotView: View {
    var body: some View {
        VStack(spacing: 12) {
            Image(systemName: "exclamationmark.triangle")
                .font(.system(size: 40))
                .foregroundStyle(.orange)
            Text("Snapshot not available")
                .font(.headline)
            Text("This snapshot was removed or is no longer accessible.")
                .font(.subheadline)
                .multilineTextAlignment(.center)
                .foregroundStyle(.secondary)
        }
        .padding()
    }
}

#Preview {
    NavigationStack {
        Text("Source Detail Preview")
    }
}
