"use client";

import * as React from "react";
import { ArrowRightLeft, Clipboard, Copy, Download, Upload } from "lucide-react";

import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
import { downloadMarkdown } from "@/lib/export";
import { getHtmlToMarkdown } from "@/lib/html-to-markdown";
import { useDebouncedValue } from "@/hooks/use-debounce";
import { useToast } from "@/hooks/use-toast";

const SAMPLE = `<h1>Hello, world</h1>
<p>This is a <strong>rich text</strong> HTML snippet that we'll convert to Markdown.</p>
<ul>
  <li>Bulleted item</li>
  <li>Another item with a <a href="https://trymarkdownviewer.com">link</a></li>
</ul>
<pre><code class="language-ts">const greet = (name) =&gt; \`Hello, \${name}!\`;</code></pre>
<table>
  <thead><tr><th>Feature</th><th>Status</th></tr></thead>
  <tbody>
    <tr><td>Tables</td><td>✅</td></tr>
    <tr><td>Task lists</td><td>✅</td></tr>
  </tbody>
</table>`;

export function HtmlToMarkdownConverter() {
  const { toast } = useToast();
  const [html, setHtml] = React.useState(SAMPLE);
  const [markdown, setMarkdown] = React.useState("");
  const [autoConvert, setAutoConvert] = React.useState(true);
  const [busy, setBusy] = React.useState(false);
  const debouncedHtml = useDebouncedValue(html, 280);
  const fileInputRef = React.useRef<HTMLInputElement>(null);

  React.useEffect(() => {
    if (!autoConvert) return;
    let cancelled = false;
    setBusy(true);
    getHtmlToMarkdown()
      .then((toMd) => {
        if (cancelled) return;
        setMarkdown(toMd(debouncedHtml));
      })
      .catch((err: unknown) => {
        if (cancelled) return;
        toast({
          title: "Conversion failed",
          description: err instanceof Error ? err.message : String(err),
          variant: "destructive",
        });
      })
      .finally(() => {
        if (!cancelled) setBusy(false);
      });
    return () => {
      cancelled = true;
    };
  }, [debouncedHtml, autoConvert, toast]);

  async function convertNow() {
    setBusy(true);
    try {
      const toMd = await getHtmlToMarkdown();
      setMarkdown(toMd(html));
    } catch (err: unknown) {
      toast({
        title: "Conversion failed",
        description: err instanceof Error ? err.message : String(err),
        variant: "destructive",
      });
    } finally {
      setBusy(false);
    }
  }

  async function pasteHtml() {
    try {
      const clip = await navigator.clipboard.read();
      for (const item of clip) {
        if (item.types.includes("text/html")) {
          const blob = await item.getType("text/html");
          const text = await blob.text();
          setHtml(text);
          toast({ title: "Pasted HTML from clipboard" });
          return;
        }
      }
      // Fallback to plain text.
      const text = await navigator.clipboard.readText();
      setHtml(text);
    } catch {
      toast({ title: "Clipboard access denied", variant: "destructive" });
    }
  }

  function importFile(file: File) {
    const reader = new FileReader();
    reader.onload = () => setHtml(String(reader.result ?? ""));
    reader.readAsText(file);
  }

  async function copyMarkdown() {
    await navigator.clipboard.writeText(markdown);
    toast({ title: "Markdown copied" });
  }

  function downloadMd() {
    downloadMarkdown(markdown, "converted.md");
  }

  return (
    <section className="container py-10">
      <div className="mx-auto mb-6 flex max-w-5xl flex-wrap items-center justify-between gap-3">
        <div className="flex items-center gap-2 text-sm">
          <Switch
            id="auto"
            checked={autoConvert}
            onCheckedChange={setAutoConvert}
            aria-label="Auto-convert as you type"
          />
          <Label htmlFor="auto" className="text-xs">
            Auto-convert
          </Label>
          {!autoConvert ? (
            <Button size="sm" onClick={convertNow} disabled={busy}>
              <ArrowRightLeft className="h-4 w-4" /> Convert
            </Button>
          ) : null}
        </div>
        <div className="flex flex-wrap items-center gap-2 text-xs">
          <Button size="sm" variant="outline" onClick={pasteHtml}>
            <Clipboard className="h-3.5 w-3.5" /> Paste HTML
          </Button>
          <Button size="sm" variant="outline" onClick={() => fileInputRef.current?.click()}>
            <Upload className="h-3.5 w-3.5" /> Import .html
          </Button>
          <Button size="sm" variant="outline" onClick={copyMarkdown} disabled={!markdown}>
            <Copy className="h-3.5 w-3.5" /> Copy markdown
          </Button>
          <Button size="sm" onClick={downloadMd} disabled={!markdown}>
            <Download className="h-3.5 w-3.5" /> Download .md
          </Button>
          <input
            ref={fileInputRef}
            type="file"
            accept=".html,.htm,text/html"
            className="sr-only"
            onChange={(e) => {
              const file = e.target.files?.[0];
              if (file) importFile(file);
              e.currentTarget.value = "";
            }}
          />
        </div>
      </div>

      <div className="mx-auto grid max-w-5xl gap-4 lg:grid-cols-2">
        <div className="overflow-hidden rounded-xl border bg-card">
          <div className="flex items-center justify-between border-b px-3 py-2">
            <span className="text-xs font-medium uppercase tracking-wider text-muted-foreground">
              HTML input
            </span>
            <span className="text-[10px] text-muted-foreground">{html.length.toLocaleString()} chars</span>
          </div>
          <textarea
            value={html}
            onChange={(e) => setHtml(e.target.value)}
            spellCheck={false}
            className="scrollbar-thin h-[480px] w-full resize-none bg-background p-4 font-mono text-xs leading-relaxed outline-none"
            aria-label="HTML input"
          />
        </div>
        <div className="overflow-hidden rounded-xl border bg-card">
          <div className="flex items-center justify-between border-b px-3 py-2">
            <span className="text-xs font-medium uppercase tracking-wider text-muted-foreground">
              Markdown output {busy ? "· converting…" : ""}
            </span>
            <span className="text-[10px] text-muted-foreground">{markdown.length.toLocaleString()} chars</span>
          </div>
          <textarea
            value={markdown}
            readOnly
            spellCheck={false}
            className="scrollbar-thin h-[480px] w-full resize-none bg-background p-4 font-mono text-xs leading-relaxed outline-none"
            aria-label="Markdown output"
          />
        </div>
      </div>
    </section>
  );
}
