'use client';

import { useState } from 'react';
import {
  AlertTriangle,
  AlertOctagon,
  Zap,
  Clock,
  TrendingUp,
  ChevronDown,
  ChevronUp,
  RefreshCw,
  Wrench,
  Lightbulb,
  Activity,
  MemoryStick,
  Boxes,
} from 'lucide-react';
import type { StructuredLog } from './index';

// Crash analysis types
interface CrashAnalysis {
  pattern: string;
  confidence: number;
  description: string;
  suggested_fix: string;
  auto_fix_params?: Record<string, any>;
}

interface MetricsHistoryEntry {
  timestamp_ms: number;
  memory_mb: number;
  dom_nodes: number;
}

export interface CrashReportData {
  crash_id: string;
  crash_type: string;
  error_message: string;
  analysis: CrashAnalysis;
  metrics_history?: MetricsHistoryEntry[];
  logs_before_crash?: StructuredLog[];
  created_at: string;
}

export interface CrashReportProps {
  jobId: string;
  crashReport: CrashReportData;
  onRetry?: (applyFix: boolean) => void;
}

// Pattern icons mapping
const PATTERN_ICONS: Record<string, typeof AlertTriangle> = {
  memory_exhaustion: MemoryStick,
  dom_explosion: Boxes,
  timeout: Clock,
  network_failure: Zap,
  rate_limited: AlertOctagon,
  default: AlertTriangle,
};

// Crash type severity colors
const CRASH_TYPE_COLORS: Record<string, { bg: string; border: string; text: string; icon: string }> = {
  memory_exhaustion: { bg: 'bg-red-900', border: 'border-red-600', text: 'text-red-200', icon: 'text-red-400' },
  dom_explosion: { bg: 'bg-orange-900', border: 'border-orange-600', text: 'text-orange-200', icon: 'text-orange-400' },
  timeout: { bg: 'bg-yellow-900', border: 'border-yellow-600', text: 'text-yellow-200', icon: 'text-yellow-400' },
  network_failure: { bg: 'bg-purple-900', border: 'border-purple-600', text: 'text-purple-200', icon: 'text-purple-400' },
  rate_limited: { bg: 'bg-blue-900', border: 'border-blue-600', text: 'text-blue-200', icon: 'text-blue-400' },
  default: { bg: 'bg-red-900', border: 'border-red-600', text: 'text-red-200', icon: 'text-red-400' },
};

// Log level colors for the logs section
const LEVEL_BADGE_COLORS: Record<string, string> = {
  DEBUG: 'bg-gray-600 text-gray-200',
  INFO: 'bg-blue-600 text-blue-100',
  WARN: 'bg-yellow-600 text-yellow-100',
  ERROR: 'bg-red-600 text-red-100',
  FATAL: 'bg-purple-600 text-purple-100',
};

export default function CrashReport({ jobId, crashReport, onRetry }: CrashReportProps) {
  const [isLogsExpanded, setIsLogsExpanded] = useState(false);
  const [isRetrying, setIsRetrying] = useState(false);
  const [retryError, setRetryError] = useState<string | null>(null);

  const { crash_type, error_message, analysis, metrics_history, logs_before_crash, created_at } = crashReport;

  // Get styling for crash type
  const crashColors = CRASH_TYPE_COLORS[crash_type] || CRASH_TYPE_COLORS.default;
  const PatternIcon = PATTERN_ICONS[analysis.pattern] || PATTERN_ICONS.default;

  // Format timestamp
  const formatTimestamp = (timestamp: string) => {
    try {
      const date = new Date(timestamp);
      return date.toLocaleString('en-US', {
        month: 'short',
        day: 'numeric',
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit',
        hour12: false,
      });
    } catch {
      return timestamp;
    }
  };

  const formatLogTimestamp = (timestamp: string) => {
    try {
      const date = new Date(timestamp);
      return date.toLocaleTimeString('en-US', {
        hour12: false,
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit',
        fractionalSecondDigits: 3,
      });
    } catch {
      return timestamp;
    }
  };

  // Get confidence color
  const getConfidenceColor = (confidence: number) => {
    if (confidence >= 0.8) return 'bg-green-600 text-green-100';
    if (confidence >= 0.5) return 'bg-yellow-600 text-yellow-100';
    return 'bg-orange-600 text-orange-100';
  };

  // Mini timeline visualization
  const renderMetricsTimeline = () => {
    if (!metrics_history || metrics_history.length < 2) {
      return (
        <div className="text-gray-500 text-sm text-center py-4">
          No metrics history available
        </div>
      );
    }

    const memoryValues = metrics_history.map((m) => m.memory_mb);
    const maxMemory = Math.max(...memoryValues);
    const minMemory = Math.min(...memoryValues);
    const range = maxMemory - minMemory || 1;

    // Calculate points for SVG path
    const width = 100;
    const height = 40;
    const points = metrics_history.map((entry, index) => {
      const x = (index / (metrics_history.length - 1)) * width;
      const y = height - ((entry.memory_mb - minMemory) / range) * height;
      return `${x},${y}`;
    });

    const pathD = `M ${points.join(' L ')}`;

    return (
      <div className="space-y-2">
        <div className="flex items-center justify-between text-xs text-gray-400">
          <span className="flex items-center gap-1">
            <Activity className="w-3 h-3" />
            Memory Usage Over Time
          </span>
          <span>{maxMemory.toFixed(0)}MB peak</span>
        </div>
        <div className="relative h-12 bg-gray-800 rounded border border-gray-700 overflow-hidden">
          <svg
            viewBox={`0 0 ${width} ${height}`}
            className="w-full h-full"
            preserveAspectRatio="none"
          >
            {/* Gradient fill under the line */}
            <defs>
              <linearGradient id="memoryGradient" x1="0" x2="0" y1="0" y2="1">
                <stop offset="0%" stopColor="rgb(239, 68, 68)" stopOpacity="0.4" />
                <stop offset="100%" stopColor="rgb(239, 68, 68)" stopOpacity="0" />
              </linearGradient>
            </defs>
            {/* Fill area */}
            <path
              d={`${pathD} L ${width},${height} L 0,${height} Z`}
              fill="url(#memoryGradient)"
            />
            {/* Line */}
            <path
              d={pathD}
              fill="none"
              stroke="rgb(239, 68, 68)"
              strokeWidth="2"
              vectorEffect="non-scaling-stroke"
            />
            {/* Crash point indicator */}
            <circle
              cx={width}
              cy={height - ((memoryValues[memoryValues.length - 1] - minMemory) / range) * height}
              r="4"
              fill="rgb(239, 68, 68)"
              stroke="white"
              strokeWidth="1"
            />
          </svg>
          {/* Crash indicator */}
          <div className="absolute right-1 top-1 px-1.5 py-0.5 bg-red-600 text-white text-xs rounded font-medium">
            CRASH
          </div>
        </div>
        <div className="flex justify-between text-xs text-gray-500">
          <span>{minMemory.toFixed(0)}MB</span>
          <span>{metrics_history.length} data points</span>
        </div>
      </div>
    );
  };

  // Handle retry with/without fix
  const handleRetry = async (applyFix: boolean) => {
    setIsRetrying(true);
    setRetryError(null);

    try {
      const response = await fetch(`/api/jobs/${jobId}/retry?apply_fix=${applyFix}`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
      });

      if (!response.ok) {
        const data = await response.json().catch(() => ({}));
        throw new Error(data.error || data.message || `Retry failed with status ${response.status}`);
      }

      // Call the onRetry callback if provided
      if (onRetry) {
        onRetry(applyFix);
      }
    } catch (err) {
      setRetryError(err instanceof Error ? err.message : 'Failed to retry job');
    } finally {
      setIsRetrying(false);
    }
  };

  return (
    <div className="w-full bg-gray-900 rounded-xl border-2 border-red-800 overflow-hidden">
      {/* Header */}
      <div className={`${crashColors.bg} ${crashColors.border} border-b-2 px-4 py-3`}>
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-3">
            <div className={`p-2 rounded-lg bg-gray-900/50 ${crashColors.icon}`}>
              <AlertOctagon className="w-6 h-6" />
            </div>
            <div>
              <h3 className={`font-bold text-lg ${crashColors.text}`}>
                {crash_type.replace(/_/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase())}
              </h3>
              <p className="text-gray-400 text-sm">{error_message}</p>
            </div>
          </div>
          <div className="text-right">
            <div className="flex items-center gap-1.5 text-gray-400 text-sm">
              <Clock className="w-4 h-4" />
              {formatTimestamp(created_at)}
            </div>
          </div>
        </div>
      </div>

      {/* Content */}
      <div className="p-4 space-y-4">
        {/* Timeline to Crash */}
        <div className="bg-gray-800 rounded-lg border border-gray-700 p-4">
          <h4 className="text-gray-300 font-semibold mb-3 flex items-center gap-2">
            <TrendingUp className="w-4 h-4 text-gray-400" />
            Timeline to Crash
          </h4>
          {renderMetricsTimeline()}
        </div>

        {/* Pattern Analysis */}
        <div className="bg-gray-800 rounded-lg border border-gray-700 p-4">
          <h4 className="text-gray-300 font-semibold mb-3 flex items-center gap-2">
            <PatternIcon className="w-4 h-4 text-gray-400" />
            Pattern Analysis
          </h4>

          <div className="space-y-3">
            {/* Pattern name with confidence */}
            <div className="flex items-center gap-3">
              <span className="text-white font-medium">
                {analysis.pattern.replace(/_/g, ' ')}
              </span>
              <span
                className={`px-2 py-0.5 text-xs font-semibold rounded ${getConfidenceColor(analysis.confidence)}`}
              >
                {Math.round(analysis.confidence * 100)}% confidence
              </span>
            </div>

            {/* Confidence bar */}
            <div className="w-full h-2 bg-gray-700 rounded-full overflow-hidden">
              <div
                className={`h-full transition-all ${
                  analysis.confidence >= 0.8
                    ? 'bg-green-500'
                    : analysis.confidence >= 0.5
                    ? 'bg-yellow-500'
                    : 'bg-orange-500'
                }`}
                style={{ width: `${analysis.confidence * 100}%` }}
              />
            </div>

            {/* Description */}
            <p className="text-gray-400 text-sm">{analysis.description}</p>

            {/* Suggested fix callout */}
            <div className="bg-blue-900/30 border border-blue-700 rounded-lg p-3 mt-3">
              <div className="flex items-start gap-2">
                <Lightbulb className="w-5 h-5 text-blue-400 flex-shrink-0 mt-0.5" />
                <div>
                  <span className="text-blue-300 font-medium text-sm">Suggested Fix</span>
                  <p className="text-blue-200 text-sm mt-1">{analysis.suggested_fix}</p>
                </div>
              </div>
            </div>
          </div>
        </div>

        {/* Auto-Fix Options */}
        {analysis.auto_fix_params && Object.keys(analysis.auto_fix_params).length > 0 && (
          <div className="bg-gray-800 rounded-lg border border-gray-700 p-4">
            <h4 className="text-gray-300 font-semibold mb-3 flex items-center gap-2">
              <Wrench className="w-4 h-4 text-gray-400" />
              Auto-Fix Parameters
            </h4>
            <div className="space-y-2">
              {Object.entries(analysis.auto_fix_params).map(([key, value]) => (
                <div
                  key={key}
                  className="flex items-center justify-between py-2 px-3 bg-gray-700/50 rounded"
                >
                  <span className="text-gray-400 text-sm font-mono">{key}</span>
                  <span className="text-green-400 text-sm font-mono">
                    {typeof value === 'object' ? JSON.stringify(value) : String(value)}
                  </span>
                </div>
              ))}
            </div>
          </div>
        )}

        {/* Retry buttons */}
        <div className="flex items-center gap-3 pt-2">
          <button
            onClick={() => handleRetry(true)}
            disabled={isRetrying || !analysis.auto_fix_params}
            className={`flex items-center gap-2 px-4 py-2.5 rounded-lg font-medium transition-all ${
              isRetrying || !analysis.auto_fix_params
                ? 'bg-gray-700 text-gray-500 cursor-not-allowed'
                : 'bg-green-600 hover:bg-green-500 text-white'
            }`}
          >
            {isRetrying ? (
              <RefreshCw className="w-4 h-4 animate-spin" />
            ) : (
              <Wrench className="w-4 h-4" />
            )}
            Apply Fix & Retry
          </button>
          <button
            onClick={() => handleRetry(false)}
            disabled={isRetrying}
            className={`flex items-center gap-2 px-4 py-2.5 rounded-lg font-medium transition-all ${
              isRetrying
                ? 'bg-gray-700 text-gray-500 cursor-not-allowed'
                : 'bg-gray-700 hover:bg-gray-600 text-gray-300 border border-gray-600'
            }`}
          >
            {isRetrying ? (
              <RefreshCw className="w-4 h-4 animate-spin" />
            ) : (
              <RefreshCw className="w-4 h-4" />
            )}
            Retry Without Fix
          </button>
        </div>

        {/* Retry error message */}
        {retryError && (
          <div className="bg-red-900/30 border border-red-700 rounded-lg p-3 text-red-300 text-sm">
            {retryError}
          </div>
        )}

        {/* Logs Before Crash */}
        {logs_before_crash && logs_before_crash.length > 0 && (
          <div className="bg-gray-800 rounded-lg border border-gray-700 overflow-hidden">
            <button
              onClick={() => setIsLogsExpanded(!isLogsExpanded)}
              className="w-full flex items-center justify-between px-4 py-3 hover:bg-gray-750 transition-colors"
            >
              <span className="text-gray-300 font-semibold flex items-center gap-2">
                <AlertTriangle className="w-4 h-4 text-gray-400" />
                Logs Before Crash
                <span className="px-2 py-0.5 text-xs bg-gray-700 text-gray-400 rounded-full">
                  {logs_before_crash.length}
                </span>
              </span>
              {isLogsExpanded ? (
                <ChevronUp className="w-5 h-5 text-gray-400" />
              ) : (
                <ChevronDown className="w-5 h-5 text-gray-400" />
              )}
            </button>

            {isLogsExpanded && (
              <div className="border-t border-gray-700 max-h-[300px] overflow-y-auto">
                <div className="font-mono text-sm">
                  {logs_before_crash.slice(-20).map((log, index) => (
                    <div
                      key={`${log.timestamp_ms}-${index}`}
                      className={`px-4 py-2 border-b border-gray-700/50 hover:bg-gray-700/30 ${
                        log.level === 'ERROR' || log.level === 'FATAL'
                          ? 'bg-red-900/20'
                          : log.level === 'WARN'
                          ? 'bg-yellow-900/10'
                          : ''
                      }`}
                    >
                      <div className="flex items-start gap-3">
                        <span className="text-gray-500 text-xs whitespace-nowrap pt-0.5">
                          {formatLogTimestamp(log.timestamp)}
                        </span>
                        <span
                          className={`px-1.5 py-0.5 text-xs font-semibold rounded ${
                            LEVEL_BADGE_COLORS[log.level] || LEVEL_BADGE_COLORS.INFO
                          } whitespace-nowrap`}
                        >
                          {log.level}
                        </span>
                        <span className="px-1.5 py-0.5 text-xs font-medium rounded bg-gray-700 text-gray-300 whitespace-nowrap">
                          {log.category}
                        </span>
                        <span className="flex-1 text-gray-300 break-words">
                          {log.message}
                        </span>
                      </div>
                    </div>
                  ))}
                </div>
              </div>
            )}
          </div>
        )}
      </div>
    </div>
  );
}
