import SwiftUI

struct JournalView: View {
    @StateObject private var viewModel = JournalViewModel()
    @State private var searchText = ""
    @State private var scrubberActive = false
    @State private var scrubberLabel = ""
    @State private var scrubberOffset: CGFloat = 0
    @State private var currentVisibleMonth: Date?
    @State private var selectedDate: Date?
    @Environment(\.horizontalSizeClass) private var horizontalSizeClass

    var body: some View {
        if horizontalSizeClass == .regular {
            iPadJournalLayout
        } else {
            iPhoneJournalLayout
        }
    }

    // MARK: - iPad Layout (list + inline detail)

    private var iPadJournalLayout: some View {
        HStack(spacing: 0) {
            // Left: month list
            NavigationStack {
                journalListContent(isPad: true)
                    .navigationTitle("Journal")
                    .searchable(text: $searchText, prompt: "Search monthly notes")
                    .onAppear { viewModel.refresh() }
            }
            .frame(width: 320)

            Divider()

            // Right: monthly check-in detail
            NavigationStack {
                if let date = selectedDate {
                    MonthlyCheckInView(referenceDate: date)
                } else {
                    noMonthSelectedView
                }
            }
        }
    }

    // MARK: - iPhone Layout (push navigation)

    private var iPhoneJournalLayout: some View {
        NavigationStack {
            journalListContent(isPad: false)
                .navigationTitle("Journal")
                .searchable(text: $searchText, prompt: "Search monthly notes")
                .onAppear { viewModel.refresh() }
        }
    }

    // MARK: - Shared List Content

    private func journalListContent(isPad: Bool) -> some View {
        ScrollViewReader { proxy in
            ZStack {
                AppBackground()

                List {
                    Section("Monthly Check-ins") {
                        if filteredMonthlyNotes.isEmpty {
                            if searchText.isEmpty {
                                VStack(spacing: 12) {
                                    Image(systemName: "book.closed")
                                        .font(.system(size: 36))
                                        .foregroundColor(.appSecondary)
                                    Text(String(localized: "journal_empty_title"))
                                        .font(.headline)
                                    Text(String(localized: "journal_empty_body"))
                                        .font(.subheadline)
                                        .foregroundColor(.secondary)
                                        .multilineTextAlignment(.center)
                                }
                                .padding(.vertical, 16)
                                .frame(maxWidth: .infinity)
                            } else {
                                Text("No matching notes.")
                                    .font(.subheadline)
                                    .foregroundColor(.secondary)
                            }
                        } else {
                            ForEach(filteredMonthlyNotes) { entry in
                                if isPad {
                                    Button {
                                        selectedDate = entry.date
                                    } label: {
                                        monthlyNoteRow(entry)
                                            .contentShape(Rectangle())
                                    }
                                    .buttonStyle(.plain)
                                    .listRowBackground(
                                        selectedDate.map { $0.isSameMonth(as: entry.date) } == true
                                            ? Color.appPrimary.opacity(0.08)
                                            : Color.clear
                                    )
                                    .id(entry.date)
                                    .onAppear { currentVisibleMonth = entry.date }
                                } else {
                                    NavigationLink {
                                        MonthlyCheckInView(referenceDate: entry.date)
                                    } label: {
                                        monthlyNoteRow(entry)
                                    }
                                    .id(entry.date)
                                    .onAppear { currentVisibleMonth = entry.date }
                                }
                            }
                        }
                    }
                }
                .listStyle(.insetGrouped)
                .scrollContentBackground(.hidden)
            }
            .overlay(alignment: .trailing) {
                monthScrubber(proxy: proxy)
            }
        }
    }

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

            VStack(spacing: 32) {
                // Icon badge con gradiente
                ZStack {
                    Circle()
                        .fill(LinearGradient(
                            colors: [Color.appSecondary, Color.appSecondary.lighter()],
                            startPoint: .topLeading,
                            endPoint: .bottomTrailing
                        ))
                        .frame(width: 120, height: 120)
                        .shadow(color: Color.appSecondary.opacity(0.25), radius: 28, y: 10)

                    Circle()
                        .fill(Color.white.opacity(0.12))
                        .frame(width: 120, height: 120)

                    Image(systemName: "book.closed.fill")
                        .font(.system(size: 50, weight: .light))
                        .foregroundColor(.white)
                }

                VStack(spacing: 10) {
                    Text("Select a Month")
                        .font(.title2.weight(.semibold))

                    Text("Choose a month from the list on the\nleft to view your check-in notes.")
                        .font(.subheadline)
                        .foregroundColor(.secondary)
                        .multilineTextAlignment(.center)
                }

                Label("Select from the list", systemImage: "arrow.left")
                    .font(.subheadline.weight(.semibold))
                    .foregroundColor(.appSecondary)
                    .padding(.horizontal, 22)
                    .padding(.vertical, 11)
                    .background(Color.appSecondary.opacity(0.1))
                    .clipShape(Capsule())
                    .overlay(Capsule().stroke(Color.appSecondary.opacity(0.2), lineWidth: 1))
            }
            .padding(48)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
    }

    private var filteredMonthlyNotes: [MonthlyNoteItem] {
        let trimmedQuery = searchText.trimmingCharacters(in: .whitespacesAndNewlines)
        let hasQuery = !trimmedQuery.isEmpty
        let query = trimmedQuery.lowercased()
        return viewModel.monthlyNotes.filter { entry in
            !hasQuery
                || entry.note.lowercased().contains(query)
                || entry.date.monthYearString.lowercased().contains(query)
        }
    }

    private func monthlyNoteRow(_ entry: MonthlyNoteItem) -> some View {
        VStack(alignment: .leading, spacing: 8) {
            HStack {
                Text(entry.date.monthYearString)
                    .font(.subheadline.weight(.semibold))
                Spacer()
                if let mood = entry.mood {
                    moodPill(mood)
                } else {
                    Text("Mood not set")
                        .font(.caption)
                        .foregroundColor(.secondary)
                }
            }

            HStack(spacing: 6) {
                starRow(rating: entry.rating)
                if entry.rating == nil {
                    Text("No rating")
                        .font(.caption)
                        .foregroundColor(.secondary)
                }
            }

            Text(entry.note.isEmpty ? "No note yet." : entry.note)
                .font(.subheadline)
                .foregroundColor(.secondary)
                .lineLimit(2)
        }
        .padding(.vertical, 4)
    }

    private func starRow(rating: Int?) -> some View {
        let value = rating ?? 0
        return HStack(spacing: 4) {
            ForEach(1...5, id: \.self) { index in
                Image(systemName: index <= value ? "star.fill" : "star")
                    .foregroundColor(index <= value ? .yellow : .secondary)
            }
        }
        .accessibilityLabel(
            Text(String(format: NSLocalizedString("rating_accessibility", comment: ""), value))
        )
    }

    private func moodPill(_ mood: MonthlyCheckInMood) -> some View {
        Label(mood.title, systemImage: mood.iconName)
            .font(.caption.weight(.semibold))
            .padding(.horizontal, 10)
            .padding(.vertical, 6)
            .background(Color.gray.opacity(0.15))
            .foregroundColor(.primary)
            .clipShape(Capsule())
    }

    private func monthScrubber(proxy: ScrollViewProxy) -> some View {
        GeometryReader { geometry in
            let height = geometry.size.height
            let count = filteredMonthlyNotes.count
            let currentIndex = currentVisibleMonth.flatMap { month in
                filteredMonthlyNotes.firstIndex(where: { $0.date.isSameMonth(as: month) })
            }

            ZStack(alignment: .trailing) {
                if let currentVisibleMonth, !scrubberActive {
                    Text(currentVisibleMonth.monthYearString)
                        .font(.caption.weight(.semibold))
                        .padding(.horizontal, 10)
                        .padding(.vertical, 6)
                        .background(Color(.systemBackground).opacity(0.95))
                        .cornerRadius(12)
                        .shadow(color: .black.opacity(0.12), radius: 6, y: 2)
                        .offset(x: -16)
                }

                if scrubberActive {
                    Text(scrubberLabel)
                        .font(.caption.weight(.semibold))
                        .padding(.horizontal, 10)
                        .padding(.vertical, 6)
                        .background(Color(.systemBackground).opacity(0.95))
                        .cornerRadius(12)
                        .shadow(color: .black.opacity(0.12), radius: 6, y: 2)
                        .offset(x: -16, y: scrubberOffset - height / 2)
                }

                if let currentIndex, count > 1 {
                    let progress = CGFloat(currentIndex) / CGFloat(max(count - 1, 1))
                    Circle()
                        .fill(Color.appSecondary.opacity(0.9))
                        .frame(width: 12, height: 12)
                        .offset(y: progress * height - height / 2)
                }

                Capsule()
                    .fill(Color.secondary.opacity(0.35))
                    .frame(width: 6)
                    .frame(maxHeight: .infinity, alignment: .trailing)
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .trailing)
            .padding(.trailing, 8)
            .contentShape(Rectangle())
            .gesture(
                DragGesture(minimumDistance: 0)
                    .onChanged { value in
                        guard count > 0 else { return }
                        scrubberActive = true
                        let clampedY = min(max(value.location.y, 0), height)
                        scrubberOffset = clampedY
                        let ratio = clampedY / max(height, 1)
                        let index = min(max(Int(round(ratio * CGFloat(count - 1))), 0), count - 1)
                        let entry = filteredMonthlyNotes[index]
                        scrubberLabel = entry.date.monthYearString
                        proxy.scrollTo(entry.id, anchor: .top)
                    }
                    .onEnded { _ in
                        scrubberActive = false
                    }
            )
            .allowsHitTesting(count > 0)
        }
        .frame(width: 72)
    }
}

struct MonthlyNoteEditorView: View {
    @Environment(\.dismiss) private var dismiss
    let date: Date
    @Binding var note: String

    var body: some View {
        VStack(alignment: .leading, spacing: 16) {
            Text(date.monthYearString)
                .font(.headline)

            TextEditor(text: $note)
                .frame(minHeight: 200)
                .padding(8)
                .background(Color.gray.opacity(0.08))
                .cornerRadius(12)
        }
        .padding()
        .navigationTitle("Monthly Note")
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .navigationBarTrailing) {
                Button("Save") {
                    MonthlyCheckInStore.setNote(note, for: date)
                    dismiss()
                }
                .fontWeight(.semibold)
            }
        }
    }
}

#Preview {
    NavigationStack {
        JournalView()
    }
}
