'use client';
import { useEffect, useMemo, useRef, useState } from 'react';

import { apiFetch } from '../lib/api';

interface CodingChallengeState {
  id: number;
  order: number;
  title: string;
  prompt: string;
  starter_code: string | null;
  is_passed: boolean;
  is_unlocked: boolean;
  last_submitted_code: string | null;
  last_stdout: string | null;
  last_stderr: string | null;
  last_exit_code: number | null;
  updated_at: string | null;
}

interface CodingMissionState {
  mission_id: number;
  total_challenges: number;
  completed_challenges: number;
  current_challenge_id: number | null;
  is_mission_completed: boolean;
  challenges: CodingChallengeState[];
}

interface CodingMissionPanelProps {
  missionId: number;
  token?: string;
  initialState: CodingMissionState | null;
  initialCompleted?: boolean;
}

interface RunResult {
  stdout: string;
  stderr: string;
  exit_code: number;
  is_passed: boolean;
  mission_completed: boolean;
  expected_output?: string | null;
}

export function CodingMissionPanel({ missionId, token, initialState, initialCompleted = false }: CodingMissionPanelProps) {
  const [state, setState] = useState<CodingMissionState | null>(initialState);
  const [missionCompleted, setMissionCompleted] = useState(initialState?.is_mission_completed || initialCompleted);
  const [editorCode, setEditorCode] = useState<string>('');
  const [status, setStatus] = useState<string | null>(null);
  const [runResult, setRunResult] = useState<RunResult | null>(null);
  const [loading, setLoading] = useState(false);
  const previousChallengeIdRef = useRef<number | null>(null);


  const activeChallenge = useMemo(() => {
    if (!state || !state.challenges.length) {
      return null;
    }
    if (state.current_challenge_id) {
      const current = state.challenges.find((challenge) => challenge.id === state.current_challenge_id);
      if (current) {
        return current;
      }
    }

    const nextUnlocked = state.challenges.find((challenge) => challenge.is_unlocked && !challenge.is_passed);
    if (nextUnlocked) {
      return nextUnlocked;
    }

    const firstIncomplete = state.challenges.find((challenge) => !challenge.is_passed);
    if (firstIncomplete) {
      return firstIncomplete;
    }

    return state.challenges[state.challenges.length - 1];
  }, [state]);

  useEffect(() => {
    if (!state) {
      return;
    }
    setMissionCompleted(state.is_mission_completed);
  }, [state]);

  useEffect(() => {
    if (!activeChallenge) {
      previousChallengeIdRef.current = null;
      return;
    }

    if (previousChallengeIdRef.current === activeChallenge.id) {
      return;
    }

    previousChallengeIdRef.current = activeChallenge.id;
    const baseCode = activeChallenge.last_submitted_code ?? activeChallenge.starter_code ?? '';
    setEditorCode(baseCode);
    setRunResult(null);
    setStatus(null);
  }, [activeChallenge]);

  if (!state) {
    return (
      <div className="card" style={{ marginTop: '2rem' }}>
        <p>
          Не удалось загрузить задания для миссии. Попробуйте обновить страницу или обратитесь к HR, чтобы
          проверить настройки миссии.
        </p>
      </div>
    );
  }

  const handleRefresh = async () => {
    if (!token) {
      return;
    }
    try {
      const updated = await apiFetch<CodingMissionState>(`/api/missions/${missionId}/coding/challenges`, {
        authToken: token
      });
      setState(updated);
    } catch (error) {
      if (error instanceof Error) {
        setStatus(error.message);
      }
    }
  };

  const handleRun = async () => {
    if (!token) {
      setStatus('Не удалось получить токен авторизации. Перезайдите в систему.');
      return;
    }
    if (!activeChallenge) {
      setStatus('Все задания выполнены — можно переходить к другим миссиям.');
      return;
    }
    if (!editorCode.trim()) {
      setStatus('Добавьте решение в редакторе, прежде чем запускать проверку.');
      return;
    }

    try {
      setLoading(true);
      setStatus(null);
      const result = await apiFetch<RunResult>(
        `/api/missions/${missionId}/coding/challenges/${activeChallenge.id}/run`,
        {
          method: 'POST',
          body: JSON.stringify({ code: editorCode }),
          authToken: token
        }
      );
      setRunResult(result);
      setMissionCompleted(result.mission_completed);
      setStatus(
        result.is_passed
          ? 'Отлично! Задание пройдено. Можно переходить к следующему шагу.'
          : 'Проверка не пройдена. Сверьтесь с выводом программы и подсказками.'
      );
      await handleRefresh();
    } catch (error) {
      if (error instanceof Error) {
        setStatus(error.message);
      } else {
        setStatus('Неожиданная ошибка при выполнении проверки. Попробуйте повторить позже.');
      }
    } finally {
      setLoading(false);
    }
  };

  return (
    <div style={{ marginTop: '2rem', display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>
      {state.challenges.map((challenge) => {
        const isActive = activeChallenge?.id === challenge.id && !missionCompleted;
        return (
          <div key={challenge.id} className="card" style={{ border: challenge.is_passed ? '1px solid rgba(85,239,196,0.4)' : undefined }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
              <h3 style={{ marginBottom: '0.25rem' }}>
                {challenge.order}. {challenge.title}
              </h3>
              {challenge.is_passed && <span style={{ color: '#55efc4' }}>✓ Готово</span>}
            </div>
            <p style={{ color: 'var(--text-muted)' }}>{challenge.prompt}</p>
            {!challenge.is_unlocked && !challenge.is_passed && (
              <p style={{ marginTop: '0.75rem', color: 'var(--text-muted)' }}>
                🔒 Задание откроется после успешного решения предыдущих пунктов.
              </p>
            )}
            {challenge.is_passed && challenge.last_stdout && (
              <div style={{ marginTop: '0.75rem' }}>
                <small style={{ color: 'var(--text-muted)' }}>Последний вывод программы:</small>
                <pre style={{ background: 'rgba(99, 110, 114, 0.2)', padding: '0.75rem', borderRadius: '12px', overflowX: 'auto' }}>
                  {challenge.last_stdout}
                </pre>
              </div>
            )}
            {isActive && (
              <div style={{ marginTop: '1rem', display: 'flex', flexDirection: 'column', gap: '1rem' }}>
                <label>
                  <span style={{ display: 'block', marginBottom: '0.5rem' }}>Редактор кода</span>
                  <textarea
                    value={editorCode}
                    onChange={(event) => setEditorCode(event.target.value)}
                    rows={12}
                    style={{ width: '100%', borderRadius: '12px', padding: '0.75rem', fontFamily: 'monospace' }}
                    disabled={loading || missionCompleted}
                  />
                </label>
                <button
                  type="button"
                  className="primary"
                  onClick={handleRun}
                  disabled={loading || missionCompleted}
                >
                  {missionCompleted ? 'Миссия завершена' : loading ? 'Выполняем код...' : 'Проверить'}
                </button>
                {status && (
                  <p
                    style={{
                      marginTop: '-0.25rem',
                      color: status.startsWith('Отлично') ? 'var(--accent-light)' : status.includes('Проверка') ? 'var(--error)' : 'var(--text-muted)'
                    }}
                  >
                    {status}
                  </p>
                )}
                {runResult && (
                  <div>
                    <details open>
                      <summary style={{ cursor: 'pointer', color: 'var(--accent)' }}>Результат последнего запуска</summary>
                      <div style={{ marginTop: '0.5rem' }}>
                        <strong>stdout:</strong>
                        <pre style={{ background: 'rgba(108, 92, 231, 0.15)', padding: '0.75rem', borderRadius: '12px', overflowX: 'auto' }}>
                          {runResult.stdout || '<пусто>'}
                        </pre>
                        <strong>stderr:</strong>
                        <pre style={{ background: 'rgba(225, 112, 85, 0.15)', padding: '0.75rem', borderRadius: '12px', overflowX: 'auto' }}>
                          {runResult.stderr || '<пусто>'}
                        </pre>
                        <p style={{ marginTop: '0.5rem', color: 'var(--text-muted)' }}>
                          Код завершился с статусом {runResult.exit_code}.
                        </p>
                        {runResult.expected_output && (
                          <div style={{ marginTop: '0.5rem' }}>
                            <strong>Ожидаемый вывод:</strong>
                            <pre style={{ background: 'rgba(99, 110, 114, 0.2)', padding: '0.75rem', borderRadius: '12px', overflowX: 'auto' }}>
                              {runResult.expected_output}
                            </pre>
                          </div>
                        )}
                      </div>
                    </details>
                  </div>
                )}
              </div>
            )}
          </div>
        );
      })}
      {missionCompleted && (
        <div className="card" style={{ border: '1px solid rgba(85,239,196,0.35)', background: 'rgba(85,239,196,0.12)' }}>
          <h3>Все задания выполнены!</h3>
          <p style={{ marginTop: '0.5rem', color: 'var(--text-muted)' }}>
            Система уже зачислила опыт и ману за миссию. Можно вернуться к списку миссий и выбрать следующее испытание.
          </p>
        </div>
      )}
    </div>
  );
}

