"use client";

import { FormEvent, useMemo, useState } from "react";
import { Bot, MessageSquareText, Send, X } from "lucide-react";
import { Button } from "@/components/ui/button";
import {
  averageSentiment,
  filterReviews,
  getCuveeCounts,
  getMarketStats,
  getPeriodRange,
  getSourceBreakdown,
  getTopDescriptors
} from "@/lib/analytics";
import { getReviews } from "@/lib/data";
import { getCuvee } from "@/lib/mock-data/cuvees";
import { useOenoscopeStore } from "@/lib/store";
import { sentimentToScore } from "@/lib/utils";

type Message = {
  role: "user" | "assistant";
  content: string;
};

export function DataChatbot() {
  const [open, setOpen] = useState(false);
  const [input, setInput] = useState("");
  const [messages, setMessages] = useState<Message[]>([
    {
      role: "assistant",
      content:
        "Démo : sur la sélection active, le Japon porte le meilleur sentiment, le blanc 2020 ressort fortement sur salinité et tension, et CellarTracker concentre les signaux collectionneurs les plus utiles."
    },
    {
      role: "assistant",
      content:
        "Cette réponse n'est qu'un exemple. Les connecteurs ne sont pas activés à ce stade d'avancement ; les réponses s'appuient sur les données mockées de la démo."
    }
  ]);
  const selectedCuvees = useOenoscopeStore((state) => state.selectedCuvees);
  const period = useOenoscopeStore((state) => state.period);
  const periodMode = useOenoscopeStore((state) => state.periodMode);
  const customRange = useOenoscopeStore((state) => state.customRange);
  const presetRange = getPeriodRange(period);
  const activePeriodFrom = periodMode === "custom" ? customRange.from : presetRange.from;
  const activePeriodTo = periodMode === "custom" ? customRange.to : presetRange.to;

  const scopedReviews = useMemo(() => {
    return filterReviews(getReviews(), { cuveeIds: selectedCuvees, period: { from: activePeriodFrom, to: activePeriodTo } });
  }, [selectedCuvees, activePeriodFrom, activePeriodTo]);

  function submit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const question = input.trim();
    if (!question) return;
    setInput("");
    setMessages((current) => [
      ...current,
      { role: "user", content: question },
      { role: "assistant", content: answerQuestion(question, scopedReviews) }
    ]);
  }

  return (
    <div className="print-hidden fixed bottom-4 right-4 z-50 xl:bottom-5 xl:right-5">
      {open ? (
        <div className="mb-3 w-[min(390px,calc(100vw-2rem))] overflow-hidden rounded-md border border-gold/35 bg-ivory shadow-vellum">
          <div className="flex items-center justify-between border-b border-gold/20 bg-bordeaux-deep px-4 py-3 text-ivory">
            <div className="flex items-center gap-2">
              <Bot className="h-4 w-4 text-gold-pale" strokeWidth={1.5} />
              <div>
                <p className="text-sm font-medium">Questionner les données</p>
                <p className="text-[11px] text-gold-pale">{scopedReviews.length} mentions dans la sélection</p>
              </div>
            </div>
            <button type="button" onClick={() => setOpen(false)} aria-label="Fermer">
              <X className="h-4 w-4" strokeWidth={1.5} />
            </button>
          </div>
          <div className="max-h-[min(380px,calc(100vh-16rem))] space-y-3 overflow-y-auto p-4 scrollbar-thin">
            {messages.map((message, index) => (
              <div
                key={`${message.role}-${index}`}
                className={
                  message.role === "user"
                    ? "ml-8 rounded-md bg-bordeaux-deep px-3 py-2 text-sm leading-relaxed text-ivory"
                    : "mr-8 rounded-md border border-gold/25 bg-ivory-warm px-3 py-2 text-sm leading-relaxed text-charcoal"
                }
              >
                {message.content}
              </div>
            ))}
          </div>
          <form onSubmit={submit} className="flex gap-2 border-t border-gold/20 p-3">
            <input
              value={input}
              onChange={(event) => setInput(event.target.value)}
              placeholder="Ex. top descripteurs du blanc"
              className="h-10 min-w-0 flex-1 rounded-md border border-gold/30 bg-ivory-warm px-3 text-sm outline-none focus:border-bordeaux-deep"
            />
            <Button size="icon" type="submit" aria-label="Envoyer">
              <Send className="h-4 w-4" strokeWidth={1.5} />
            </Button>
          </form>
        </div>
      ) : null}
      <Button onClick={() => setOpen((value) => !value)} className="h-12 rounded-full px-5 shadow-vellum">
        <MessageSquareText className="h-5 w-5" strokeWidth={1.5} />
        Questions données
      </Button>
    </div>
  );
}

function answerQuestion(question: string, reviews: ReturnType<typeof getReviews>) {
  const q = question.toLowerCase();
  if (!reviews.length) return "Aucune mention dans la sélection actuelle. Élargissez la période ou les cuvées.";

  if (q.includes("marché") || q.includes("pays") || q.includes("market")) {
    const markets = getMarketStats(reviews);
    const best = [...markets].sort((a, b) => b.sentiment - a.sentiment)[0];
    const active = markets[0];
    return `${best.name} porte le meilleur sentiment avec ${sentimentToScore(best.sentiment)}/100. En volume, ${active.name} domine avec ${active.mentions} mentions.`;
  }

  if (q.includes("source")) {
    const source = getSourceBreakdown(reviews)[0];
    return `${source.label} est la source la plus présente avec ${source.mentions} mentions. Son sentiment moyen est de ${sentimentToScore(source.sentiment)}/100.`;
  }

  if (q.includes("descripteur") || q.includes("mot") || q.includes("lexique") || q.includes("salinit")) {
    const descriptors = getTopDescriptors(reviews, 5);
    return `Les cinq descripteurs dominants sont : ${descriptors.map((item) => `${item.term} (${item.count})`).join(", ")}.`;
  }

  if (q.includes("blanc") || q.includes("rouge") || q.includes("cuvée") || q.includes("cuvee")) {
    const cuvee = getCuveeCounts(reviews)[0];
    return `${cuvee.name} est la cuvée la plus discutée dans la sélection, avec ${cuvee.mentions} mentions et un sentiment moyen de ${sentimentToScore(cuvee.sentiment)}/100.`;
  }

  if (q.includes("négatif") || q.includes("negatif") || q.includes("risque") || q.includes("alerte")) {
    const negative = reviews.filter((review) => review.sentiment === "negative");
    const sample = negative[0];
    if (!sample) return "Aucun avis négatif significatif dans la sélection actuelle.";
    return `${negative.length} avis négatifs sont présents. Le cas le plus utile à vérifier concerne ${getCuvee(sample.cuveeId).name} ${sample.vintage}, source ${sample.source}, marché ${sample.market}.`;
  }

  return `Dans la sélection actuelle : ${reviews.length} mentions, sentiment moyen ${sentimentToScore(averageSentiment(reviews))}/100. Les sujets les plus utiles à creuser sont les marchés, les sources, les cuvées et les descripteurs.`;
}
