"use client";

import Image from "next/image";
import {
  Archive,
  Check,
  Download,
  Film,
  FolderOpen,
  Play,
  Sparkles,
  X,
} from "lucide-react";
import { useEffect, useState } from "react";
import { mockVideoBehavior } from "@/mock-video/behavior.config";
import { downloadMockArchive } from "@/lib/mock-video";

const styleOptions = [
  { name: "Cinematic", image: "/generated/images/cinematic-city.webp" },
  { name: "Anime", image: "/generated/images/neon-portrait.webp" },
  { name: "Storybook", image: "/generated/images/storybook-forest.webp" },
  { name: "Dreamlike", image: "/generated/images/ocean-dream.webp" },
] as const;

type Project = { id: string; title: string; image: string; date: string };

export function Wizard({ initialTool = "story" }: { initialTool?: string }) {
  const [toolLabel, setToolLabel] = useState(initialTool);
  const [step, setStep] = useState(1);
  const [script, setScript] = useState(
    "A lonely astronaut discovers a hidden garden beneath the red dust of Mars.",
  );
  const [style, setStyle] = useState("Cinematic");
  const [ratio, setRatio] = useState("16:9");
  const [videoCount, setVideoCount] = useState(4);
  const [progress, setProgress] = useState(0);
  const [status, setStatus] = useState("Preparing your request...");
  const [toast, setToast] = useState("");
  const [downloadOpen, setDownloadOpen] = useState(false);
  const [downloadError, setDownloadError] = useState("");

  const poster =
    styleOptions.find((option) => option.name === style)?.image ||
    mockVideoBehavior.posterImage;

  useEffect(() => {
    const timer = window.setTimeout(() => {
      const tool = new URLSearchParams(window.location.search).get("tool");
      if (tool) setToolLabel(tool);
    }, 0);
    return () => window.clearTimeout(timer);
  }, []);

  useEffect(() => {
    window.scrollTo({ top: 0, behavior: "smooth" });
  }, [step]);

  useEffect(() => {
    if (step !== 2) return;

    const duration =
      mockVideoBehavior.fakeProcessingTimeMs.min +
      Math.random() *
        (mockVideoBehavior.fakeProcessingTimeMs.max -
          mockVideoBehavior.fakeProcessingTimeMs.min);
    const startedAt = Date.now();
    const timer = window.setInterval(() => {
      const elapsed = Date.now() - startedAt;
      const nextProgress = Math.min(100, Math.round((elapsed / duration) * 100));
      const messageIndex = Math.min(
        mockVideoBehavior.fakeStatusMessages.length - 1,
        Math.floor(
          (nextProgress / 100) * mockVideoBehavior.fakeStatusMessages.length,
        ),
      );

      setProgress(nextProgress);
      setStatus(mockVideoBehavior.fakeStatusMessages[messageIndex]);

      if (nextProgress >= 100) {
        window.clearInterval(timer);
        const project: Project = {
          id: crypto.randomUUID(),
          title: script.slice(0, 56) || "Untitled story",
          image: poster,
          date: new Date().toISOString(),
        };
        const projects: Project[] = JSON.parse(
          localStorage.getItem("nuvid-projects") || "[]",
        );
        localStorage.setItem(
          "nuvid-projects",
          JSON.stringify([project, ...projects].slice(0, 20)),
        );
        window.setTimeout(() => setStep(3), 350);
      }
    }, 120);

    return () => window.clearInterval(timer);
  }, [poster, script, step]);

  const startGeneration = () => {
    setProgress(0);
    setStatus(mockVideoBehavior.fakeStatusMessages[0]);
    setStep(2);
  };

  const resetWizard = () => {
    setProgress(0);
    setStep(1);
  };

  const confirmDownload = async () => {
    try {
      setDownloadError("");
      await downloadMockArchive(script);
      setDownloadOpen(false);
      setToast("Your video archive is downloading");
      window.setTimeout(() => setToast(""), 2600);
    } catch {
      setDownloadError("The archive could not be downloaded. Please try again.");
    }
  };

  return (
    <div className="wizard-shell">
      <div className="wizard-top">
        <div>
          <p className="eyebrow">{toolLabel.replace(/-/g, " ")}</p>
          <h1>Create your story</h1>
        </div>
        <div className="step-track" aria-label={`Step ${step} of 3`}>
          {[1, 2, 3].map((number) => (
            <span key={number} className={number <= step ? "active" : ""}>
              {number < step ? <Check size={13} /> : number}
            </span>
          ))}
        </div>
      </div>

      {step === 1 && (
        <section className="wizard-panel">
          <div className="wizard-main">
            <label className="field-label" htmlFor="script">
              Describe your video
            </label>
            <textarea
              id="script"
              value={script}
              onChange={(event) => setScript(event.target.value)}
              maxLength={2500}
              placeholder="Describe the person, action, setting, camera, and mood..."
            />
            <div className="char-count">{script.length} / 2500</div>
            <div className="option-block">
              <span className="field-label">Visual style</span>
              <div className="style-grid">
                {styleOptions.map((option) => (
                  <button
                    key={option.name}
                    className={option.name === style ? "selected" : ""}
                    onClick={() => setStyle(option.name)}
                  >
                    <Image
                      src={option.image}
                      alt=""
                      fill
                      sizes="150px"
                      priority={option.name === "Cinematic"}
                    />
                    <span>{option.name}</span>
                    {option.name === style && (
                      <i>
                        <Check size={12} />
                      </i>
                    )}
                  </button>
                ))}
              </div>
            </div>
          </div>
          <aside className="wizard-side">
            <div className="option-block">
              <span className="field-label">Aspect ratio</span>
              <div className="ratio-row">
                {["16:9", "9:16", "1:1"].map((option) => (
                  <button
                    key={option}
                    className={option === ratio ? "selected" : ""}
                    onClick={() => setRatio(option)}
                  >
                    <i style={{ aspectRatio: option.replace(":", "/") }} />
                    {option}
                  </button>
                ))}
              </div>
            </div>
            <div className="option-block">
              <span className="field-label">
                Number of videos <strong>{videoCount}</strong>
              </span>
              <input
                type="range"
                min="1"
                max="4"
                value={videoCount}
                onChange={(event) => setVideoCount(Number(event.target.value))}
              />
              <div className="range-labels">
                <span>1</span>
                <span>4</span>
              </div>
            </div>
            <div className="generate-note">
              <Sparkles size={16} />
              <p>
                <strong>Everything looks ready</strong>
                <span>
                  This demo uses a local preview and a downloadable placeholder
                  archive. No request is sent to an AI provider.
                </span>
              </p>
            </div>
            <button
              className="button button-primary"
              onClick={startGeneration}
              disabled={!script.trim()}
            >
              Generate video <Sparkles size={16} />
            </button>
          </aside>
        </section>
      )}

      {step === 2 && (
        <section className="generation-panel">
          <div className="generation-orbit">
            <Film size={34} />
            <i />
            <i />
            <i />
          </div>
          <p className="eyebrow">Preparing your preview</p>
          <h2>{progress}%</h2>
          <p>{status}</p>
          <div className="progress-bar">
            <span style={{ width: `${progress}%` }} />
          </div>
          <small>Demo mode · no real AI generation is running</small>
        </section>
      )}

      {step === 3 && (
        <section className="result-panel">
          <div className="result-copy">
            <p className="eyebrow">Your preview is ready</p>
            <h2>
              A first look at
              <br />
              your story.
            </h2>
            <p>
              This is a visual placeholder for your result. The download button
              provides the prepared ZIP archive for this demo.
            </p>
            <button
              className="button button-primary"
              onClick={() => setDownloadOpen(true)}
            >
              <Download size={17} /> Download your videos
            </button>
            <button className="restart" onClick={resetWizard}>
              Create another story
            </button>
          </div>
          <div
            className={`result-player ratio-${ratio.replace(":", "")}`}
            style={{ backgroundImage: `url(${poster})` }}
            onContextMenu={(event) => event.preventDefault()}
          >
            <button
              type="button"
              aria-label="Play placeholder preview"
              onClick={() => {
                setToast("Preview playback is a placeholder in this demo");
                window.setTimeout(() => setToast(""), 2600);
              }}
            >
              <Play size={31} fill="currentColor" />
            </button>
            <div className="player-meta">
              <span>
                {style} · {ratio}
              </span>
              <span>Placeholder · {videoCount} {videoCount === 1 ? "scene" : "scenes"}</span>
            </div>
          </div>
          {toast && <div className="toast">{toast}</div>}
        </section>
      )}

      {downloadOpen && (
        <div
          className="download-backdrop"
          onMouseDown={(event) =>
            event.target === event.currentTarget && setDownloadOpen(false)
          }
        >
          <section
            className="download-dialog"
            role="dialog"
            aria-modal="true"
            aria-labelledby="download-title"
          >
            <button
              className="dialog-close"
              onClick={() => setDownloadOpen(false)}
              aria-label="Close download instructions"
            >
              <X size={18} />
            </button>
            <div className="archive-icon">
              <Archive size={27} />
            </div>
            <p className="eyebrow">Before you download</p>
            <h2 id="download-title">Your videos come in a ZIP archive.</h2>
            <p className="dialog-lead">
              The archive keeps all of your video files together in one download.
            </p>
            <ol>
              <li>
                <span>1</span>
                <div>
                  <strong>Download the archive</strong>
                  <p>Click the button below and wait for the ZIP file to finish downloading.</p>
                </div>
              </li>
              <li>
                <span>2</span>
                <div>
                  <strong>Open or extract it</strong>
                  <p>Double-click the ZIP file, then choose Extract all if your computer asks.</p>
                </div>
              </li>
              <li>
                <span>3</span>
                <div>
                  <strong>Open your videos</strong>
                  <p>Your MP4 video files and a short README will be waiting inside.</p>
                </div>
              </li>
            </ol>
            {downloadError && <p className="download-error">{downloadError}</p>}
            <button
              className="button button-primary dialog-download"
              onClick={confirmDownload}
            >
              <FolderOpen size={17} /> Download archive
            </button>
            <small>ZIP archive · Contains MP4 video files</small>
          </section>
        </div>
      )}
    </div>
  );
}

export function Dashboard() {
  const [projects, setProjects] = useState<Project[]>([]);

  useEffect(() => {
    const timer = window.setTimeout(() => {
      const storedProjects =
        localStorage.getItem("nuvid-projects") || "[]";
      setProjects(JSON.parse(storedProjects));
    }, 0);
    return () => window.clearTimeout(timer);
  }, []);

  return (
    <div className="dashboard-shell">
      <div className="dashboard-head">
        <div>
          <p className="eyebrow">Your workspace</p>
          <h1>My videos</h1>
        </div>
        <a className="button button-primary" href="/app/create/">
          New project <Sparkles size={15} />
        </a>
      </div>
      {projects.length ? (
        <div className="project-grid">
          {projects.map((project) => (
            <article key={project.id}>
              <div>
                <Image src={project.image} alt="" fill sizes="320px" />
                <Play fill="currentColor" />
              </div>
              <h2>{project.title}</h2>
              <p>
                {new Date(project.date).toLocaleDateString("en", {
                  month: "short",
                  day: "numeric",
                  year: "numeric",
                })}
              </p>
            </article>
          ))}
        </div>
      ) : (
        <div className="empty-state">
          <Film size={34} />
          <h2>Your next story starts here.</h2>
          <p>Projects created with the video workflow will appear in this browser.</p>
          <a className="button button-primary" href="/app/create/">
            Create your first video
          </a>
        </div>
      )}
    </div>
  );
}
