type Platform = "TikTok" | "Instagram" | "YouTube Shorts" | "X" | "Universal";
type HashtagDatabase = {
  topics: Record<string, string[]>;
  platforms: Record<Platform, string[]>;
  intent: string[];
  aliases?: Record<string, string[]>;
};
type Search = { topic: string; platform: Platform; count: number; createdAt: number };

declare const React: typeof import("react");
declare const ReactDOM: typeof import("react-dom/client");

const { useEffect, useMemo, useState } = React;
const HISTORY_KEY = "vyroclips-hashtag-history";
const PLATFORMS: Platform[] = ["TikTok", "Instagram", "YouTube Shorts", "X", "Universal"];
const COUNTS = [10, 20, 30, 50];

const cleanTag = (value: string) => value.toLowerCase().replace(/[^a-z0-9]/g, "");
const shuffled = <T,>(items: T[]) => {
  const copy = [...items];
  for (let i = copy.length - 1; i > 0; i -= 1) {
    const j = Math.floor(Math.random() * (i + 1));
    [copy[i], copy[j]] = [copy[j], copy[i]];
  }
  return copy;
};

function matchedCategories(topic: string, db: HashtagDatabase): string[] {
  const phrase = cleanTag(topic);
  const words = topic.toLowerCase().split(/[^a-z0-9]+/).map(cleanTag).filter(word => word.length > 1);
  return Object.keys(db.topics).filter(category => {
    const categoryKey = cleanTag(category);
    const aliases = (db.aliases?.[category] ?? []).map(cleanTag);
    const keywords = [categoryKey, ...aliases];
    return keywords.some(keyword => keyword === phrase || words.includes(keyword));
  });
}

function topicVariants(topic: string, intents: string[]): string[] {
  const phrase = cleanTag(topic);
  const words = topic.toLowerCase().split(/[^a-z0-9]+/).map(cleanTag).filter(word => word.length > 2);
  return [
    phrase,
    ...words,
    ...intents.map(intent => `${phrase}${cleanTag(intent)}`),
    `${phrase}community`, `${phrase}content`, `${phrase}video`, `${phrase}news`,
    `${phrase}tips`, `${phrase}ideas`, `${phrase}guide`, `${phrase}explained`,
    `daily${phrase}`, `${phrase}daily`, `${phrase}life`, `${phrase}lover`,
    `${phrase}talk`, `${phrase}updates`, `${phrase}facts`, `${phrase}basics`,
    `${phrase}101`, `${phrase}trends`, `${phrase}strategy`, `${phrase}inspiration`,
    `${phrase}tutorial`, `${phrase}beginners`, `${phrase}expert`, `${phrase}world`,
    `best${phrase}`, `top${phrase}`, `learn${phrase}`, `discover${phrase}`,
    `${phrase}hacks`, `${phrase}lessons`, `${phrase}resources`, `${phrase}stories`,
    `${phrase}review`, `${phrase}reviews`, `${phrase}recommendations`, `${phrase}insights`,
    `${phrase}knowledge`, `${phrase}education`, `${phrase}questions`, `${phrase}answers`,
    `${phrase}howto`, `${phrase}deepdive`, `${phrase}spotlight`, `${phrase}forbeginners`,
    `${phrase}professionals`, `${phrase}enthusiast`, `${phrase}fans`, `${phrase}online`,
    `${phrase}today`, `${phrase}weekly`, `${phrase}update`, `${phrase}discussion`,
    `${phrase}explore`, `${phrase}focus`, `${phrase}skills`, `${phrase}goals`
  ];
}

function generateHashtags(topic: string, platform: Platform, count: number, db: HashtagDatabase): string[] {
  const phrase = cleanTag(topic);
  const categories = matchedCategories(topic, db);
  const categoryTags = categories.flatMap(category => db.topics[category]);
  const derivedTags = topicVariants(topic, db.intent);
  // Make platform signals topic-specific instead of adding broad filler such as
  // #tiktokcreator or #trending.
  const platformTags: Record<Platform, string[]> = {
    "TikTok": [`${phrase}tok`, `${phrase}tiktok`],
    "Instagram": [`${phrase}reels`, `${phrase}instagram`],
    "YouTube Shorts": [`${phrase}shorts`, `${phrase}youtube`],
    "X": [`${phrase}x`, `${phrase}twitter`],
    "Universal": []
  };
  const randomizedCategoryTags = shuffled(categoryTags);
  const pool = [
    phrase,
    ...randomizedCategoryTags.slice(0, 8),
    ...platformTags[platform],
    ...randomizedCategoryTags.slice(8),
    ...derivedTags
  ];
  const unique = [...new Set(pool.map(cleanTag).filter(Boolean))];
  return unique.slice(0, count).map(tag => `#${tag}`);
}

function FieldLabel({ children }: React.PropsWithChildren) {
  return <label className="mb-2 block text-sm font-bold text-gray-800">{children}</label>;
}

function History({ items, onSelect }: { items: Search[]; onSelect: (item: Search) => void }) {
  if (!items.length) return null;
  return (
    <aside className="mt-6 min-w-0 max-w-full border-t border-gray-100 pt-5" aria-label="Recent searches">
      <div className="mb-3 flex items-center justify-between">
        <h3 className="text-xs font-black uppercase tracking-[.16em] text-gray-400">Recent searches</h3>
        <span className="text-xs text-gray-400">Saved on this device</span>
      </div>
      <div className="flex w-full min-w-0 max-w-full gap-2 overflow-x-auto pb-2">
        {items.map(item => (
          <button key={item.createdAt} onClick={() => onSelect(item)} className="history-pill whitespace-nowrap rounded-full border border-gray-200 bg-white px-3 py-2 text-xs font-semibold text-gray-600 transition hover:border-cyan-300 hover:text-cyan-700">
            {item.topic} · {item.platform}
          </button>
        ))}
      </div>
    </aside>
  );
}

function Results({ tags, onShuffle }: { tags: string[]; onShuffle: () => void }) {
  const [copied, setCopied] = useState<string | null>(null);
  const copy = async (value: string, label: string) => {
    await navigator.clipboard.writeText(value);
    setCopied(label);
    window.setTimeout(() => setCopied(null), 1600);
  };

  if (!tags.length) {
    return (
      <div className="results-empty flex min-h-[330px] flex-col items-center justify-center rounded-3xl border border-dashed border-gray-200 bg-gray-50/60 px-6 text-center">
        <div className="mb-4 flex h-14 w-14 items-center justify-center rounded-2xl bg-cyan-100 text-2xl text-cyan-700">#</div>
        <h3 className="mb-2 text-lg font-black text-gray-900">Your hashtags will appear here</h3>
        <p className="max-w-sm text-sm leading-relaxed text-gray-500">Enter a topic and choose a platform. We’ll mix focused, discovery, and platform-native tags.</p>
      </div>
    );
  }

  return (
    <section aria-live="polite" aria-label="Generated hashtags">
      <div className="mb-5 flex flex-wrap items-center justify-between gap-3">
        <div><h2 className="text-xl font-black text-gray-900">Ready to post</h2><p className="text-sm text-gray-500">{tags.length} unique hashtags</p></div>
        <div className="flex gap-2">
          <button onClick={onShuffle} className="tool-button rounded-full border border-gray-200 bg-white px-4 py-2.5 text-sm font-bold text-gray-700 hover:border-cyan-300 hover:text-cyan-700">↻ Shuffle</button>
          <button onClick={() => copy(tags.join(" "), "all")} className="rounded-full bg-gray-900 px-5 py-2.5 text-sm font-bold text-white transition hover:bg-cyan-700">{copied === "all" ? "Copied!" : "Copy all"}</button>
        </div>
      </div>
      <div className="tag-panel flex min-h-[250px] min-w-0 max-w-full flex-wrap content-start gap-2.5 rounded-3xl border border-cyan-100 bg-cyan-50/50 p-5">
        {tags.map(tag => (
          <button key={tag} onClick={() => copy(tag, tag)} title={`Copy ${tag}`} className="hashtag-chip max-w-full break-all rounded-full border border-cyan-200 bg-white px-3.5 py-2 text-sm font-semibold text-cyan-800 shadow-sm transition hover:-translate-y-0.5 hover:border-cyan-400 hover:shadow-md">
            {copied === tag ? "Copied!" : tag}
          </button>
        ))}
      </div>
      <p className="mt-3 text-xs leading-relaxed text-gray-400">Tip: tap any hashtag to copy it. Review your platform’s current hashtag guidance before publishing.</p>
    </section>
  );
}

function HashtagGenerator() {
  const [db, setDb] = useState<HashtagDatabase | null>(null);
  const [topic, setTopic] = useState("");
  const [platform, setPlatform] = useState<Platform>("TikTok");
  const [count, setCount] = useState(20);
  const [tags, setTags] = useState<string[]>([]);
  const [error, setError] = useState("");
  const [history, setHistory] = useState<Search[]>(() => {
    try { return JSON.parse(localStorage.getItem(HISTORY_KEY) ?? "[]"); } catch { return []; }
  });

  useEffect(() => {
    fetch("/static/hashtags.json")
      .then(response => response.ok ? response.json() : Promise.reject(new Error("Database unavailable")))
      .then(setDb)
      .catch(() => setError("The local hashtag library could not be loaded. Please refresh and try again."));
  }, []);

  const canGenerate = useMemo(() => topic.trim().length >= 2 && Boolean(db), [topic, db]);
  const submit = (event?: React.FormEvent) => {
    event?.preventDefault();
    if (!canGenerate || !db) { setError("Enter at least two characters for your topic."); return; }
    setError("");
    setTags(generateHashtags(topic.trim(), platform, count, db));
    const next = [{ topic: topic.trim(), platform, count, createdAt: Date.now() }, ...history.filter(item => !(item.topic.toLowerCase() === topic.trim().toLowerCase() && item.platform === platform))].slice(0, 10);
    setHistory(next);
    localStorage.setItem(HISTORY_KEY, JSON.stringify(next));
  };
  const selectHistory = (item: Search) => { setTopic(item.topic); setPlatform(item.platform); setCount(item.count); if (db) setTags(generateHashtags(item.topic, item.platform, item.count, db)); };

  return (
    <div className="generator-card w-full min-w-0 max-w-full overflow-hidden rounded-[2rem] border border-gray-200 bg-white shadow-[0_24px_80px_rgba(15,23,42,.10)]">
      <div className="grid min-w-0 grid-cols-1 lg:grid-cols-[minmax(0,.86fr)_minmax(0,1.14fr)]">
        <form onSubmit={submit} className="generator-form min-w-0 max-w-full border-b border-gray-100 p-6 sm:p-8 lg:border-b-0 lg:border-r">
          <div className="mb-7"><span className="mb-2 inline-block text-xs font-black uppercase tracking-[.18em] text-cyan-600">Build your set</span><h2 className="text-2xl font-black text-gray-900">What is your post about?</h2></div>
          <div className="mb-5">
            <FieldLabel>Topic</FieldLabel>
            <input value={topic} onChange={event => setTopic(event.target.value)} placeholder="e.g. podcast marketing" maxLength={80} autoFocus className="generator-input w-full rounded-2xl border border-gray-200 bg-white px-4 py-3.5 text-gray-900 outline-none transition placeholder:text-gray-400 focus:border-cyan-400 focus:ring-4 focus:ring-cyan-100" />
            <div className="mt-2 flex flex-wrap gap-1.5">{["fitness", "small business", "travel", "AI tools"].map(example => <button type="button" key={example} onClick={() => setTopic(example)} className="text-xs font-semibold text-gray-400 hover:text-cyan-700">{example}</button>)}</div>
          </div>
          <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-1 xl:grid-cols-2">
            <div><FieldLabel>Platform</FieldLabel><select value={platform} onChange={event => setPlatform(event.target.value as Platform)} className="generator-input w-full rounded-2xl border border-gray-200 bg-white px-4 py-3.5 text-sm font-semibold text-gray-800 outline-none focus:border-cyan-400 focus:ring-4 focus:ring-cyan-100">{PLATFORMS.map(item => <option key={item}>{item}</option>)}</select></div>
            <div><FieldLabel>Number of hashtags</FieldLabel><select value={count} onChange={event => setCount(Number(event.target.value))} className="generator-input w-full rounded-2xl border border-gray-200 bg-white px-4 py-3.5 text-sm font-semibold text-gray-800 outline-none focus:border-cyan-400 focus:ring-4 focus:ring-cyan-100">{COUNTS.map(item => <option key={item} value={item}>{item} hashtags</option>)}</select></div>
          </div>
          {error && <p role="alert" className="mt-4 rounded-xl bg-rose-50 px-3 py-2 text-sm font-medium text-rose-700">{error}</p>}
          <button type="submit" disabled={!canGenerate} className="mt-6 w-full rounded-full bg-gradient-to-r from-cyan-500 to-sky-600 px-6 py-4 text-sm font-black text-white shadow-lg shadow-cyan-500/25 transition hover:-translate-y-0.5 hover:shadow-xl disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:translate-y-0">{db ? "Generate hashtags →" : "Loading hashtag library…"}</button>
          <History items={history} onSelect={selectHistory} />
        </form>
        <div className="min-w-0 max-w-full p-6 sm:p-8"><Results tags={tags} onShuffle={() => setTags(shuffled(tags))} /></div>
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("hashtag-generator-root")!).render(<HashtagGenerator />);
