import SwiftUI
import Charts

struct LinkDetailView: View {
    let link: Link
    @EnvironmentObject var linkViewModel: LinkViewModel
    @Environment(\.presentationMode) var presentationMode
    @State private var selectedTimeRange: TimeRange = .threeMonths
    @State private var showingEdit = false
    @State private var templateParameters: [String: String] = [:]
    @State private var showingTemplateDialog = false
    @State private var showingShareSheet = false

    private var shareItems: [Any] {
        var items: [Any] = []

        // Add the alias and URL for link/template types
        if link.linkTypeEnum == .link || link.linkTypeEnum == .template {
            if let url = link.originalURL, !url.isEmpty {
                items.append("\(link.alias): \(url)")
                items.append(URL(string: url) ?? url)
            } else {
                items.append(link.alias)
            }
        }

        return items
    }

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

        var displayName: String {
            switch self {
            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 .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
            }
        }
    }

    var filteredClickLogs: [ClickLog] {
        let logs = link.sortedClickLogs

        guard let dateRange = selectedTimeRange.dateRange else {
            return logs
        }

        return logs.filter { log in
            dateRange.contains(log.clickedAt)
        }
    }

    var chartData: [ChartDataPoint] {
        let calendar = Calendar.current
        let logs = filteredClickLogs

        guard !logs.isEmpty else { return [] }

        // Determine the grouping based on time range
        let component: Calendar.Component
        let dateFormat: String

        switch selectedTimeRange {
        case .threeMonths, .sixMonths:
            component = .day
            dateFormat = "MMM d"
        case .oneYear:
            component = .weekOfYear
            dateFormat = "MMM d"
        case .allTime:
            component = .month
            dateFormat = "MMM yyyy"
        }

        // Group clicks by the component
        let groupedLogs = Dictionary(grouping: logs) { log in
            calendar.dateInterval(of: component, for: log.clickedAt)?.start ?? log.clickedAt
        }

        // Create chart data points
        let formatter = DateFormatter()
        formatter.dateFormat = dateFormat

        return groupedLogs.map { date, logs in
            ChartDataPoint(
                date: date,
                count: logs.count,
                label: formatter.string(from: date)
            )
        }.sorted { $0.date < $1.date }
    }

    var body: some View {
        NavigationView {
            ScrollView {
                VStack(alignment: .leading, spacing: 16) {
                    headerSection
                    tagsSection
                    customContentSection
                    analyticsSection
                    changeHistorySection
                }
                .padding()
            }
            .navigationTitle("Link Details - \(link.alias)")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button("close") {
                        presentationMode.wrappedValue.dismiss()
                    }
                }

                ToolbarItem(placement: .navigationBarTrailing) {
                    toolbarMenu
                }
            }
        }
        .sheet(isPresented: $showingEdit) {
            LinkFormView(link: link)
                .environmentObject(linkViewModel)
        }
        .sheet(isPresented: $showingTemplateDialog) {
            TemplateParameterView(
                link: link,
                parameters: $templateParameters,
                onOpen: { params in
                    linkViewModel.openLink(link, with: params)
                    presentationMode.wrappedValue.dismiss()
                }
            )
        }
        .sheet(isPresented: $showingShareSheet) {
            ShareSheet(activityItems: shareItems)
        }
    }

    private var headerSection: some View {
        VStack(alignment: .leading, spacing: 8) {
            // Alias row (tappable)
            HStack {
                Button(action: {
                    handlePrimaryOpen()
                }) {
                    Text(link.alias)
                        .font(.largeTitle)
                        .fontWeight(.bold)
                        .foregroundColor(.primary)
                        .contentShape(Rectangle())
                }
                .buttonStyle(PlainButtonStyle())
                .accessibilityLabel("open_link")

                Spacer()

                Text(link.linkTypeEnum.displayName)
                    .font(.caption)
                    .padding(.horizontal, 8)
                    .padding(.vertical, 4)
                    .background(linkTypeColor(link.linkTypeEnum))
                    .foregroundColor(.white)
                    .cornerRadius(6)
            }

            // URL row (tappable if exists) - only show for non-custom links
            if let url = link.originalURL, !url.isEmpty, link.linkTypeEnum != .custom {
                Button(action: {
                    handlePrimaryOpen()
                }) {
                    HStack(alignment: .top, spacing: 4) {
                        Image(systemName: "safari")
                            .foregroundColor(.blue)
                        Text(url)
                            .font(.body)
                            .foregroundColor(.blue)
                            .multilineTextAlignment(.leading)
                    }
                }
                .buttonStyle(PlainButtonStyle())
                .accessibilityLabel("open_link")
            }

            if let description = link.linkDescription, !description.isEmpty {
                Text(description)
                    .font(.body)
                    .foregroundColor(.secondary)
            }
        }
        .padding()
        .background(Color(.systemGray6))
        .cornerRadius(12)
    }

    private var tagsSection: some View {
        Group {
            if !link.sortedTags.isEmpty {
                VStack(alignment: .leading) {
                    Text("tags")
                        .font(.headline)

                    ScrollView(.horizontal, showsIndicators: false) {
                        HStack {
                            ForEach(link.sortedTags, id: \.id) { tag in
                                NavigationLink(destination: TagDetailView(tag: tag)) {
                                    Text(tag.name)
                                        .font(.caption)
                                        .padding(.horizontal, 8)
                                        .padding(.vertical, 4)
                                        .background(Color.blue.opacity(0.2))
                                        .foregroundColor(.blue)
                                        .cornerRadius(6)
                                }
                                .buttonStyle(PlainButtonStyle())
                            }
                        }
                        .padding(.horizontal)
                    }
                }
            }
        }
    }

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

                Spacer()

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

            analyticsStatsCards
            analyticsChart
        }
    }

    private var analyticsStatsCards: some View {
        HStack(spacing: 16) {
            StatCard(
                title: "total_clicks",
                value: "\(link.clickCount)",
                icon: "hand.tap"
            )

            StatCard(
                title: "clicks_in_period",
                value: "\(filteredClickLogs.count)",
                icon: "chart.bar"
            )
        }
    }

    private var analyticsChart: some View {
        Group {
            if !chartData.isEmpty {
                Chart(chartData) { dataPoint in
                    BarMark(
                        x: .value("Date", dataPoint.date),
                        y: .value("Clicks", dataPoint.count)
                    )
                    .foregroundStyle(.blue)
                }
                .frame(height: 200)
                .chartXAxisLabel("Date")
                .chartYAxisLabel("Clicks")
            } else {
                Text("no_data_for_period")
                    .font(.body)
                    .foregroundColor(.secondary)
                    .frame(height: 200)
                    .frame(maxWidth: .infinity)
                    .background(Color(.systemGray6))
                    .cornerRadius(8)
            }
        }
    }

    private var customContentSection: some View {
        Group {
            if link.linkTypeEnum == .custom, let text = link.text {
                VStack(alignment: .leading, spacing: 6) {
                    Text("content_preview")
                        .font(.headline)

                    MarkdownView(text: text)
                        .frame(maxWidth: .infinity, maxHeight: 300, alignment: .leading)
                        .background(Color(.systemGray6))
                        .cornerRadius(8)
                }
            }
        }
    }

    private var changeHistorySection: some View {
        Group {
          if ((link.changeLogs?.allObjects.isEmpty) == nil) {
                VStack(alignment: .leading) {
                    Text("change_history")
                        .font(.headline)

                    let changeLogs = (link.changeLogs?.allObjects as? [ChangeLog] ?? [])
                        .sorted { $0.changedAt > $1.changedAt }

                    ForEach(changeLogs.prefix(10), id: \.id) { changeLog in
                        HStack {
                            Image(systemName: changeLog.changeType == "CREATE" ? "plus.circle" : "pencil.circle")
                                .foregroundColor(changeLog.changeType == "CREATE" ? .green : .orange)

                            VStack(alignment: .leading) {
                                Text(changeLog.changeDescription)
                                    .font(.body)
                                Text(changeLog.changedAt, format: .dateTime)
                                    .font(.caption)
                                    .foregroundColor(.secondary)
                            }

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

    private var toolbarMenu: some View {
        Menu {
            // Share button for link and template types (not for custom)
            if link.linkTypeEnum == .link || link.linkTypeEnum == .template {
                Button(action: {
                    showingShareSheet = true
                }) {
                    Label("Share", systemImage: "square.and.arrow.up")
                }
            }

            Button("edit") {
                showingEdit = true
            }

            if link.isTemplate {
                Button("open_with_parameters") { showingTemplateDialog = true }
            }

            Button("delete", role: .destructive) {
                linkViewModel.deleteLink(link)
                presentationMode.wrappedValue.dismiss()
            }
        } 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
        }
    }

    private func handlePrimaryOpen() {
        if link.isTemplate {
            showingTemplateDialog = true
        } else {
            linkViewModel.openLink(link)
        }
    }
}

struct StatCard: View {
    let title: String
    let value: String
    let icon: String

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

            Text(value)
                .font(.title2)
                .fontWeight(.semibold)
        }
        .padding()
        .frame(maxWidth: .infinity, alignment: .leading)
        .background(Color(.systemGray6))
        .cornerRadius(8)
    }
}

struct ChartDataPoint: Identifiable {
    let id = UUID()
    let date: Date
    let count: Int
    let label: String
}

struct TemplateParameterView: View {
    let link: Link
    @Binding var parameters: [String: String]
    let onOpen: ([String: String]) -> Void
    @Environment(\.presentationMode) var presentationMode
    @State private var extractedParams: [TemplateParameter] = []

    var body: some View {
        NavigationView {
            Form {
                Section("template_parameters") {
                    ForEach(extractedParams, id: \.name) { param in
                        VStack(alignment: .leading) {
                            Text(param.name)
                                .font(.headline)

                            TextField(param.defaultValue ?? "enter_value", text: Binding(
                                get: { parameters[param.name] ?? param.defaultValue ?? "" },
                                set: { parameters[param.name] = $0 }
                            ))
                            .textFieldStyle(RoundedBorderTextFieldStyle())
                        }
                    }
                }
            }
            .navigationTitle("enter_parameters")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button("cancel") {
                        presentationMode.wrappedValue.dismiss()
                    }
                }

                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("open") {
                        onOpen(parameters)
                    }
                }
            }
        }
        .onAppear {
            extractTemplateParameters()
        }
    }

    private func extractTemplateParameters() {
        guard let url = link.originalURL else { return }
        extractedParams = URLTemplateProcessor.extractParameters(from: url)
    }
}

#Preview {
    LinkDetailView(link: PersistenceController.preview.container.viewContext.registeredObjects.first { $0 is Link } as! Link)
        .environmentObject(LinkViewModel())
}
