'use client';

import { useEffect, useState } from 'react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Loader2, CheckCircle2, AlertTriangle, X } from 'lucide-react';
import { Button } from '@/components/ui/button';

interface ExecutionRow {
  id: string;
  scriptId: string;
  jobName: string;
  targetHostname: string | null;
  status: 'queued' | 'running' | 'complete' | 'failed' | 'timeout';
  exitCode: number | null;
  rawStdout: string | null;
  rawStderr: string | null;
  parsedEvidence: unknown;
  parseError: string | null;
  errorMessage: string | null;
  queuedAt: string;
  completedAt: string | null;
}

const POLL_MS = 3000;
const POLL_TIMEOUT_MS = 6 * 60 * 1000; // 6 min — slightly longer than the server-side hard cap.

export function RmmExecutionStream({
  executionId,
  onComplete,
}: {
  executionId: string;
  onComplete?: () => void;
}) {
  const [exec, setExec] = useState<ExecutionRow | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [closed, setClosed] = useState(false);

  useEffect(() => {
    if (closed) return;
    let cancelled = false;
    const start = Date.now();

    async function tick() {
      if (cancelled) return;
      try {
        const res = await fetch(`/api/rmm/executions/${executionId}`);
        if (!res.ok) {
          throw new Error(`HTTP ${res.status}`);
        }
        const data = (await res.json()) as { execution: ExecutionRow };
        if (cancelled) return;
        setExec(data.execution);
        if (
          data.execution.status === 'complete' ||
          data.execution.status === 'failed' ||
          data.execution.status === 'timeout'
        ) {
          onComplete?.();
          return;
        }
        if (Date.now() - start > POLL_TIMEOUT_MS) {
          setError('Polling timed out — check execution status manually.');
          return;
        }
        setTimeout(tick, POLL_MS);
      } catch (err) {
        if (cancelled) return;
        setError(err instanceof Error ? err.message : 'Unknown error');
      }
    }

    void tick();
    return () => {
      cancelled = true;
    };
  }, [executionId, closed, onComplete]);

  if (closed) return null;

  const status = exec?.status ?? 'queued';
  const isDone =
    status === 'complete' || status === 'failed' || status === 'timeout';

  return (
    <Card>
      <CardHeader>
        <div className="flex items-start justify-between gap-3 flex-wrap">
          <div>
            <CardTitle className="text-base flex items-center gap-2">
              {!isDone ? (
                <Loader2 className="w-4 h-4 animate-spin text-muted-foreground" />
              ) : status === 'complete' ? (
                <CheckCircle2 className="w-4 h-4 text-emerald-600" />
              ) : (
                <AlertTriangle className="w-4 h-4 text-amber-600" />
              )}
              {exec?.jobName ?? 'Discovery script'}
              <Badge
                variant={
                  status === 'complete'
                    ? 'default'
                    : status === 'failed' || status === 'timeout'
                      ? 'destructive'
                      : 'outline'
                }
                className="text-[10px]"
              >
                {status}
              </Badge>
            </CardTitle>
            <p className="text-xs text-muted-foreground mt-1">
              {exec?.targetHostname ? `target: ${exec.targetHostname} · ` : ''}
              execution {executionId}
            </p>
          </div>
          <Button
            type="button"
            variant="ghost"
            size="icon"
            onClick={() => setClosed(true)}
            title="Hide"
          >
            <X className="w-4 h-4" />
          </Button>
        </div>
      </CardHeader>
      <CardContent className="space-y-3">
        {error && <p className="text-sm text-destructive">{error}</p>}

        {isDone && exec?.parseError && (
          <p className="text-xs text-amber-600">
            Output parser failed: {exec.parseError}
          </p>
        )}

        {isDone && exec?.errorMessage && (
          <p className="text-xs text-destructive">{exec.errorMessage}</p>
        )}

        {isDone && exec?.parsedEvidence !== undefined && exec.parsedEvidence !== null && (
          <div>
            <p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground mb-1">
              Parsed evidence
            </p>
            <pre className="text-[11px] bg-muted/50 rounded p-2 max-h-72 overflow-auto whitespace-pre-wrap">
              {JSON.stringify(exec.parsedEvidence, null, 2)}
            </pre>
          </div>
        )}

        {isDone && exec?.rawStdout && (
          <details>
            <summary className="text-xs font-semibold uppercase tracking-wide text-muted-foreground cursor-pointer">
              Raw stdout ({exec.rawStdout.length} chars)
            </summary>
            <pre className="text-[11px] bg-muted/50 rounded p-2 max-h-72 overflow-auto whitespace-pre-wrap mt-1">
              {exec.rawStdout.slice(0, 50000)}
            </pre>
          </details>
        )}

        {isDone && exec?.rawStderr && (
          <details>
            <summary className="text-xs font-semibold uppercase tracking-wide text-muted-foreground cursor-pointer">
              Raw stderr
            </summary>
            <pre className="text-[11px] bg-muted/50 rounded p-2 max-h-40 overflow-auto whitespace-pre-wrap mt-1">
              {exec.rawStderr.slice(0, 20000)}
            </pre>
          </details>
        )}

        {!isDone && (
          <p className="text-xs text-muted-foreground">
            Polling every {POLL_MS / 1000}s — Datto typically returns within
            ~30-90s for asset-self scripts and ~60-180s for site-anchored.
          </p>
        )}
      </CardContent>
    </Card>
  );
}
