import SwiftUI

/// Card component displaying session information in the list.
///
/// Shows session details including status, command, working directory,
/// and provides quick actions for managing the session.
struct SessionCardView: View {
    let session: Session
    let onTap: () -> Void
    let onKill: () -> Void
    let onCleanup: () -> Void

    @State private var isPressed = false
    @State private var terminalSnapshot: TerminalSnapshot?
    @State private var isLoadingSnapshot = false
    @State private var isKilling = false
    @State private var opacity: Double = 1.0
    @State private var scale: CGFloat = 1.0
    @State private var rotation: Double = 0
    @State private var brightness: Double = 1.0

    @Environment(\.livePreviewSubscription) private var livePreview

    private var displayWorkingDir: String {
        // Convert absolute paths back to ~ notation for display
        let homePrefix = "/Users/"
        if session.workingDir.hasPrefix(homePrefix),
           let userEndIndex = session.workingDir[homePrefix.endIndex...].firstIndex(of: "/")
        {
            let restOfPath = String(session.workingDir[userEndIndex...])
            return "~\(restOfPath)"
        }
        return session.workingDir
    }

    var body: some View {
        Button(action: onTap) {
            VStack(alignment: .leading, spacing: Theme.Spacing.medium) {
                // Header with session ID/name and kill button
                HStack {
                    Text(session.displayName)
                        .font(Theme.Typography.terminalSystem(size: 14))
                        .fontWeight(.medium)
                        .foregroundColor(Theme.Colors.primaryAccent)
                        .lineLimit(1)

                    Spacer()

                    Button(action: {
                        HapticFeedback.impact(.medium)
                        if session.isRunning {
                            animateKill()
                        } else {
                            animateCleanup()
                        }
                    }, label: {
                        if isKilling {
                            LoadingView(message: "", useUnicodeSpinner: true)
                                .scaleEffect(0.7)
                                .frame(width: 18, height: 18)
                        } else {
                            Image(systemName: session.isRunning ? "xmark.circle" : "trash.circle")
                                .font(.system(size: 18))
                                .foregroundColor(session.isRunning ? Theme.Colors.errorAccent : Theme.Colors
                                    .terminalForeground.opacity(0.6)
                                )
                        }
                    })
                    .buttonStyle(.plain)
                }

                // Terminal content area showing command and terminal output preview
                RoundedRectangle(cornerRadius: Theme.CornerRadius.small)
                    .fill(Theme.Colors.terminalBackground)
                    .frame(height: 120)
                    .overlay(
                        Group {
                            if session.isRunning {
                                // Show live preview if available
                                if let bufferSnapshot = livePreview?.latestSnapshot {
                                    CompactTerminalPreview(snapshot: bufferSnapshot)
                                        .animation(.easeInOut(duration: 0.2), value: bufferSnapshot.cursorY)
                                } else if let snapshot = terminalSnapshot, !snapshot.cleanOutputPreview.isEmpty {
                                    // Show static snapshot as fallback
                                    staticSnapshotView(snapshot)
                                } else {
                                    // Show command and working directory info as fallback
                                    commandInfoView
                                }
                            } else {
                                // For exited sessions, show last output if available
                                if let snapshot = terminalSnapshot, !snapshot.cleanOutputPreview.isEmpty {
                                    exitedSessionView(snapshot)
                                } else {
                                    Text("Session exited")
                                        .font(Theme.Typography.terminalSystem(size: 12))
                                        .foregroundColor(Theme.Colors.terminalForeground.opacity(0.5))
                                        .frame(maxWidth: .infinity, maxHeight: .infinity)
                                }
                            }
                        }
                    )

                // Status bar at bottom
                HStack(spacing: Theme.Spacing.small) {
                    // Status indicator
                    HStack(spacing: 4) {
                        Circle()
                            .fill(session.isRunning ? Theme.Colors.successAccent : Theme.Colors.terminalForeground
                                .opacity(0.3)
                            )
                            .frame(width: 6, height: 6)
                        Text(session.isRunning ? "running" : "exited")
                            .font(Theme.Typography.terminalSystem(size: 10))
                            .foregroundColor(session.isRunning ? Theme.Colors.successAccent : Theme.Colors
                                .terminalForeground.opacity(0.5)
                            )

                        // Live preview indicator
                        if session.isRunning && livePreview?.latestSnapshot != nil {
                            HStack(spacing: 2) {
                                Image(systemName: "dot.radiowaves.left.and.right")
                                    .font(.system(size: 8))
                                    .foregroundColor(Theme.Colors.primaryAccent)
                                    .symbolEffect(.pulse)
                                Text("live")
                                    .font(Theme.Typography.terminalSystem(size: 9))
                                    .foregroundColor(Theme.Colors.primaryAccent)
                            }
                            .padding(.horizontal, 6)
                            .padding(.vertical, 2)
                            .background(
                                Capsule()
                                    .fill(Theme.Colors.primaryAccent.opacity(0.1))
                            )
                        }
                    }

                    Spacer()

                    // PID info
                    if session.isRunning, let pid = session.pid {
                        Text("PID: \(pid)")
                            .font(Theme.Typography.terminalSystem(size: 10))
                            .foregroundColor(Theme.Colors.terminalForeground.opacity(0.5))
                            .onTapGesture {
                                UIPasteboard.general.string = String(pid)
                                HapticFeedback.notification(.success)
                            }
                    }
                }
            }
            .padding(Theme.Spacing.medium)
            .background(
                RoundedRectangle(cornerRadius: Theme.CornerRadius.card)
                    .fill(Theme.Colors.cardBackground)
            )
            .overlay(
                RoundedRectangle(cornerRadius: Theme.CornerRadius.card)
                    .stroke(Theme.Colors.cardBorder, lineWidth: 1)
            )
            .scaleEffect(isPressed ? 0.98 : scale)
            .opacity(opacity)
            .rotationEffect(.degrees(rotation))
            .brightness(brightness)
        }
        .buttonStyle(.plain)
        .onLongPressGesture(
            minimumDuration: 0.1,
            maximumDistance: .infinity,
            pressing: { pressing in
                withAnimation(Theme.Animation.quick) {
                    isPressed = pressing
                }
            },
            perform: {}
        )
        .contextMenu {
            if session.isRunning {
                Button(action: animateKill) {
                    Label("Kill Session", systemImage: "stop.circle")
                }
            } else {
                Button(action: animateCleanup) {
                    Label("Clean Up", systemImage: "trash")
                }
            }
        }
        .onAppear {
            loadSnapshot()
        }
    }

    private func loadSnapshot() {
        guard terminalSnapshot == nil else { return }

        isLoadingSnapshot = true
        Task {
            do {
                let snapshot = try await APIClient.shared.getSessionSnapshot(sessionId: session.id)
                await MainActor.run {
                    self.terminalSnapshot = snapshot
                    self.isLoadingSnapshot = false
                }
            } catch {
                // Silently fail - we'll just show the command/cwd fallback
                await MainActor.run {
                    self.isLoadingSnapshot = false
                }
            }
        }
    }

    private func animateKill() {
        guard !isKilling else { return }
        isKilling = true

        // Shake animation
        withAnimation(.linear(duration: 0.05).repeatCount(4, autoreverses: true)) {
            scale = 0.97
        }

        // Fade out after shake
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
            withAnimation(.easeOut(duration: 0.3)) {
                opacity = 0.5
                scale = 0.95
            }
            onKill()

            // Reset after a delay
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                isKilling = false
                withAnimation(.easeIn(duration: 0.2)) {
                    opacity = 1.0
                    scale = 1.0
                }
            }
        }
    }

    private func animateCleanup() {
        // Black hole collapse animation matching web
        withAnimation(.easeInOut(duration: 0.3)) {
            scale = 0
            rotation = 360
            brightness = 0.3
            opacity = 0
        }

        DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
            onCleanup()
            // Reset values for potential reuse
            scale = 1.0
            rotation = 0
            brightness = 1.0
            opacity = 1.0
        }
    }

    // MARK: - View Components

    @ViewBuilder
    private var commandInfoView: some View {
        VStack(alignment: .leading, spacing: 4) {
            HStack(spacing: 4) {
                Text("$")
                    .font(Theme.Typography.terminalSystem(size: 12))
                    .foregroundColor(Theme.Colors.primaryAccent)
                Text(session.command.joined(separator: " "))
                    .font(Theme.Typography.terminalSystem(size: 12))
                    .foregroundColor(Theme.Colors.terminalForeground)
            }

            Text(displayWorkingDir)
                .font(Theme.Typography.terminalSystem(size: 10))
                .foregroundColor(Theme.Colors.terminalForeground.opacity(0.6))
                .lineLimit(1)
                .onTapGesture {
                    UIPasteboard.general.string = session.workingDir
                    HapticFeedback.notification(.success)
                }

            if isLoadingSnapshot {
                HStack {
                    ProgressView()
                        .progressViewStyle(CircularProgressViewStyle(tint: Theme.Colors.primaryAccent))
                        .scaleEffect(0.8)
                    Text("Connecting...")
                        .font(Theme.Typography.terminalSystem(size: 10))
                        .foregroundColor(Theme.Colors.terminalForeground.opacity(0.5))
                }
                .padding(.top, Theme.Spacing.extraSmall)
            }
        }
        .padding(Theme.Spacing.small)
    }

    @ViewBuilder
    private func staticSnapshotView(_ snapshot: TerminalSnapshot) -> some View {
        ScrollView(.vertical, showsIndicators: false) {
            VStack(alignment: .leading, spacing: 4) {
                // ESC indicator if present
                if snapshot.cleanOutputPreview.lowercased().contains("esc to interrupt") {
                    HStack(spacing: 4) {
                        Image(systemName: "escape")
                            .font(.system(size: 10, weight: .bold))
                            .foregroundColor(Theme.Colors.warningAccent)
                        Text("Press ESC to interrupt")
                            .font(Theme.Typography.terminalSystem(size: 10))
                            .foregroundColor(Theme.Colors.warningAccent)
                    }
                    .padding(.horizontal, 8)
                    .padding(.vertical, 4)
                    .background(
                        RoundedRectangle(cornerRadius: 4)
                            .fill(Theme.Colors.warningAccent.opacity(0.2))
                    )
                }

                Text(snapshot.cleanOutputPreview)
                    .font(Theme.Typography.terminalSystem(size: 10))
                    .foregroundColor(Theme.Colors.terminalForeground.opacity(0.8))
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .lineLimit(nil)
                    .multilineTextAlignment(.leading)
            }
        }
        .padding(Theme.Spacing.small)
    }

    @ViewBuilder
    private func exitedSessionView(_ snapshot: TerminalSnapshot) -> some View {
        ScrollView(.vertical, showsIndicators: false) {
            VStack(alignment: .leading, spacing: 4) {
                Text("Session exited")
                    .font(Theme.Typography.terminalSystem(size: 10))
                    .foregroundColor(Theme.Colors.errorAccent)
                Text(snapshot.cleanOutputPreview)
                    .font(Theme.Typography.terminalSystem(size: 10))
                    .foregroundColor(Theme.Colors.terminalForeground.opacity(0.6))
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .lineLimit(nil)
                    .multilineTextAlignment(.leading)
            }
        }
        .padding(Theme.Spacing.small)
    }
}
