import { forwardRef, useEffect, useRef, useState } from "react";
import {
  Bot,
  Sparkles,
  FileText,
  Wand2,
  SlidersHorizontal,
  ListChecks,
  MessageSquareText,
} from "lucide-react";
import { Dialog, DialogContent } from "@/components/ui/dialog";
import { Terminal, AnimatedStep } from "@/components/ui/terminal";
import { TypingAnimation } from "@/components/ui/typing-animation";
import { AnimatedBeam } from "@/components/ui/animated-beam";
import { cn } from "@/lib/utils";

const PROMPT_CREATE_STEPS = [
  "Interpretando instruções e contexto...",
  "Definindo objetivo, público e tom...",
  "Organizando estrutura do prompt (seções e regras)...",
  "Especificando formato de saída e restrições...",
  "Adicionando critérios de qualidade e validações...",
  "Incluindo exemplos e casos de borda...",
  "Revisando clareza e consistência...",
  "Finalizando prompt...",
] as const;

const PROMPT_REFINE_STEPS = [
  "Lendo o prompt atual...",
  "Identificando ambiguidades e pontos fracos...",
  "Removendo redundâncias e ruído...",
  "Aprimorando instruções e critérios de sucesso...",
  "Ajustando tom, voz e consistência...",
  "Fortalecendo formato de saída e validações...",
  "Adicionando exemplos e casos de borda...",
  "Consolidando melhorias e finalizando...",
] as const;

const STEP_INTERVAL_MS = 1500;

export type PromptGeneratingMode = "create" | "refine";

export interface PromptGeneratingScreenProps {
  mode: PromptGeneratingMode;
  progress?: number;
  message?: string;
}

function visibleLineCount(progress: number, stepCount: number): number {
  if (progress <= 0) return 1;
  const phase = (progress / 100) * stepCount;
  const stepInCycle = Math.floor(phase) % stepCount;
  return Math.min(stepInCycle + 1, stepCount);
}

const BeamCircle = forwardRef<
  HTMLDivElement,
  { className?: string; children?: React.ReactNode }
>(({ className, children }, ref) => (
  <div
    ref={ref}
    className={cn(
      "z-10 flex size-12 items-center justify-center rounded-full border-2 border-slate-300 bg-slate-100 text-slate-700 shadow-sm",
      className
    )}
  >
    {children}
  </div>
));
BeamCircle.displayName = "BeamCircle";

export function PromptGeneratingScreen({
  mode,
  progress,
  message = "Assim que finalizar, o modal será fechado automaticamente.",
}: PromptGeneratingScreenProps) {
  const steps = mode === "refine" ? PROMPT_REFINE_STEPS : PROMPT_CREATE_STEPS;
  const stepCount = steps.length;

  const containerRef = useRef<HTMLDivElement>(null);
  const sparklesRef = useRef<HTMLDivElement>(null);
  const fileRef = useRef<HTMLDivElement>(null);
  const slidersRef = useRef<HTMLDivElement>(null);
  const centerRef = useRef<HTMLDivElement>(null);
  const wandRef = useRef<HTMLDivElement>(null);
  const checklistRef = useRef<HTMLDivElement>(null);
  const chatRef = useRef<HTMLDivElement>(null);

  const [loopStep, setLoopStep] = useState(0);
  useEffect(() => {
    if (progress !== undefined) return;
    const id = setInterval(() => {
      setLoopStep((s) => (s + 1) % stepCount);
    }, STEP_INTERVAL_MS);
    return () => clearInterval(id);
  }, [progress, stepCount]);

  const visibleCount =
    progress !== undefined
      ? visibleLineCount(progress, stepCount)
      : loopStep + 1;

  return (
    <Dialog open>
      <DialogContent
        hideClose
        overlayClassName="bg-black/50"
        className="max-w-2xl gap-0 overflow-hidden bg-white p-0 sm:rounded-xl"
      >
        <div className="flex flex-col gap-4 p-5">
          <div className="flex items-center gap-3 rounded-t-lg border border-b-0 border-border bg-zinc-100 px-3 py-2.5">
            <div className="flex gap-1.5">
              <span className="size-3 rounded-full bg-[#ff5f57]" aria-hidden />
              <span className="size-3 rounded-full bg-[#febc2e]" aria-hidden />
              <span className="size-3 rounded-full bg-[#28c840]" aria-hidden />
            </div>
            <span className="font-mono text-xs text-muted-foreground">
              codex prompt — {mode === "refine" ? "melhorando" : "gerando"}
            </span>
          </div>

          <Terminal className="min-h-[200px] space-y-2 rounded-t-none border-t-0 bg-white p-4 font-mono text-sm">
            <AnimatedStep delay={0} className="text-muted-foreground">
              {`> codex prompt --${mode === "refine" ? "refine" : "create"}`}
            </AnimatedStep>
            {steps.slice(0, visibleCount).map((text, i) => (
              <div key={`${visibleCount}-${i}-${text}`} className="flex items-center gap-0">
                {i < visibleCount - 1 ? (
                  <span className="text-sky-600 dark:text-sky-400">
                    ✔ {text}
                  </span>
                ) : (
                  <TypingAnimation
                    key={`typing-${visibleCount}`}
                    startOnView={false}
                    showCursor
                    cursorStyle="block"
                    className="text-sky-600 dark:text-sky-400"
                  >
                    {`✔ ${text}`}
                  </TypingAnimation>
                )}
              </div>
            ))}
          </Terminal>

          {message && (
            <p className="text-center text-sm text-muted-foreground">
              {message}
            </p>
          )}

          <div className="rounded-xl border border-border bg-white p-6">
            <div
              ref={containerRef}
              className="relative flex h-[260px] w-full items-center justify-center overflow-hidden"
            >
              <div className="flex size-full max-h-[220px] max-w-lg flex-col items-stretch justify-between">
                <div className="flex flex-row items-center justify-between">
                  <BeamCircle ref={sparklesRef}>
                    <Sparkles className="size-6 text-sky-500" />
                  </BeamCircle>
                  <BeamCircle ref={fileRef}>
                    <FileText className="size-6 text-slate-600" />
                  </BeamCircle>
                </div>
                <div className="flex flex-row items-center justify-between">
                  <BeamCircle ref={slidersRef}>
                    <SlidersHorizontal className="size-6 text-indigo-500" />
                  </BeamCircle>
                  <BeamCircle ref={centerRef} className="size-14 border-slate-400 bg-slate-200">
                    <Bot className="size-8 text-slate-700" />
                  </BeamCircle>
                  <BeamCircle ref={wandRef}>
                    <Wand2 className="size-6 text-amber-500" />
                  </BeamCircle>
                </div>
                <div className="flex flex-row items-center justify-between">
                  <BeamCircle ref={checklistRef}>
                    <ListChecks className="size-6 text-slate-600" />
                  </BeamCircle>
                  <BeamCircle ref={chatRef}>
                    <MessageSquareText className="size-6 text-slate-600" />
                  </BeamCircle>
                </div>
              </div>

              <AnimatedBeam
                containerRef={containerRef}
                fromRef={sparklesRef}
                toRef={centerRef}
                curvature={-75}
                endYOffset={-10}
                gradientStartColor="#0ea5e9"
                gradientStopColor="#64748b"
              />
              <AnimatedBeam
                containerRef={containerRef}
                fromRef={fileRef}
                toRef={centerRef}
                curvature={-75}
                endYOffset={-10}
                reverse
                gradientStartColor="#94a3b8"
                gradientStopColor="#64748b"
              />
              <AnimatedBeam
                containerRef={containerRef}
                fromRef={slidersRef}
                toRef={centerRef}
                gradientStartColor="#6366f1"
                gradientStopColor="#64748b"
              />
              <AnimatedBeam
                containerRef={containerRef}
                fromRef={wandRef}
                toRef={centerRef}
                reverse
                gradientStartColor="#f59e0b"
                gradientStopColor="#64748b"
              />
              <AnimatedBeam
                containerRef={containerRef}
                fromRef={checklistRef}
                toRef={centerRef}
                curvature={75}
                endYOffset={10}
                gradientStartColor="#94a3b8"
                gradientStopColor="#64748b"
              />
              <AnimatedBeam
                containerRef={containerRef}
                fromRef={chatRef}
                toRef={centerRef}
                curvature={75}
                endYOffset={10}
                reverse
                gradientStartColor="#94a3b8"
                gradientStopColor="#64748b"
              />
            </div>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );
}

