"use client";

import { useEffect, useMemo, useState } from "react";
import {
  Bot, ChevronDown, Folder, History, Menu, MessageSquarePlus, Paperclip,
  Search, Send, Settings, Sparkles, X, Zap, GitCompare, Globe, Copy, Check
} from "lucide-react";
import { MODELS, PROVIDERS, type ProviderId } from "@/lib/models";

type Msg = { role: "user" | "assistant"; content: string; provider?: string; model?: string };
type Conversation = { id: string; title: string; provider: string; model: string; messages: Msg[] };
type CompareResult = { provider: string; model: string; answer: string; error?: string };

const suggestions = [
  "Écris-moi un site web moderne",
  "Explique-moi un concept simplement",
  "Aide-moi à coder un projet",
  "Donne-moi des idées de business",
];

export function ModelBoxApp() {
  const [mobile, setMobile] = useState(false);
  const [provider, setProvider] = useState<ProviderId>("google");
  const [model, setModel] = useState("gemini-2.5-flash");
  const [input, setInput] = useState("");
  const [loading, setLoading] = useState(false);
  const [conversations, setConversations] = useState<Conversation[]>([]);
  const [activeId, setActiveId] = useState<string | null>(null);
  const [search, setSearch] = useState("");
  const [compare, setCompare] = useState(false);
  const [compareResults, setCompareResults] = useState<CompareResult[]>([]);
  const [copied, setCopied] = useState(false);

  const active = conversations.find(c => c.id === activeId) ?? null;
  const providerModels = useMemo(() => MODELS.filter(m => m.provider === provider), [provider]);

  useEffect(() => {
    const saved = localStorage.getItem("modelbox-conversations");
    if (saved) {
      try {
        const data = JSON.parse(saved) as Conversation[];
        setConversations(data);
        if (data[0]) {
          setActiveId(data[0].id);
          setProvider(data[0].provider as ProviderId);
          setModel(data[0].model);
        }
      } catch {}
    }
  }, []);

  useEffect(() => {
    localStorage.setItem("modelbox-conversations", JSON.stringify(conversations));
  }, [conversations]);

  useEffect(() => {
    if (!providerModels.some(m => m.id === model) && providerModels[0]) {
      setModel(providerModels[0].id);
    }
  }, [providerModels, model]);

  function newChat() {
    const id = crypto.randomUUID();
    const chat: Conversation = {
      id,
      title: "Nouvelle conversation",
      provider,
      model,
      messages: [],
    };
    setConversations(cs => [chat, ...cs]);
    setActiveId(id);
    setCompareResults([]);
    setMobile(false);
  }

  function ensureActive() {
    if (active) return active;
    const id = crypto.randomUUID();
    const chat: Conversation = { id, title: "Nouvelle conversation", provider, model, messages: [] };
    setConversations(cs => [chat, ...cs]);
    setActiveId(id);
    return chat;
  }

  async function send() {
    const text = input.trim();
    if (!text || loading) return;

    const chat = ensureActive();
    const userMsg: Msg = { role: "user", content: text, provider, model };
    const history = [...chat.messages, userMsg];

    setConversations(cs => cs.map(c => c.id === chat.id ? {
      ...c,
      title: c.messages.length ? c.title : text.slice(0, 48),
      provider,
      model,
      messages: history,
    } : c));
    setInput("");
    setCompareResults([]);
    setLoading(true);

    try {
      if (compare) {
        const picks = MODELS.filter(m => m.free).slice(0, 4).map(m => ({
          provider: m.provider,
          model: m.id,
        }));
        const res = await fetch("/api/compare", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            prompts: picks,
            messages: history,
          }),
        });
        const data = await res.json();
        if (!res.ok) throw new Error(data.error || "Erreur de comparaison");
        setCompareResults(data.results || []);
      } else {
        const res = await fetch("/api/chat", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            provider,
            model,
            messages: history,
          }),
        });
        const data = await res.json();
        if (!res.ok) throw new Error(data.error || "Erreur API");
        const answer: Msg = { role: "assistant", content: data.answer, provider, model };
        setConversations(cs => cs.map(c => c.id === chat.id ? { ...c, messages: [...history, answer] } : c));
      }
    } catch (e) {
      const answer: Msg = {
        role: "assistant",
        content: `Erreur : ${e instanceof Error ? e.message : "Impossible de contacter le modèle."}`,
        provider,
        model,
      };
      setConversations(cs => cs.map(c => c.id === chat.id ? { ...c, messages: [...history, answer] } : c));
    } finally {
      setLoading(false);
    }
  }

  function selectProvider(id: ProviderId) {
    setProvider(id);
    const first = MODELS.find(m => m.provider === id);
    if (first) setModel(first.id);
  }

  async function copyLast() {
    const last = [...(active?.messages || [])].reverse().find(m => m.role === "assistant");
    if (!last) return;
    await navigator.clipboard?.writeText(last.content);
    setCopied(true);
    setTimeout(() => setCopied(false), 1200);
  }

  const visible = conversations.filter(c => c.title.toLowerCase().includes(search.toLowerCase()));
  const providerName = PROVIDERS.find(p => p.id === provider)?.name || provider;
  const modelName = MODELS.find(m => m.id === model)?.name || model;

  return (
    <div className="min-h-screen bg-[#08090b] text-zinc-100 flex">
      <aside className={`${mobile ? "fixed inset-y-0 left-0 z-50 flex" : "hidden"} lg:flex w-[285px] shrink-0 flex-col border-r border-white/8 bg-[#0b0c0f]`}>
        <div className="h-16 px-5 flex items-center justify-between border-b border-white/8">
          <div className="flex items-center gap-2 font-semibold tracking-tight">
            <div className="w-8 h-8 rounded-lg bg-white text-black grid place-items-center"><Sparkles size={17}/></div>
            ModelBox
          </div>
          <button onClick={() => setMobile(false)} className="lg:hidden p-2 text-zinc-400"><X size={18}/></button>
        </div>
        <div className="p-3">
          <button onClick={newChat} className="w-full flex items-center gap-2 justify-center rounded-xl bg-white text-black py-2.5 text-sm font-medium hover:bg-zinc-200">
            <MessageSquarePlus size={17}/> Nouvelle conversation
          </button>
        </div>
        <div className="px-3 pb-2">
          <div className="relative">
            <Search size={15} className="absolute left-3 top-2.5 text-zinc-500"/>
            <input value={search} onChange={e=>setSearch(e.target.value)} placeholder="Rechercher" className="w-full bg-[#111216] border border-white/8 rounded-lg pl-9 pr-3 py-2 text-sm outline-none focus:border-white/20"/>
          </div>
        </div>
        <div className="px-3 text-[11px] uppercase tracking-wider text-zinc-500 mt-2 mb-1">Conversations</div>
        <div className="px-2 space-y-0.5 overflow-y-auto flex-1">
          {visible.map(c =>
            <button key={c.id} onClick={()=>{setActiveId(c.id);setProvider(c.provider as ProviderId);setModel(c.model);setMobile(false)}} className={`w-full text-left flex gap-2 items-center px-3 py-2.5 rounded-lg text-sm ${c.id===activeId?"bg-white/8 text-white":"text-zinc-400 hover:bg-white/5 hover:text-zinc-200"}`}>
              <History size={15}/><span className="truncate">{c.title}</span>
            </button>
          )}
          {!visible.length && <div className="text-xs text-zinc-600 px-3 py-3">Aucune conversation.</div>}
        </div>
        <div className="p-3 border-t border-white/8 space-y-1">
          <a href="/settings" className="flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-zinc-400 hover:bg-white/5"><Settings size={16}/> Paramètres</a>
          <div className="flex items-center gap-2 px-3 py-2 text-xs text-zinc-600"><Zap size={14}/> ModelBox · MOV-Corp</div>
        </div>
      </aside>

      {mobile && <button aria-label="Fermer" onClick={()=>setMobile(false)} className="fixed inset-0 z-40 bg-black/60 lg:hidden"/>}

      <main className="flex-1 min-w-0 flex flex-col">
        <header className="h-16 shrink-0 border-b border-white/8 bg-[#08090b]/90 backdrop-blur flex items-center justify-between px-3 sm:px-6">
          <div className="flex items-center gap-2">
            <button onClick={()=>setMobile(true)} className="lg:hidden p-2 text-zinc-400"><Menu size={19}/></button>

            <div className="relative">
              <select value={provider} onChange={e=>selectProvider(e.target.value as ProviderId)} className="appearance-none bg-[#111216] border border-white/10 rounded-lg pl-3 pr-8 py-2 text-sm outline-none">
                {PROVIDERS.map(p=><option key={p.id} value={p.id}>{p.name}{p.free?" · gratuit":""}</option>)}
              </select>
              <ChevronDown size={14} className="absolute right-2.5 top-2.5 pointer-events-none text-zinc-500"/>
            </div>

            <div className="relative hidden sm:block">
              <select value={model} onChange={e=>setModel(e.target.value)} className="appearance-none bg-transparent border-0 pl-2 pr-7 py-2 text-sm text-zinc-300 outline-none">
                {providerModels.map(m=><option key={m.id} value={m.id}>{m.name}{m.free?" · gratuit":""}</option>)}
              </select>
              <ChevronDown size={14} className="absolute right-1 top-2.5 pointer-events-none text-zinc-600"/>
            </div>
          </div>

          <div className="flex items-center gap-1">
            <button onClick={()=>setCompare(v=>!v)} className={`px-3 py-2 rounded-lg text-xs border flex items-center gap-1.5 ${compare?"bg-white text-black border-white":"border-white/10 text-zinc-400 hover:text-white"}`}>
              <GitCompare size={14}/> Comparer
            </button>
            <a href="/settings" className="p-2 text-zinc-400 hover:text-white"><Settings size={18}/></a>
          </div>
        </header>

        <section className="flex-1 overflow-y-auto">
          <div className="max-w-4xl mx-auto px-4 sm:px-6 py-8">
            {!active && (
              <div className="min-h-[62vh] grid place-items-center text-center">
                <div className="max-w-2xl">
                  <div className="mx-auto w-14 h-14 rounded-2xl border border-white/10 bg-white/5 grid place-items-center mb-5"><Sparkles size={25}/></div>
                  <h1 className="text-4xl sm:text-5xl font-semibold tracking-tight">One workspace.<br/><span className="text-zinc-500">Every AI.</span></h1>
                  <p className="text-zinc-500 mt-4 max-w-xl mx-auto">Choisis Google Gemini, OpenAI, Claude, Mistral, Groq, OpenRouter et d'autres modèles dans une seule interface.</p>
                  <div className="grid sm:grid-cols-2 gap-2 mt-8">
                    {suggestions.map(s=><button key={s} onClick={()=>{newChat();setTimeout(()=>setInput(s),0)}} className="text-left border border-white/8 rounded-xl p-3 text-sm text-zinc-400 hover:text-white hover:bg-white/5">{s}</button>)}
                  </div>
                  <div className="flex flex-wrap justify-center gap-3 mt-7 text-[11px] text-zinc-600">
                    <span className="flex gap-1 items-center"><GitCompare size={13}/> Comparaison multi-modèles</span>
                    <span className="flex gap-1 items-center"><Folder size={13}/> Projets</span>
                    <span className="flex gap-1 items-center"><Bot size={13}/> Assistants</span>
                    <span className="flex gap-1 items-center"><Globe size={13}/> Web search ready</span>
                  </div>
                </div>
              </div>
            )}

            {active?.messages.map((m,i)=>
              <div key={i} className="mb-8 flex gap-3">
                <div className={`w-8 h-8 shrink-0 rounded-lg grid place-items-center text-[10px] font-bold ${m.role==="user"?"bg-white text-black":"bg-white/8 text-zinc-300"}`}>
                  {m.role==="user"?"TOI":<Bot size={15}/>}
                </div>
                <div className="min-w-0 pt-1">
                  {m.role==="assistant" && <div className="text-[10px] text-zinc-600 mb-1">{m.model || modelName} · {m.provider || providerName}</div>}
                  <div className="whitespace-pre-wrap leading-7 text-[15px] text-zinc-200">{m.content}</div>
                </div>
              </div>
            )}

            {compareResults.length > 0 && (
              <div className="grid md:grid-cols-2 gap-3 mt-4">
                {compareResults.map((r,i)=>
                  <div key={i} className="rounded-2xl border border-white/10 bg-[#0d0f12] overflow-hidden">
                    <div className="px-4 py-3 border-b border-white/8 flex items-center justify-between">
                      <div className="min-w-0"><div className="text-sm font-medium truncate">{MODELS.find(m=>m.id===r.model)?.name || r.model}</div><div className="text-[10px] text-zinc-600">{PROVIDERS.find(p=>p.id===r.provider)?.name || r.provider}</div></div>
                      <span className="text-[9px] px-2 py-1 rounded-full bg-white/5 text-zinc-500">AI {i+1}</span>
                    </div>
                    <div className="p-4 text-sm leading-6 text-zinc-300 whitespace-pre-wrap max-h-[430px] overflow-y-auto">{r.error ? `Erreur : ${r.error}` : r.answer}</div>
                  </div>
                )}
              </div>
            )}

            {loading && <div className="flex gap-3 text-zinc-500"><div className="w-8 h-8 rounded-lg bg-white/8 grid place-items-center"><Bot size={15}/></div><div className="pt-1 flex gap-1"><span>●</span><span className="opacity-60">●</span><span className="opacity-30">●</span></div></div>}
          </div>
        </section>

        <div className="p-3 sm:p-5">
          <div className="max-w-4xl mx-auto">
            {compare && <div className="mb-2 text-[11px] text-zinc-500 flex items-center gap-1"><GitCompare size={13}/> Comparaison active : ModelBox interrogera plusieurs modèles gratuits/quota en parallèle.</div>}
            <div className="rounded-2xl border border-white/10 bg-[#101114] shadow-2xl">
              <textarea value={input} onChange={e=>setInput(e.target.value)} onKeyDown={e=>{if(e.key==="Enter"&&!e.shiftKey){e.preventDefault();send()}}} placeholder={`Message à ${modelName}…`} rows={3} className="w-full resize-none bg-transparent px-4 pt-4 pb-2 outline-none text-[15px] placeholder:text-zinc-600"/>
              <div className="flex items-center justify-between px-3 pb-3">
                <div className="flex gap-1 items-center">
                  <button title="Pièce jointe" className="p-2 rounded-lg text-zinc-500 hover:bg-white/5 hover:text-zinc-300"><Paperclip size={17}/></button>
                  <button title="Recherche web" className="p-2 rounded-lg text-zinc-500 hover:bg-white/5 hover:text-zinc-300"><Globe size={17}/></button>
                  <span className="hidden sm:block text-xs text-zinc-600">Entrée pour envoyer · Shift+Entrée pour une nouvelle ligne</span>
                </div>
                <div className="flex gap-1">
                  {active?.messages.some(m=>m.role==="assistant") && <button title="Copier la dernière réponse" onClick={copyLast} className="p-2 rounded-lg text-zinc-500 hover:bg-white/5">{copied?<Check size={16}/>:<Copy size={16}/>}</button>}
                  <button onClick={send} disabled={loading || !input.trim()} className="w-9 h-9 rounded-lg bg-white text-black grid place-items-center disabled:opacity-30"><Send size={16}/></button>
                </div>
              </div>
            </div>
            <div className="text-center text-[10px] text-zinc-700 mt-2">Les quotas et conditions des fournisseurs peuvent changer.</div>
          </div>
        </div>
      </main>
    </div>
  );
}
