import { useEffect, useState, type FormEvent } from 'react';
import { Link, useNavigate, useParams } from 'react-router-dom';
import { Save, RotateCcw } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import { extractApiError } from '@/api/client';
import type { SimulationPatchInput } from '@/api/types';
import { useAuth } from '@/hooks/useAuth';
import { useToast } from '@/hooks/useToast';
import {
  useCreateSimulation,
  useDeleteSimulation,
  useSimulation,
  useTransitionSimulation,
  useUpdateSimulation,
} from '@/hooks/useSimulations';
import { useC2Config, useC2Tasks } from '@/hooks/useC2';
import { FormField, TextArea, TextInput } from '@/components/FormField';
import { LoadingState } from '@/components/LoadingState';
import { ErrorState } from '@/components/ErrorState';
import { SimulationStatusBadge } from '@/components/SimulationStatusBadge';
import { ConfirmDialog } from '@/components/ConfirmDialog';
import { MitreTechniquesField } from '@/components/MitreTechniquesField';
import { ExecuteViaC2Modal } from '@/components/ExecuteViaC2Modal';
import { ImportC2HistoryModal } from '@/components/ImportC2HistoryModal';
import { C2TasksPanel } from '@/components/C2TasksPanel';
import { AlertBanner } from '@/components/AlertBanner';
import { BackLink } from '@/components/BackLink';

interface RedteamFormState {
  name: string;
  description: string;
  commands: string;
  prerequisites: string;
  executed_at: string;
  execution_result: string;
}

interface SocFormState {
  log_source: string;
  logs: string;
  soc_comment: string;
  incident_number: string;
}

const EMPTY_RT: RedteamFormState = {
  name: '',
  description: '',
  commands: '',
  prerequisites: '',
  executed_at: '',
  execution_result: '',
};

const EMPTY_SOC: SocFormState = {
  log_source: '',
  logs: '',
  soc_comment: '',
  incident_number: '',
};

export function SimulationFormPage(): JSX.Element {
  const { t } = useTranslation();
  const { eid, sid } = useParams<{ eid: string; sid: string }>();
  const engagementId = eid ? Number(eid) : undefined;
  const simulationId = sid ? Number(sid) : undefined;
  const isNew = !simulationId;

  const navigate = useNavigate();
  const { push } = useToast();
  const { isAdmin, isRedteam, isSoc, canEditEngagements } = useAuth();

  const canEditRT = isAdmin || isRedteam;
  const c2ConfigQuery = useC2Config(
    !isNew && typeof engagementId === 'number' ? engagementId : undefined,
    { enabled: !isNew && canEditRT },
  );
  const hasC2Config = c2ConfigQuery.data !== null && c2ConfigQuery.data !== undefined;

  const c2TasksQuery = useC2Tasks(!isNew ? simulationId : undefined, {
    enabled: !isNew && canEditRT,
  });
  const hasTasks = (c2TasksQuery.data?.tasks?.length ?? 0) > 0;
  // Show panel when: has C2 config (so Execute button is visible) OR already has tasks
  const showTasksPanel = !isNew && canEditRT && (hasC2Config || hasTasks);

  const detail = useSimulation(isNew ? undefined : simulationId);
  const createMutation = useCreateSimulation(engagementId ?? 0);
  const updateMutation = useUpdateSimulation(simulationId ?? 0, engagementId ?? 0);
  const deleteMutation = useDeleteSimulation(engagementId ?? 0);
  const transitionMutation = useTransitionSimulation(simulationId ?? 0, engagementId ?? 0);

  const [rt, setRt] = useState<RedteamFormState>(EMPTY_RT);
  const [soc, setSoc] = useState<SocFormState>(EMPTY_SOC);
  const [nameError, setNameError] = useState<string | null>(null);
  const [submitError, setSubmitError] = useState<string | null>(null);
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
  const [showC2Modal, setShowC2Modal] = useState(false);
  const [showImportModal, setShowImportModal] = useState(false);

  useEffect(() => {
    if (!isNew && detail.data) {
      const s = detail.data;
      setRt({
        name: s.name,
        description: s.description ?? '',
        commands: s.commands ?? '',
        prerequisites: s.prerequisites ?? '',
        executed_at: s.executed_at ? s.executed_at.slice(0, 16) : '',
        execution_result: s.execution_result ?? '',
      });
      setSoc({
        log_source: s.log_source ?? '',
        logs: s.logs ?? '',
        soc_comment: s.soc_comment ?? '',
        incident_number: s.incident_number ?? '',
      });
    }
  }, [isNew, detail.data]);

  if (!isNew && detail.isLoading) return <LoadingState label={t('simulation.form.loading')} />;
  if (!isNew && detail.isError) {
    return (
      <ErrorState
        message={extractApiError(detail.error, t('simulation.form.error.load'))}
        onRetry={() => detail.refetch()}
      />
    );
  }

  const simulation = detail.data;
  const status = simulation?.status;

  // US-18: Done = fully read-only, Reopen only
  const isDone = status === 'done';

  const socCanEdit = isSoc && (status === 'review_required' || status === 'done');
  const socBlocked = isSoc && (status === 'pending' || status === 'in_progress');

  const canSaveSoc = !isDone && (socCanEdit || canEditEngagements);
  const rtDisabled = !canEditRT || isDone;
  const socDisabled = isDone || (!canEditEngagements && !socCanEdit);

  const showMarkReview =
    !isDone && canEditEngagements && (status === 'pending' || status === 'in_progress');
  const showClose =
    !isDone && (canEditEngagements || isSoc) && status === 'review_required';
  const showReopen = isDone && (isAdmin || isRedteam || isSoc);

  const onSubmitNew = async (e: FormEvent) => {
    e.preventDefault();
    setNameError(null);
    setSubmitError(null);
    if (!rt.name.trim()) { setNameError(t('simulation.form.validation.nameRequired')); return; }
    try {
      const created = await createMutation.mutateAsync({ name: rt.name.trim() });
      push(t('simulation.form.toast.created'), 'success');
      navigate(`/engagements/${engagementId}/simulations/${created.id}/edit`);
    } catch (err) {
      setSubmitError(extractApiError(err, t('simulation.form.error.create')));
    }
  };

  const onSaveRT = async (e: FormEvent) => {
    e.preventDefault();
    setNameError(null);
    setSubmitError(null);
    if (!rt.name.trim()) { setNameError(t('simulation.form.validation.nameRequired')); return; }
    const patch: SimulationPatchInput = {
      name: rt.name.trim(),
      description: rt.description.trim() || null,
      commands: rt.commands.trim() || null,
      prerequisites: rt.prerequisites.trim() || null,
      executed_at: rt.executed_at || null,
      execution_result: rt.execution_result.trim() || null,
    };
    try {
      await updateMutation.mutateAsync(patch);
      push(t('simulation.form.toast.updated'), 'success');
    } catch (err) {
      setSubmitError(extractApiError(err, t('simulation.form.error.update')));
    }
  };

  const onSaveSOC = async (e: FormEvent) => {
    e.preventDefault();
    setSubmitError(null);
    const patch: SimulationPatchInput = {
      log_source: soc.log_source.trim() || null,
      logs: soc.logs.trim() || null,
      soc_comment: soc.soc_comment.trim() || null,
      incident_number: soc.incident_number.trim() || null,
    };
    try {
      await updateMutation.mutateAsync(patch);
      push(t('simulation.form.toast.socUpdated'), 'success');
    } catch (err) {
      setSubmitError(extractApiError(err, t('simulation.form.error.soc')));
    }
  };

  const onMarkReview = async () => {
    try {
      await transitionMutation.mutateAsync('review_required');
      push(t('simulation.form.toast.markedReview'), 'success');
    } catch (err) {
      push(extractApiError(err, t('simulation.form.error.transition')), 'error');
    }
  };

  const onClose = async () => {
    try {
      await transitionMutation.mutateAsync('done');
      push(t('simulation.form.toast.closed'), 'success');
    } catch (err) {
      push(extractApiError(err, t('simulation.form.error.transition')), 'error');
    }
  };

  const onReopen = async () => {
    try {
      await transitionMutation.mutateAsync('review_required');
      push(t('simulation.form.toast.reopened'), 'success');
    } catch (err) {
      push(extractApiError(err, t('simulation.form.error.transition')), 'error');
    }
  };

  const onDelete = async () => {
    setShowDeleteConfirm(false);
    try {
      await deleteMutation.mutateAsync(simulationId as number);
      push(t('simulation.form.toast.deleted'), 'success');
      navigate(`/engagements/${engagementId}`);
    } catch (err) {
      push(extractApiError(err, t('simulation.form.error.delete')), 'error');
    }
  };

  // New simulation form
  if (isNew) {
    const submitting = createMutation.isPending;
    return (
      <div className="flex flex-col gap-xl max-w-2xl">
        <header>
          <BackLink to={`/engagements/${engagementId}`}>{t('engagement.detail.backTo')}</BackLink>
          <h1 className="text-[32px] font-medium leading-none mt-sm">{t('simulation.form.title.new')}</h1>
        </header>

        <form onSubmit={onSubmitNew} noValidate className="card-product flex flex-col gap-md">
          <FormField label={t('simulation.form.field.name')} htmlFor="sim-name" required error={nameError}>
            <TextInput
              id="sim-name"
              name="name"
              value={rt.name}
              onChange={(e) => setRt({ ...rt, name: e.target.value })}
              required
            />
          </FormField>

          {submitError ? (
            <div role="alert" className="text-[14px] text-bloom-deep">{submitError}</div>
          ) : null}

          <div className="flex items-center gap-md pt-sm">
            <button type="submit" className="btn-primary" disabled={submitting} data-testid="create-sim-btn">
              {submitting ? t('simulation.form.btn.creating') : t('simulation.form.btn.create')}
            </button>
            <Link to={`/engagements/${engagementId}`} className="btn-outline-ink">
              {t('simulation.form.btn.cancel')}
            </Link>
          </div>
        </form>
      </div>
    );
  }

  const submitting =
    updateMutation.isPending || transitionMutation.isPending || deleteMutation.isPending;

  return (
    <div className="flex flex-col gap-xl">
      <header className="flex items-start justify-between gap-md">
        <div className="flex flex-col gap-sm">
          <BackLink to={`/engagements/${engagementId}`}>{t('engagement.detail.backTo')}</BackLink>
          <h1 className="text-[32px] font-medium leading-none">{rt.name || simulation?.name}</h1>
          {status ? (
            <div className="flex items-center gap-md">
              <SimulationStatusBadge status={status} />
              {simulation?.created_by && (
                <span className="text-[14px] text-graphite">
                  {t('engagement.detail.createdBy')}{' '}
                  <span className="text-ink">{simulation.created_by.username}</span>
                </span>
              )}
            </div>
          ) : null}
        </div>
      </header>

      {/* Done banner */}
      {isDone && (
        <AlertBanner variant="success">
          {t('simulation.form.banner.done')}
        </AlertBanner>
      )}

      {/* SOC banner */}
      {socBlocked && (
        <div data-testid="soc-blocked-banner">
          <AlertBanner variant="warn">
            {t('simulation.form.banner.socNotReady')}
          </AlertBanner>
        </div>
      )}

      {/* 2-column grid: RT+tasks left, SOC right. Stacks vertically below lg. */}
      <div className="grid gap-xl lg:grid-cols-2 items-start">
        {/* Left column: RT card + C2 tasks panel */}
        <div className="flex flex-col gap-xl">
        {/* Red Team card */}
        <form
          id="rt-form"
          onSubmit={canEditRT && !isDone ? onSaveRT : (e) => e.preventDefault()}
          noValidate
          className="card-product flex flex-col gap-md"
        >
          <h2 className="text-[20px] font-medium text-ink">{t('simulation.form.header.redTeam')}</h2>

          <FormField label={t('simulation.form.field.name')} htmlFor="sim-name" required error={nameError}>
            <TextInput
              id="sim-name"
              name="name"
              value={rt.name}
              onChange={(e) => setRt({ ...rt, name: e.target.value })}
              disabled={rtDisabled}
              required
            />
          </FormField>

          <div className="flex flex-col gap-xs">
            <span className="text-[14px] font-medium text-ink">{t('simulation.form.field.mitre')}</span>
            <MitreTechniquesField
              value={simulation?.techniques ?? []}
              tactics={simulation?.tactics ?? []}
              simulationId={simulationId as number}
              engagementId={engagementId as number}
              disabled={rtDisabled}
            />
          </div>

          <FormField label={t('simulation.form.field.description')} htmlFor="sim-description">
            <TextArea
              id="sim-description"
              name="description"
              value={rt.description}
              onChange={(e) => setRt({ ...rt, description: e.target.value })}
              disabled={rtDisabled}
            />
          </FormField>

          <FormField label={t('simulation.form.field.commands')} htmlFor="sim-commands" hint={t('simulation.form.field.commandsHint')}>
            <TextArea
              id="sim-commands"
              name="commands"
              value={rt.commands}
              onChange={(e) => setRt({ ...rt, commands: e.target.value })}
              disabled={rtDisabled}
              className="min-h-[160px] font-mono text-[14px]"
            />
          </FormField>

          <FormField label={t('simulation.form.field.prerequisites')} htmlFor="sim-prerequisites">
            <TextArea
              id="sim-prerequisites"
              name="prerequisites"
              value={rt.prerequisites}
              onChange={(e) => setRt({ ...rt, prerequisites: e.target.value })}
              disabled={rtDisabled}
            />
          </FormField>

          <FormField label={t('simulation.form.field.executedAt')} htmlFor="sim-executed-at">
            <TextInput
              id="sim-executed-at"
              type="datetime-local"
              name="executed_at"
              value={rt.executed_at}
              onChange={(e) => setRt({ ...rt, executed_at: e.target.value })}
              disabled={rtDisabled}
            />
          </FormField>

          <FormField label={t('simulation.form.field.executionResult')} htmlFor="sim-exec-result">
            <TextArea
              id="sim-exec-result"
              name="execution_result"
              value={rt.execution_result}
              onChange={(e) => setRt({ ...rt, execution_result: e.target.value })}
              disabled={rtDisabled}
              rows={5}
            />
          </FormField>

          {!isDone && canEditRT && hasC2Config && (
            <div className="pt-xs flex items-center gap-md flex-wrap">
              <button
                type="button"
                data-testid="c2-execute-btn"
                className="btn-outline"
                onClick={() => setShowC2Modal(true)}
              >
                {t('simulation.form.btn.executeC2')}
              </button>
              <button
                type="button"
                data-testid="c2-import-trigger-btn"
                className="btn-outline"
                onClick={() => setShowImportModal(true)}
              >
                {t('simulation.form.btn.importC2History')}
              </button>
            </div>
          )}
        </form>

        {/* C2 tasks panel — under RT card, same left column */}
        {showTasksPanel && simulationId && (
          <C2TasksPanel simulationId={simulationId} />
        )}
        </div>{/* end left column */}

        {/* SOC card */}
        <form
          id="soc-form"
          onSubmit={canSaveSoc ? onSaveSOC : (e) => e.preventDefault()}
          noValidate
          className="card-product flex flex-col gap-md"
        >
          <h2 className="text-[20px] font-medium text-ink">{t('simulation.form.header.soc')}</h2>

          <FormField label={t('simulation.form.field.logSource')} htmlFor="sim-log-source">
            <TextInput
              id="sim-log-source"
              name="log_source"
              value={soc.log_source}
              onChange={(e) => setSoc({ ...soc, log_source: e.target.value })}
              disabled={socDisabled}
            />
          </FormField>

          <FormField label={t('simulation.form.field.logs')} htmlFor="sim-logs">
            <TextArea
              id="sim-logs"
              name="logs"
              value={soc.logs}
              onChange={(e) => setSoc({ ...soc, logs: e.target.value })}
              disabled={socDisabled}
            />
          </FormField>

          <FormField label={t('simulation.form.field.socComment')} htmlFor="sim-soc-comment">
            <TextArea
              id="sim-soc-comment"
              name="soc_comment"
              value={soc.soc_comment}
              onChange={(e) => setSoc({ ...soc, soc_comment: e.target.value })}
              disabled={socDisabled}
            />
          </FormField>

          <FormField label={t('simulation.form.field.incidentNumber')} htmlFor="sim-incident">
            <TextInput
              id="sim-incident"
              name="incident_number"
              value={soc.incident_number}
              onChange={(e) => setSoc({ ...soc, incident_number: e.target.value })}
              disabled={socDisabled}
            />
          </FormField>
        </form>
      </div>

      {submitError ? (
        <div role="alert" className="text-[14px] text-bloom-deep">{submitError}</div>
      ) : null}

      {/* Unified sticky action bar */}
      <div className="sticky bottom-0 bg-canvas border-t border-hairline flex items-center gap-md flex-wrap py-md">
        {/* Done state: Reopen only */}
        {showReopen && (
          <button
            type="button"
            className="btn-outline"
            onClick={onReopen}
            disabled={transitionMutation.isPending}
            data-testid="reopen-btn"
          >
            <RotateCcw size={14} aria-hidden />
            {t('simulation.form.btn.reopen')}
          </button>
        )}

        {/* Normal state buttons */}
        {!isDone && canEditRT && (
          <button type="submit" form="rt-form" className="btn-primary" disabled={submitting}>
            <Save size={14} aria-hidden />
            {updateMutation.isPending ? t('simulation.form.btn.saving') : t('simulation.form.btn.save')}
          </button>
        )}
        {!isDone && canSaveSoc && (
          <button type="submit" form="soc-form" className="btn-primary" disabled={submitting}>
            <Save size={14} aria-hidden />
            {updateMutation.isPending ? t('simulation.form.btn.saving') : t('simulation.form.btn.saveSoc')}
          </button>
        )}
        {showMarkReview && (
          <button
            type="button"
            className="btn-outline"
            onClick={onMarkReview}
            disabled={transitionMutation.isPending}
            data-testid="mark-review-btn"
          >
            {t('simulation.form.btn.markReview')}
          </button>
        )}
        {showClose && (
          <button
            type="button"
            className="btn-outline"
            onClick={onClose}
            disabled={transitionMutation.isPending}
            data-testid="close-btn"
          >
            {t('simulation.form.btn.close')}
          </button>
        )}
        {!isDone && canEditEngagements && simulationId && (
          <button
            type="button"
            className="btn-text-link text-bloom-deep ml-auto"
            onClick={() => setShowDeleteConfirm(true)}
            disabled={submitting}
            data-testid="delete-btn"
          >
            {t('simulation.form.btn.delete')}
          </button>
        )}
      </div>

      {showDeleteConfirm && (
        <ConfirmDialog
          title={t('simulation.form.deleteConfirm.title')}
          description={t('simulation.form.deleteConfirm.desc')}
          confirmLabel={t('simulation.form.deleteConfirm.confirm')}
          cancelLabel={t('simulation.form.deleteConfirm.cancel')}
          destructive
          onConfirm={onDelete}
          onCancel={() => setShowDeleteConfirm(false)}
        />
      )}

      {showC2Modal && simulationId && typeof engagementId === 'number' && (
        <ExecuteViaC2Modal
          simulationId={simulationId}
          engagementId={engagementId}
          initialCommands={rt.commands}
          onClose={() => setShowC2Modal(false)}
        />
      )}

      {showImportModal && simulationId && typeof engagementId === 'number' && (
        <ImportC2HistoryModal
          simulationId={simulationId}
          engagementId={engagementId}
          onClose={() => setShowImportModal(false)}
        />
      )}
    </div>
  );
}
