import SwiftUI

struct DashboardTabsView: View {
    @EnvironmentObject var projectManager: ProjectManager

    var body: some View {
        VStack(spacing: 0) {
            if projectManager.dashboards.isEmpty {
                emptyState
            } else {
                tabBar
                tabContent
            }
        }
    }

    // MARK: - Empty State

    private var emptyState: some View {
        VStack(spacing: 16) {
            Image(systemName: "rectangle.on.rectangle.slash")
                .font(.system(size: 48))
                .foregroundColor(.secondary)

            Text("No Dashboards Running")
                .font(.title2)
                .foregroundColor(.secondary)

            Text("Right-click a project in the sidebar to start a dashboard,\nor click the play button.")
                .font(.body)
                .foregroundColor(.secondary)
                .multilineTextAlignment(.center)

            if let first = projectManager.projects.first {
                // `.id(...)` rebuilds the button when the target project
                // changes (e.g. after a sidebar reorder) instead of animating
                // the size between two different labels — the latter showed
                // visible artifacts as the bordered-prominent background
                // resized. Wrapping in a `.transaction` with no animation
                // also suppresses implicit width animation when the same
                // project is renamed.
                Button("Start \(first.name)") {
                    projectManager.startDashboard(for: first)
                }
                .buttonStyle(.borderedProminent)
                .id(first.id)
                .transaction { $0.animation = nil }
                .fixedSize()
            } else {
                Button("Add a Project") {
                    projectManager.showAddProject = true
                }
                .buttonStyle(.borderedProminent)
                .fixedSize()
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
    }

    // MARK: - Tab Bar

    private var tabBar: some View {
        HStack(spacing: 0) {
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(spacing: 0) {
                    ForEach(projectManager.dashboards) { dashboard in
                        TabButton(dashboard: dashboard)
                    }
                }
            }

            if let selectedId = projectManager.selectedTab,
               let dashboard = projectManager.dashboards.first(where: { $0.id == selectedId }) {
                Divider().frame(height: 20)
                Button(action: {
                    TerminalHelper.open(path: dashboard.project.path)
                }) {
                    Image(systemName: "terminal")
                        .font(.system(size: 12))
                        .foregroundColor(.secondary)
                }
                .buttonStyle(.plain)
                .padding(.horizontal, 8)
                .help("Open terminal at \(dashboard.project.name)")
            }
        }
        .frame(height: 36)
        .background(Color(nsColor: .controlBackgroundColor))
        .overlay(alignment: .bottom) {
            Divider()
        }
    }

    // MARK: - Tab Content

    @ViewBuilder
    private var tabContent: some View {
        if let selectedId = projectManager.selectedTab,
           let dashboard = projectManager.dashboards.first(where: { $0.id == selectedId }) {
            switch dashboard.status {
            case .running:
                if let url = dashboard.url {
                    DashboardWebView(url: url)
                } else {
                    loadingView(dashboard)
                }
            case .starting:
                loadingView(dashboard)
            case .error:
                errorView(dashboard)
            case .stopping, .stopped:
                stoppedView(dashboard)
            }
        } else if let first = projectManager.dashboards.first {
            Color.clear
                .onAppear {
                    projectManager.selectedTab = first.id
                }
        }
    }

    private func loadingView(_ dashboard: DashboardInstance) -> some View {
        VStack(spacing: 16) {
            ProgressView()
                .controlSize(.large)
            Text("Starting dashboard for \(dashboard.project.name)...")
                .font(.title3)
                .foregroundColor(.secondary)

            if !dashboard.outputLog.isEmpty {
                ScrollView {
                    Text(dashboard.outputLog)
                        .font(.system(.caption, design: .monospaced))
                        .frame(maxWidth: .infinity, alignment: .leading)
                        .padding()
                }
                .frame(maxWidth: 500, maxHeight: 200)
                .background(Color(nsColor: .textBackgroundColor))
                .cornerRadius(8)
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
    }

    private func errorView(_ dashboard: DashboardInstance) -> some View {
        VStack(spacing: 16) {
            Image(systemName: "exclamationmark.triangle.fill")
                .font(.system(size: 48))
                .foregroundColor(.red)

            Text("Dashboard Error")
                .font(.title2)

            if let error = dashboard.errorMessage {
                Text(error)
                    .font(.body)
                    .foregroundColor(.secondary)
            }

            if !dashboard.outputLog.isEmpty {
                ScrollView {
                    Text(dashboard.outputLog)
                        .font(.system(.caption, design: .monospaced))
                        .frame(maxWidth: .infinity, alignment: .leading)
                        .padding()
                }
                .frame(maxWidth: 600, maxHeight: 300)
                .background(Color(nsColor: .textBackgroundColor))
                .cornerRadius(8)
            }

            HStack {
                Button("Restart") {
                    projectManager.removeDashboard(id: dashboard.id)
                    projectManager.startDashboard(for: dashboard.project)
                }
                .buttonStyle(.borderedProminent)

                Button("Remove") {
                    projectManager.removeDashboard(id: dashboard.id)
                }
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
    }

    private func stoppedView(_ dashboard: DashboardInstance) -> some View {
        VStack(spacing: 16) {
            Image(systemName: "stop.circle")
                .font(.system(size: 48))
                .foregroundColor(.secondary)

            Text("Dashboard Stopped")
                .font(.title2)
                .foregroundColor(.secondary)

            HStack {
                Button("Restart") {
                    projectManager.removeDashboard(id: dashboard.id)
                    projectManager.startDashboard(for: dashboard.project)
                }
                .buttonStyle(.borderedProminent)

                Button("Remove Tab") {
                    projectManager.removeDashboard(id: dashboard.id)
                }
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
    }
}

// MARK: - Tab Button

struct TabButton: View {
    @EnvironmentObject var projectManager: ProjectManager
    let dashboard: DashboardInstance

    private var isSelected: Bool {
        projectManager.selectedTab == dashboard.id
    }

    var body: some View {
        HStack(spacing: 6) {
            statusDot

            Text(dashboard.project.name)
                .font(.system(size: 12, weight: isSelected ? .semibold : .regular))
                .lineLimit(1)

            // Badges for tabs that need attention. The green status dot
            // already conveys "running", so the port suffix that used to
            // live here was redundant — we use the freed space for these.
            if dashboard.status == .running {
                if dashboard.questionsCount > 0 {
                    badge(
                        count: dashboard.questionsCount,
                        color: .orange,
                        systemImage: "questionmark",
                        help: "\(dashboard.questionsCount) item\(dashboard.questionsCount == 1 ? "" : "s") awaiting your answer"
                    )
                }
                if dashboard.reviewsCount > 0 {
                    badge(
                        count: dashboard.reviewsCount,
                        color: .blue,
                        systemImage: "eye",
                        help: "\(dashboard.reviewsCount) item\(dashboard.reviewsCount == 1 ? "" : "s") in review"
                    )
                }
            }

            Button(action: {
                projectManager.removeDashboard(id: dashboard.id)
            }) {
                Image(systemName: "xmark")
                    .font(.system(size: 9, weight: .bold))
                    .foregroundColor(.secondary)
            }
            .buttonStyle(.plain)
            .opacity(isSelected ? 1 : 0)
        }
        .padding(.horizontal, 12)
        .padding(.vertical, 6)
        .background(isSelected ? Color(nsColor: .selectedControlColor).opacity(0.3) : Color.clear)
        .overlay(alignment: .bottom) {
            if isSelected {
                Rectangle()
                    .fill(Color.accentColor)
                    .frame(height: 2)
            }
        }
        .contentShape(Rectangle())
        .onTapGesture {
            projectManager.selectedTab = dashboard.id
        }
        .onHover { hovering in
            if hovering {
                NSCursor.pointingHand.push()
            } else {
                NSCursor.pop()
            }
        }
    }

    /// Compact pill showing an SF Symbol + count, e.g. ❓ 2 or 👁 1.
    /// Tinted so a glance across many tabs surfaces the ones that need attention.
    private func badge(count: Int, color: Color, systemImage: String, help: String) -> some View {
        HStack(spacing: 2) {
            Image(systemName: systemImage)
                .font(.system(size: 8, weight: .bold))
            Text("\(count)")
                .font(.system(size: 10, weight: .semibold, design: .rounded))
                .monospacedDigit()
        }
        .foregroundColor(.white)
        .padding(.horizontal, 5)
        .padding(.vertical, 1)
        .background(
            Capsule().fill(color)
        )
        .help(help)
    }

    @ViewBuilder
    private var statusDot: some View {
        switch dashboard.status {
        case .running:
            Circle()
                .fill(.green)
                .frame(width: 8, height: 8)
        case .starting, .stopping:
            ProgressView()
                .controlSize(.mini)
        case .error:
            Circle()
                .fill(.red)
                .frame(width: 8, height: 8)
        case .stopped:
            Circle()
                .fill(.gray)
                .frame(width: 8, height: 8)
        }
    }
}
