'use client';

import { useState, useCallback } from 'react';
import {
  PlayCircle,
  CheckCircle,
  XCircle,
  Loader2,
  ArrowRight,
  RefreshCw,
} from 'lucide-react';
import { apiService, type ApiTestResult } from '@/services/api.service';

interface TestStep {
  name: string;
  description: string;
  status: 'pending' | 'running' | 'pass' | 'fail';
  latency?: number;
  error?: string;
}

const INITIAL_STEPS: TestStep[] = [
  { name: 'Register', description: 'Test user registration endpoint', status: 'pending' },
  { name: 'Database Insert', description: 'Verify database write operation', status: 'pending' },
  { name: 'Login', description: 'Test user authentication', status: 'pending' },
  { name: 'JWT', description: 'Verify JWT token generation', status: 'pending' },
  { name: 'Dashboard', description: 'Access user dashboard', status: 'pending' },
  { name: 'Wallet', description: 'Verify wallet balance retrieval', status: 'pending' },
  { name: 'Create Order', description: 'Test order creation flow', status: 'pending' },
  { name: 'Database Updated', description: 'Verify database update after order', status: 'pending' },
  { name: 'Order History Updated', description: 'Check order history reflects changes', status: 'pending' },
  { name: 'Notification Generated', description: 'Verify notification was created', status: 'pending' },
  { name: 'Profile Update', description: 'Test profile update operation', status: 'pending' },
  { name: 'Logout', description: 'Test session termination', status: 'pending' },
];

export function ApplicationTester() {
  const [steps, setSteps] = useState<TestStep[]>(INITIAL_STEPS);
  const [isRunning, setIsRunning] = useState(false);
  const [startTime, setStartTime] = useState<number | null>(null);
  const [elapsed, setElapsed] = useState(0);

  const testEmail = `test+${Date.now()}@example.com`;
  const testPassword = 'TestPass123!';

  const runStep = async (index: number): Promise<TestStep> => {
    const step = { ...INITIAL_STEPS[index] };
    step.status = 'running';

    const start = performance.now();
    
    try {
      let result: ApiTestResult;
      
      switch (index) {
        case 0: // Register
          result = await apiService.testPost('/auth/register', { email: testEmail, password: testPassword, firstName: 'Test', lastName: 'User' }, 'POST /auth/register');
          break;
        case 1: // Database Insert
          result = await apiService.testGet('/health/database', 'GET /health/database');
          break;
        case 2: // Login
          result = await apiService.testPost('/auth/login', { email: testEmail, password: testPassword }, 'POST /auth/login');
          break;
        case 3: // JWT
          result = await apiService.testGet('/health', 'GET /health');
          break;
        case 4: // Dashboard
          result = await apiService.testGet('/dashboard', 'GET /dashboard');
          break;
        case 5: // Wallet
          result = await apiService.testGet('/wallet', 'GET /wallet');
          break;
        case 6: // Create Order
          result = await apiService.testPost('/orders', { amount: 100, type: 'BUY' }, 'POST /orders');
          break;
        case 7: // Database Updated
          result = await apiService.testGet('/health/database', 'GET /health/database');
          break;
        case 8: // Order History Updated
          result = await apiService.testGet('/orders', 'GET /orders');
          break;
        case 9: // Notification Generated
          result = await apiService.testGet('/notifications', 'GET /notifications');
          break;
        case 10: // Profile Update
          result = await apiService.testPost('/users/profile', { name: 'Test User' }, 'POST /users/profile');
          break;
        case 11: // Logout
          result = await apiService.testPost('/auth/logout', {}, 'POST /auth/logout');
          break;
        default:
          result = { endpoint: '', method: '', status: 'FAIL', statusCode: null, latency: 0, error: 'Unknown step' };
      }

      const latency = Math.round(performance.now() - start);
      step.status = result.status === 'PASS' ? 'pass' : 'fail';
      step.latency = latency;
      step.error = result.error;
    } catch (err: any) {
      const latency = Math.round(performance.now() - start);
      step.status = 'fail';
      step.latency = latency;
      step.error = err?.message ?? 'Step failed';
    }

    return step;
  };

  const runSystemTest = useCallback(async () => {
    setIsRunning(true);
    setStartTime(Date.now());
    setElapsed(0);

    const timer = setInterval(() => {
      setElapsed((prev) => prev + 100);
    }, 100);

    const newSteps: TestStep[] = [...INITIAL_STEPS];

    for (let i = 0; i < newSteps.length; i++) {
      newSteps[i] = { ...newSteps[i], status: 'running' };
      setSteps([...newSteps]);
      
      const result = await runStep(i);
      newSteps[i] = result;
      setSteps([...newSteps]);

      // If critical step fails, break early
      if (result.status === 'fail') {
        // Mark remaining as skipped
        for (let j = i + 1; j < newSteps.length; j++) {
          newSteps[j] = { ...newSteps[j], status: 'pending', error: 'Skipped due to previous failure' };
        }
        setSteps([...newSteps]);
        break;
      }
    }

    clearInterval(timer);
    setIsRunning(false);
  }, []);

  const reset = () => {
    setSteps(INITIAL_STEPS);
    setStartTime(null);
    setElapsed(0);
  };

  const passCount = steps.filter((s) => s.status === 'pass').length;
  const failCount = steps.filter((s) => s.status === 'fail').length;
  const isComplete = steps.every((s) => s.status !== 'pending' && s.status !== 'running');
  const isPassing = passCount > 0 && failCount === 0 && isComplete;

  return (
    <div className="rounded-xl border border-white/5 bg-slate-900/50">
      <div className="flex items-center justify-between border-b border-white/5 px-4 py-3">
        <div className="flex items-center gap-2">
          <PlayCircle className="h-4 w-4 text-purple-400" />
          <h3 className="text-xs font-semibold text-white">Complete System Test</h3>
          {isComplete && (
            <span className={`rounded px-1.5 py-0.5 text-[9px] font-mono font-medium ${
              isPassing ? 'bg-emerald-500/10 text-emerald-400' : 'bg-red-500/10 text-red-400'
            }`}>
              {isPassing ? 'ALL PASSED' : 'FAILURES DETECTED'}
            </span>
          )}
        </div>
        <div className="flex items-center gap-2">
          {startTime && (
            <span className="text-[10px] font-mono text-slate-500">
              {(elapsed / 1000).toFixed(1)}s
            </span>
          )}
          <button
            onClick={isRunning ? undefined : isComplete ? reset : runSystemTest}
            disabled={isRunning}
            className="flex items-center gap-1.5 rounded-lg bg-purple-500/10 px-3 py-1.5 text-xs font-medium text-purple-400 hover:bg-purple-500/20 transition-colors disabled:opacity-50"
          >
            {isRunning ? (
              <>
                <Loader2 className="h-3.5 w-3.5 animate-spin" />
                Running...
              </>
            ) : isComplete ? (
              <>
                <RefreshCw className="h-3.5 w-3.5" />
                Reset
              </>
            ) : (
              <>
                <PlayCircle className="h-3.5 w-3.5" />
                Run Complete System Test
              </>
            )}
          </button>
        </div>
      </div>

      <div className="p-4">
        {/* Flow Visualization */}
        <div className="mb-4 flex flex-wrap items-center gap-1">
          {steps.map((step, i) => (
            <div key={step.name} className="flex items-center">
              <div className={`flex items-center gap-1 rounded-lg border px-2 py-1 text-[9px] font-mono ${
                step.status === 'pass' ? 'border-emerald-500/20 bg-emerald-500/5 text-emerald-400' :
                step.status === 'fail' ? 'border-red-500/20 bg-red-500/5 text-red-400' :
                step.status === 'running' ? 'border-amber-500/20 bg-amber-500/5 text-amber-400 animate-pulse' :
                'border-white/5 bg-white/[0.02] text-slate-500'
              }`}>
                {step.status === 'pass' ? <CheckCircle className="h-3 w-3" /> :
                 step.status === 'fail' ? <XCircle className="h-3 w-3" /> :
                 step.status === 'running' ? <Loader2 className="h-3 w-3 animate-spin" /> :
                 null}
                <span>{i + 1}</span>
              </div>
              {i < steps.length - 1 && (
                <ArrowRight className="h-3 w-3 text-slate-700 mx-0.5" />
              )}
            </div>
          ))}
        </div>

        {/* Step Details */}
        <div className="space-y-1">
          {steps.map((step, i) => (
            <div
              key={step.name}
              className={`flex items-center justify-between rounded-lg border px-3 py-2 transition-all ${
                step.status === 'pass' ? 'border-emerald-500/10 bg-emerald-500/[0.02]' :
                step.status === 'fail' ? 'border-red-500/10 bg-red-500/[0.02]' :
                step.status === 'running' ? 'border-amber-500/10 bg-amber-500/[0.02]' :
                'border-white/5 bg-white/[0.02]'
              }`}
            >
              <div className="flex items-center gap-2.5">
                <span className={`flex h-5 w-5 items-center justify-center rounded text-[9px] font-bold font-mono ${
                  step.status === 'pass' ? 'bg-emerald-500/20 text-emerald-400' :
                  step.status === 'fail' ? 'bg-red-500/20 text-red-400' :
                  step.status === 'running' ? 'bg-amber-500/20 text-amber-400' :
                  'bg-slate-500/20 text-slate-500'
                }`}>
                  {i + 1}
                </span>
                <div>
                  <p className={`text-xs font-medium ${
                    step.status === 'pass' ? 'text-emerald-300' :
                    step.status === 'fail' ? 'text-red-300' :
                    step.status === 'running' ? 'text-amber-300' :
                    'text-slate-400'
                  }`}>
                    {step.name}
                  </p>
                  <p className="text-[9px] text-slate-500">{step.description}</p>
                </div>
              </div>
              <div className="flex items-center gap-2">
                {step.error && (
                  <span className="hidden md:block text-[9px] text-red-400 max-w-[200px] truncate">{step.error}</span>
                )}
                {step.latency !== undefined && (
                  <span className="text-[9px] font-mono text-slate-500">{step.latency}ms</span>
                )}
                <span className={`rounded px-1.5 py-0.5 text-[9px] font-mono font-medium ${
                  step.status === 'pass' ? 'bg-emerald-500/10 text-emerald-400' :
                  step.status === 'fail' ? 'bg-red-500/10 text-red-400' :
                  step.status === 'running' ? 'bg-amber-500/10 text-amber-400' :
                  'bg-slate-500/10 text-slate-500'
                }`}>
                  {step.status === 'pass' ? 'PASS' :
                   step.status === 'fail' ? 'FAIL' :
                   step.status === 'running' ? 'TESTING...' :
                   'PENDING'}
                </span>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}
