"use client";

import * as React from "react";
import { useEffect, useState, useRef } from "react";
import { motion, useInView } from "framer-motion";

interface CodeSnippetProps {
  className?: string;
  variant?: "code" | "git" | "terminal";
}

const codeLines = [
  { indent: 0, text: "async deploy(config) {", color: "text-slate-500" },
  { indent: 1, text: "const build = await compile({", color: "text-slate-400" },
  { indent: 2, text: 'target: "production",', color: "text-slate-300" },
  { indent: 2, text: "optimize: true,", color: "text-slate-300" },
  { indent: 2, text: 'performance: "maximum"', color: "text-slate-300" },
  { indent: 1, text: "});", color: "text-slate-400" },
  { indent: 1, text: "", color: "" },
  { indent: 1, text: "await pipeline.run([", color: "text-slate-400" },
  { indent: 2, text: "lint, test, build, stage", color: "text-slate-300" },
  { indent: 1, text: "]);", color: "text-slate-400" },
  { indent: 1, text: "", color: "" },
  { indent: 1, text: 'return { status: "live" };', color: "text-slate-400" },
  { indent: 0, text: "}", color: "text-slate-500" },
];

const gitBranches = [
  {
    type: "commit",
    branch: "main",
    label: "v2.1.0 – Production",
    active: false,
  },
  {
    type: "branch",
    branch: "feature",
    label: "feature/redesign",
    active: true,
  },
  { type: "commit", branch: "feature", label: "Neues Layout", active: true },
  {
    type: "commit",
    branch: "feature",
    label: "Performance-Optimierung",
    active: true,
  },
  { type: "merge", branch: "main", label: "Merge → Production", active: false },
  { type: "commit", branch: "main", label: "v2.2.0 – Live", active: false },
];

const terminalLines = [
  { prompt: true, text: "npm run build", delay: 0 },
  { prompt: false, text: "✓ Compiled successfully", delay: 0.3 },
  { prompt: false, text: "✓ Lighthouse: 98/100", delay: 0.6 },
  { prompt: false, text: "✓ Bundle: 42kb gzipped", delay: 0.9 },
  { prompt: true, text: "git push origin main", delay: 1.5 },
  { prompt: false, text: "→ Deploying to production...", delay: 1.8 },
  { prompt: false, text: "✓ Live in 12s", delay: 2.4 },
];

import { CodeWindow } from "./CodeWindow";

export const CodeSnippet: React.FC<CodeSnippetProps> = ({
  className = "",
  variant = "code",
}) => {
  const ref = useRef(null);
  const isInView = useInView(ref, { once: true, margin: "-10%" });
  const [visibleLineIndex, setVisibleLineIndex] = useState(-1);
  const [displayText, setDisplayText] = useState<string[]>([]);

  useEffect(() => {
    if (!isInView) return;

    const lines =
      variant === "code"
        ? codeLines
        : variant === "git"
          ? gitBranches.map((b) => ({ text: b.label }))
          : terminalLines;

    const animate = async () => {
      for (let i = 0; i < lines.length; i++) {
        setVisibleLineIndex(i);
        const line = lines[i];
        const text = "text" in line ? line.text : (line as any).label || "";

        for (let j = 0; j <= text.length; j++) {
          setDisplayText((prev) => {
            const next = [...prev];
            next[i] = text.slice(0, j);
            return next;
          });
          const speed = "prompt" in line && line.prompt ? 40 : 25;
          await new Promise((r) => setTimeout(r, speed));
        }

        const pause = "delay" in line ? (line as any).delay * 1000 : 150;
        await new Promise((r) => setTimeout(r, pause));
      }
    };

    animate();
  }, [isInView, variant]);

  const title =
    variant === "code"
      ? "deploy.ts"
      : variant === "git"
        ? "git log"
        : "terminal";

  return (
    <CodeWindow title={title} className={className} minHeight="380px">
      <div ref={ref}>
        {variant === "code" &&
          codeLines.map((line, i) => (
            <motion.div
              key={i}
              initial={{ opacity: 0 }}
              animate={i <= visibleLineIndex ? { opacity: 1 } : { opacity: 0 }}
              className={`${line.color} whitespace-pre flex items-center h-6`}
              style={{ paddingLeft: `${line.indent * 20}px` }}
            >
              <span>{displayText[i] || ""}</span>
              {i === visibleLineIndex && (
                <motion.span
                  animate={{ opacity: [1, 0] }}
                  transition={{ repeat: Infinity, duration: 0.6 }}
                  className="inline-block w-1.5 h-4 bg-slate-300 ml-1 shrink-0"
                />
              )}
            </motion.div>
          ))}

        {variant === "git" && (
          <div className="relative">
            <div className="absolute left-[7px] top-3 bottom-3 w-px bg-slate-200" />
            {gitBranches.map((item, i) => (
              <motion.div
                key={i}
                initial={{ opacity: 0, x: -5 }}
                animate={i <= visibleLineIndex ? { opacity: 1, x: 0 } : {}}
                className="flex items-center gap-4 py-1.5 relative h-8"
              >
                <div
                  className={`w-4 h-4 rounded-full border-2 z-10 shrink-0 ${item.type === "merge" ? "border-slate-400 bg-slate-100" : item.active ? "border-slate-300 bg-white" : "border-slate-200 bg-slate-50"}`}
                />
                {item.type === "branch" && (
                  <span className="text-[10px] px-2 py-0.5 rounded-full bg-slate-100 border border-slate-200 text-slate-400 font-bold shrink-0">
                    {item.branch}
                  </span>
                )}
                <span
                  className={`text-xs ${item.active ? "text-slate-500" : "text-slate-300"} truncate`}
                >
                  {displayText[i] || ""}
                </span>
              </motion.div>
            ))}
          </div>
        )}

        {variant === "terminal" &&
          terminalLines.map((line, i) => (
            <motion.div
              key={i}
              initial={{ opacity: 0 }}
              animate={i <= visibleLineIndex ? { opacity: 1 } : {}}
              className="flex items-start gap-2 py-0.5 min-h-[1.5rem]"
            >
              {line.prompt && (
                <span className="text-slate-300 select-none shrink-0">❯</span>
              )}
              <span
                className={
                  line.prompt ? "text-slate-500 font-medium" : "text-slate-300"
                }
              >
                {displayText[i] || ""}
              </span>
              {i === visibleLineIndex && (
                <motion.span
                  animate={{ opacity: [1, 0] }}
                  transition={{ repeat: Infinity, duration: 0.6 }}
                  className="inline-block w-1.5 h-4 bg-slate-300 ml-0.5 shrink-0"
                />
              )}
            </motion.div>
          ))}
      </div>
    </CodeWindow>
  );
};
