import React, { useState, useEffect, useRef, useCallback, useMemo } from "react";
import {
  X, Monitor, Tablet, Smartphone, Maximize2, RefreshCw,
  Download, Copy, Check, Code2, Eye, Columns, ZoomIn, ZoomOut,
  ExternalLink, RotateCcw, Sun, Moon, Paintbrush,
} from "lucide-react";

/* ═══════════════════════════════════════════════════
   VIEWPORT PRESETS
   ═══════════════════════════════════════════════════ */
const VIEWPORTS = [
  { id: "desktop", label: "Desktop", width: 1440, height: 900, icon: Monitor },
  { id: "tablet", label: "Tablet", width: 768, height: 1024, icon: Tablet },
  { id: "mobile", label: "Mobile", width: 375, height: 812, icon: Smartphone },
  { id: "full", label: "Responsive", width: null, height: null, icon: Maximize2 },
];

const ZOOM_LEVELS = [25, 50, 75, 100, 125, 150, 200];

/* ═══════════════════════════════════════════════════
   HTML BUILDER — Combines code blocks into a page
   ═══════════════════════════════════════════════════ */
const TAILWIND_RE = /class="[^"]*(?:flex|grid|p-\d|m-\d|bg-|text-(?:sm|lg|xl|\w+-\d)|rounded|shadow|border|w-|h-|gap-|space-|items-|justify-)/;
const REACT_IMPORT_RE = /(?:import\s+.*from\s+['"]react|React\.|useState|useEffect|useRef|jsx|<\w+[A-Z])/;

export function buildPreviewHTML(blocks) {
  if (!blocks || !blocks.length) return null;

  const htmlBlocks = blocks.filter(
    (b) => b.language === "html" || b.filename?.match(/\.html?$/)
  );
  const cssBlocks = blocks.filter(
    (b) => b.language === "css" || b.language === "scss" || b.filename?.match(/\.s?css$/)
  );
  const jsBlocks = blocks.filter(
    (b) =>
      ["javascript", "js"].includes(b.language) ||
      (b.filename?.match(/\.m?js$/) && !b.filename?.match(/\.jsx$/))
  );
  const reactBlocks = blocks.filter(
    (b) =>
      ["jsx", "tsx", "react"].includes(b.language) ||
      b.filename?.match(/\.(jsx|tsx)$/) ||
      (["javascript", "js", "typescript", "ts"].includes(b.language) &&
        REACT_IMPORT_RE.test(b.code))
  );
  const vueBlocks = blocks.filter(
    (b) => b.language === "vue" || b.filename?.match(/\.vue$/)
  );
  const svelteBlocks = blocks.filter(
    (b) => b.language === "svelte" || b.filename?.match(/\.svelte$/)
  );

  // ── Case 1: Complete HTML file ──
  if (htmlBlocks.length) {
    let html = htmlBlocks[0].code;

    // Check if it's a full document or a fragment
    const isFullDoc = /<!DOCTYPE|<html/i.test(html);

    if (!isFullDoc) {
      html = _wrapFragment(html, cssBlocks, jsBlocks);
    } else {
      // Inject additional CSS blocks
      if (cssBlocks.length) {
        const css = cssBlocks.map((b) => b.code).join("\n\n");
        if (html.includes("</head>")) {
          html = html.replace("</head>", `<style>\n${css}\n</style>\n</head>`);
        } else {
          html = `<style>\n${css}\n</style>\n` + html;
        }
      }
      // Inject additional JS blocks
      if (jsBlocks.length) {
        const js = jsBlocks.map((b) => b.code).join("\n\n");
        if (html.includes("</body>")) {
          html = html.replace("</body>", `<script>\n${js}\n</script>\n</body>`);
        } else {
          html += `\n<script>\n${js}\n</script>`;
        }
      }
      // Auto-inject Tailwind CDN if needed
      html = _injectTailwindIfNeeded(html);
    }
    return html;
  }

  // ── Case 2: React/JSX ──
  if (reactBlocks.length) {
    return _buildReactPreview(reactBlocks, cssBlocks, jsBlocks);
  }

  // ── Case 3: Vue SFC ──
  if (vueBlocks.length) {
    return _buildVuePreview(vueBlocks, cssBlocks);
  }

  // ── Case 4: CSS only (showcase) ──
  if (cssBlocks.length && !jsBlocks.length) {
    return _buildCSSShowcase(cssBlocks);
  }

  // ── Case 5: JS only ──
  if (jsBlocks.length) {
    return _wrapFragment("", cssBlocks, jsBlocks);
  }

  return null;
}

function _wrapFragment(bodyHTML, cssBlocks, jsBlocks) {
  const css = cssBlocks.map((b) => b.code).join("\n\n");
  const js = jsBlocks.map((b) => b.code).join("\n\n");
  const combined = `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>UI Preview</title>
  ${css ? `<style>\n${css}\n</style>` : ""}
</head>
<body>
  ${bodyHTML}
  ${js ? `<script>\n${js}\n</script>` : ""}
</body>
</html>`;
  return _injectTailwindIfNeeded(combined);
}

function _buildReactPreview(reactBlocks, cssBlocks, jsBlocks) {
  const css = cssBlocks.map((b) => b.code).join("\n\n");
  const jsx = reactBlocks.map((b) => b.code).join("\n\n");
  const js = jsBlocks.map((b) => b.code).join("\n\n");

  // Strip import/export statements for browser execution
  const cleanJSX = jsx
    .replace(/^import\s+.*?from\s+['"][^'"]+['"];?\s*$/gm, "")
    .replace(/^export\s+default\s+/gm, "const __DefaultExport__ = ")
    .replace(/^export\s+/gm, "");

  // Find the main component name
  const componentMatch = cleanJSX.match(
    /(?:function|const|class)\s+([A-Z]\w+)/
  );
  const mainComponent = componentMatch
    ? componentMatch[1]
    : "__DefaultExport__";

  const html = `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>React Preview</title>
  <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin><\/script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin><\/script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"><\/script>
  ${css ? `<style>\n${css}\n</style>` : ""}
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
  </style>
</head>
<body>
  <div id="root"></div>
  ${js ? `<script>\n${js}\n<\/script>` : ""}
  <script type="text/babel">
    const { useState, useEffect, useRef, useCallback, useMemo, createContext, useContext, useReducer } = React;
    ${cleanJSX}
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(React.createElement(${mainComponent}));
  <\/script>
</body>
</html>`;
  return _injectTailwindIfNeeded(html);
}

function _buildVuePreview(vueBlocks, cssBlocks) {
  const vue = vueBlocks[0].code;
  const css = cssBlocks.map((b) => b.code).join("\n\n");

  // Extract template, script, style from SFC
  const templateMatch = vue.match(/<template>([\s\S]*?)<\/template>/);
  const scriptMatch = vue.match(/<script[^>]*>([\s\S]*?)<\/script>/);
  const styleMatch = vue.match(/<style[^>]*>([\s\S]*?)<\/style>/);

  const template = templateMatch ? templateMatch[1] : "<div>Vue Component</div>";
  const script = scriptMatch ? scriptMatch[1] : "";
  const style = styleMatch ? styleMatch[1] : "";

  return `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vue Preview</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"><\/script>
  <style>${css}\n${style}</style>
</head>
<body>
  <div id="app">${template}</div>
  <script>
    ${script.replace(/export\s+default\s*/, "const __comp__ = ")}
    Vue.createApp(typeof __comp__ !== 'undefined' ? __comp__ : {}).mount('#app');
  <\/script>
</body>
</html>`;
}

function _buildCSSShowcase(cssBlocks) {
  const css = cssBlocks.map((b) => b.code).join("\n\n");
  return `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS Preview</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; padding: 2rem; }
    ${css}
  </style>
</head>
<body>
  <div class="preview-container">
    <h1>CSS Preview</h1>
    <p>Your styles are applied to this page. Add HTML elements to see them in action.</p>
  </div>
</body>
</html>`;
}

function _injectTailwindIfNeeded(html) {
  if (!TAILWIND_RE.test(html)) return html;
  if (html.includes("tailwindcss") || html.includes("tailwind.")) return html;
  const tailwindScript = '<script src="https://cdn.tailwindcss.com"><\/script>';
  if (html.includes("</head>")) {
    return html.replace("</head>", `  ${tailwindScript}\n</head>`);
  }
  return tailwindScript + "\n" + html;
}

export function isPreviewable(blocks) {
  if (!blocks || !blocks.length) return false;
  const langs = new Set(blocks.map((b) => b.language));
  const files = blocks.map((b) => b.filename || "").join(" ");
  if (langs.has("html") || files.match(/\.html?/)) return true;
  if (langs.has("jsx") || langs.has("tsx") || files.match(/\.(jsx|tsx)/)) return true;
  if (langs.has("vue") || files.match(/\.vue/)) return true;
  if (langs.has("svelte") || files.match(/\.svelte/)) return true;
  // CSS + JS combo
  if (
    (langs.has("css") || langs.has("scss")) &&
    (langs.has("javascript") || langs.has("js"))
  )
    return true;
  // Single HTML-like code that starts with tags
  for (const b of blocks) {
    if (b.code.trim().match(/^<!DOCTYPE|^<html|^<div|^<section|^<main|^<header/i))
      return true;
  }
  return false;
}

/* ═══════════════════════════════════════════════════
   MAIN COMPONENT
   ═══════════════════════════════════════════════════ */
export default function UIPreview({ html: initialHtml, title, onClose }) {
  const [html, setHtml] = useState(initialHtml);
  const [editHtml, setEditHtml] = useState(initialHtml);
  const [viewport, setViewport] = useState("full");
  const [viewMode, setViewMode] = useState("preview");
  const [zoom, setZoom] = useState(100);
  const [copied, setCopied] = useState(false);
  const [blobUrl, setBlobUrl] = useState(null);
  const [iframeKey, setIframeKey] = useState(0);
  const [darkBg, setDarkBg] = useState(false);
  const iframeRef = useRef(null);
  const containerRef = useRef(null);

  // Create blob URL for iframe
  useEffect(() => {
    if (!html) return;
    const blob = new Blob([html], { type: "text/html;charset=utf-8" });
    const url = URL.createObjectURL(blob);
    setBlobUrl(url);
    return () => URL.revokeObjectURL(url);
  }, [html, iframeKey]);

  // Escape key to close
  useEffect(() => {
    const onKey = (e) => {
      if (e.key === "Escape") onClose?.();
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [onClose]);

  const handleRefresh = useCallback(() => {
    setIframeKey((k) => k + 1);
  }, []);

  const handleApplyCode = useCallback(() => {
    setHtml(editHtml);
    setIframeKey((k) => k + 1);
  }, [editHtml]);

  const handleCopy = useCallback(() => {
    navigator.clipboard.writeText(html);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  }, [html]);

  const handleDownload = useCallback(() => {
    const blob = new Blob([html], { type: "text/html" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    const safeName = (title || "design")
      .replace(/[^\w\s-]/g, "")
      .trim()
      .replace(/\s+/g, "-")
      .slice(0, 50);
    a.download = `${safeName || "design"}.html`;
    a.click();
    URL.revokeObjectURL(url);
  }, [html, title]);

  const handleOpenExternal = useCallback(() => {
    if (!html) return;
    const blob = new Blob([html], { type: "text/html;charset=utf-8" });
    const url = URL.createObjectURL(blob);
    window.open(url, "_blank");
    // Don't revoke immediately — let the new tab load
    setTimeout(() => URL.revokeObjectURL(url), 5000);
  }, [html]);

  const handleZoomIn = () =>
    setZoom((z) => Math.min(z + 25, ZOOM_LEVELS[ZOOM_LEVELS.length - 1]));
  const handleZoomOut = () => setZoom((z) => Math.max(z - 25, ZOOM_LEVELS[0]));

  const currentVP = VIEWPORTS.find((v) => v.id === viewport);
  const iframeWidth = currentVP?.width || "100%";
  const iframeHeight = currentVP?.height || "100%";

  const showPreview = viewMode === "preview" || viewMode === "split";
  const showCode = viewMode === "code" || viewMode === "split";

  return (
    <div className="fixed inset-0 z-[100] bg-black/90 backdrop-blur-sm flex flex-col animate-fade-in">
      {/* ═══ HEADER ═══ */}
      <div className="flex items-center gap-2 px-3 py-2 bg-anton-surface border-b border-anton-border shrink-0 flex-wrap">
        {/* Close + Title */}
        <button
          onClick={onClose}
          className="p-1.5 rounded-lg text-anton-muted hover:text-white hover:bg-anton-card transition"
        >
          <X size={18} />
        </button>
        <div className="flex items-center gap-2 min-w-0 mr-2">
          <Paintbrush size={16} className="text-anton-accent shrink-0" />
          <span className="text-sm font-semibold text-white truncate max-w-[200px]">
            {title || "UI Preview"}
          </span>
        </div>

        {/* View Mode Tabs */}
        <div className="flex items-center bg-anton-bg rounded-lg p-0.5 border border-anton-border">
          {[
            { id: "preview", label: "Preview", icon: Eye },
            { id: "code", label: "Code", icon: Code2 },
            { id: "split", label: "Split", icon: Columns },
          ].map(({ id, label, icon: Icon }) => (
            <button
              key={id}
              onClick={() => setViewMode(id)}
              className={`flex items-center gap-1 px-2.5 py-1.5 rounded-md text-xs font-medium transition ${
                viewMode === id
                  ? "bg-anton-accent text-white shadow"
                  : "text-anton-muted hover:text-white"
              }`}
            >
              <Icon size={13} />
              <span className="hidden sm:inline">{label}</span>
            </button>
          ))}
        </div>

        {/* Viewport Controls */}
        <div className="flex items-center gap-0.5 ml-2">
          {VIEWPORTS.map(({ id, label, icon: Icon, width }) => (
            <button
              key={id}
              onClick={() => setViewport(id)}
              className={`p-1.5 rounded-lg transition relative group ${
                viewport === id
                  ? "bg-anton-accent/20 text-anton-accent"
                  : "text-anton-muted hover:text-white hover:bg-anton-card"
              }`}
              title={`${label}${width ? ` (${width}px)` : ""}`}
            >
              <Icon size={15} />
            </button>
          ))}
        </div>

        {/* Zoom */}
        <div className="flex items-center gap-0.5 ml-2">
          <button
            onClick={handleZoomOut}
            className="p-1 rounded text-anton-muted hover:text-white transition"
            disabled={zoom <= ZOOM_LEVELS[0]}
          >
            <ZoomOut size={14} />
          </button>
          <span className="text-[10px] text-anton-muted font-mono w-8 text-center">
            {zoom}%
          </span>
          <button
            onClick={handleZoomIn}
            className="p-1 rounded text-anton-muted hover:text-white transition"
            disabled={zoom >= ZOOM_LEVELS[ZOOM_LEVELS.length - 1]}
          >
            <ZoomIn size={14} />
          </button>
        </div>

        {/* Spacer */}
        <div className="flex-1" />

        {/* Actions */}
        <div className="flex items-center gap-1">
          <button
            onClick={() => setDarkBg(!darkBg)}
            className={`p-1.5 rounded-lg transition ${
              darkBg
                ? "bg-gray-700 text-yellow-300"
                : "text-anton-muted hover:text-white hover:bg-anton-card"
            }`}
            title="Toggle background"
          >
            {darkBg ? <Moon size={14} /> : <Sun size={14} />}
          </button>
          <button
            onClick={handleRefresh}
            className="p-1.5 rounded-lg text-anton-muted hover:text-white hover:bg-anton-card transition"
            title="Refresh preview"
          >
            <RefreshCw size={14} />
          </button>
          <button
            onClick={handleOpenExternal}
            className="p-1.5 rounded-lg text-anton-muted hover:text-white hover:bg-anton-card transition"
            title="Open in new tab"
          >
            <ExternalLink size={14} />
          </button>
          <button
            onClick={handleCopy}
            className="p-1.5 rounded-lg text-anton-muted hover:text-white hover:bg-anton-card transition"
            title="Copy HTML"
          >
            {copied ? (
              <Check size={14} className="text-green-400" />
            ) : (
              <Copy size={14} />
            )}
          </button>
          <button
            onClick={handleDownload}
            className="p-1.5 rounded-lg text-anton-muted hover:text-white hover:bg-anton-card transition"
            title="Download HTML"
          >
            <Download size={14} />
          </button>
        </div>
      </div>

      {/* ═══ VIEWPORT INDICATOR ═══ */}
      {viewport !== "full" && (
        <div className="text-center py-1 text-[10px] text-anton-muted bg-anton-bg/50 border-b border-anton-border shrink-0">
          {currentVP?.label} — {currentVP?.width}×{currentVP?.height}px
          {zoom !== 100 && ` @ ${zoom}%`}
        </div>
      )}

      {/* ═══ MAIN CONTENT ═══ */}
      <div
        ref={containerRef}
        className="flex-1 flex overflow-hidden min-h-0"
      >
        {/* CODE PANEL */}
        {showCode && (
          <div
            className={`flex flex-col bg-[#1a1b26] border-r border-anton-border overflow-hidden ${
              viewMode === "split" ? "w-1/2" : "w-full"
            }`}
          >
            <div className="flex items-center justify-between px-3 py-1.5 border-b border-anton-border bg-anton-surface">
              <span className="text-[10px] text-anton-accent font-mono uppercase">
                HTML
              </span>
              <div className="flex gap-1">
                <button
                  onClick={() => setEditHtml(initialHtml)}
                  className="text-[10px] text-anton-muted hover:text-white px-1.5 py-0.5 rounded transition flex items-center gap-1"
                  title="Reset to original"
                >
                  <RotateCcw size={10} /> Reset
                </button>
                <button
                  onClick={handleApplyCode}
                  className="text-[10px] bg-anton-accent text-white px-2 py-0.5 rounded hover:opacity-80 transition"
                >
                  Apply Changes
                </button>
              </div>
            </div>
            <textarea
              value={editHtml}
              onChange={(e) => setEditHtml(e.target.value)}
              className="flex-1 w-full bg-transparent text-[12px] text-[#d4d4d4] font-mono p-3 resize-none focus:outline-none leading-relaxed"
              spellCheck={false}
              wrap="off"
            />
          </div>
        )}

        {/* PREVIEW PANEL */}
        {showPreview && (
          <div
            className={`flex-1 flex items-start justify-center overflow-auto ${
              darkBg ? "bg-[#0a0a0a]" : "bg-[#f0f0f0]"
            } ${viewMode === "split" ? "w-1/2" : "w-full"}`}
            style={{ padding: viewport === "full" ? 0 : "24px" }}
          >
            <div
              className="relative transition-all duration-300 ease-out"
              style={{
                width:
                  viewport === "full"
                    ? "100%"
                    : `${(currentVP?.width || 1440) * (zoom / 100)}px`,
                height: viewport === "full" ? "100%" : "auto",
                maxWidth: "100%",
              }}
            >
              {/* Device Frame */}
              {viewport !== "full" && (
                <div
                  className={`rounded-xl overflow-hidden shadow-2xl ${
                    darkBg ? "shadow-black/50" : "shadow-gray-400/30"
                  }`}
                  style={{
                    border: `${viewport === "mobile" ? 8 : viewport === "tablet" ? 6 : 2}px solid ${
                      darkBg ? "#222" : "#ccc"
                    }`,
                    borderRadius:
                      viewport === "mobile"
                        ? "32px"
                        : viewport === "tablet"
                          ? "20px"
                          : "8px",
                  }}
                >
                  {/* Notch for mobile */}
                  {viewport === "mobile" && (
                    <div
                      className="flex justify-center py-1"
                      style={{
                        background: darkBg ? "#222" : "#ccc",
                      }}
                    >
                      <div
                        className="rounded-full"
                        style={{
                          width: "80px",
                          height: "6px",
                          background: darkBg ? "#333" : "#aaa",
                        }}
                      />
                    </div>
                  )}
                  {blobUrl && (
                    <iframe
                      ref={iframeRef}
                      key={`frame-${iframeKey}`}
                      src={blobUrl}
                      sandbox="allow-scripts allow-popups allow-forms allow-modals"
                      style={{
                        width: `${currentVP.width}px`,
                        height: `${currentVP.height}px`,
                        transform: `scale(${zoom / 100})`,
                        transformOrigin: "top left",
                        border: "none",
                        display: "block",
                        background: "white",
                      }}
                      title="UI Preview"
                    />
                  )}
                </div>
              )}

              {/* Full responsive mode */}
              {viewport === "full" && blobUrl && (
                <iframe
                  ref={iframeRef}
                  key={`frame-${iframeKey}`}
                  src={blobUrl}
                  sandbox="allow-scripts allow-popups allow-forms allow-modals"
                  className="w-full border-none"
                  style={{
                    height: "100%",
                    minHeight: "calc(100vh - 120px)",
                    transform: zoom !== 100 ? `scale(${zoom / 100})` : undefined,
                    transformOrigin: "top left",
                    background: "white",
                  }}
                  title="UI Preview"
                />
              )}
            </div>
          </div>
        )}
      </div>

      {/* ═══ FOOTER STATUS BAR ═══ */}
      <div className="flex items-center justify-between px-3 py-1.5 bg-anton-surface border-t border-anton-border text-[10px] text-anton-muted shrink-0">
        <span>
          {html.length.toLocaleString()} chars • Sandbox: scripts only
        </span>
        <span>
          Son of Anton UI Preview •{" "}
          <kbd className="px-1 py-0.5 bg-anton-bg rounded text-[9px]">Esc</kbd>{" "}
          to close
        </span>
      </div>
    </div>
  );
}