/**
 * Suggested FAQs Dashboard Component
 *
 * Shows the business owner:
 * 1. Knowledge Base coverage score (answered-from-KB / total questions)
 * 2. Unanswered customer questions from WhatsApp/Voice, sorted by frequency
 * 3. AI-generated FAQ suggestions with one-click approve / reject / edit
 *
 * Data is loaded via `/api/dashboard/suggested-faqs` to stay consistent with
 * the rest of the dashboard (no direct Convex client hooks here).
 */

"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import {
  BarChart3,
  CheckCircle2,
  HelpCircle,
  Lightbulb,
  Loader2,
  Pencil,
  RefreshCw,
  Sparkles,
  X,
} from "lucide-react";

// ── Types ───────────────────────────────────────────────────────────────────

type Lang = "en" | "ar";

interface SuggestedFAQsProps {
  organizationId: string;
  lang: Lang;
}

interface UnansweredQuestion {
  id: string;
  question: string;
  language: "en" | "ar";
  count: number;
  lastAskedAt?: number;
}

interface FAQSuggestion {
  id: string;
  question: string;
  answer: string;
  language: "en" | "ar";
  sourceCount?: number;
  confidence?: number;
}

interface SuggestedFAQsResponse {
  coverageScore: number; // 0 – 100
  answeredCount: number;
  totalQuestions: number;
  unansweredThisWeek: number;
  unanswered: UnansweredQuestion[];
  suggestions: FAQSuggestion[];
}

type ActionState =
  | { kind: "idle" }
  | { kind: "pending"; id: string }
  | { kind: "error"; id: string; message: string };

// ── Helpers ─────────────────────────────────────────────────────────────────

const clampPercent = (value: number): number => {
  if (Number.isNaN(value)) return 0;
  if (value < 0) return 0;
  if (value > 100) return 100;
  return Math.round(value);
};

const coverageBarColor = (score: number): string => {
  if (score >= 80) return "bg-emerald-500";
  if (score >= 50) return "bg-amber-500";
  return "bg-rose-500";
};

const coverageTextColor = (score: number): string => {
  if (score >= 80) return "text-emerald-600";
  if (score >= 50) return "text-amber-600";
  return "text-rose-600";
};

// ── Component ───────────────────────────────────────────────────────────────

export default function SuggestedFAQs({
  organizationId,
  lang,
}: SuggestedFAQsProps) {
  const isAr = lang === "ar";
  const dir: "rtl" | "ltr" = isAr ? "rtl" : "ltr";

  const t = useMemo(
    () => ({
      title: isAr ? "اقتراحات الأسئلة الشائعة" : "Suggested FAQs",
      subtitle: isAr
        ? "حسّن قاعدة معرفتك باعتماد الأسئلة المقترحة بنقرة واحدة"
        : "Improve your knowledge base with one-click FAQ approvals",
      coverage: isAr ? "تغطية قاعدة المعرفة" : "Knowledge Base Coverage",
      coverageHint: isAr
        ? "نسبة الأسئلة التي أجابت عنها قاعدة المعرفة"
        : "Share of questions answered from your knowledge base",
      answeredOf: isAr ? "من" : "of",
      questions: isAr ? "سؤال" : "questions",
      unanswered: isAr ? "أسئلة بدون إجابة" : "Unanswered Questions",
      thisWeek: isAr ? "هذا الأسبوع" : "this week",
      suggestions: isAr ? "اقتراحات مُولَّدة" : "Suggested FAQs",
      pending: isAr ? "معلق" : "pending",
      approve: isAr ? "موافقة" : "Approve",
      reject: isAr ? "رفض" : "Reject",
      edit: isAr ? "تعديل" : "Edit",
      askedTimes: isAr ? "مرة" : "times",
      asked: isAr ? "طُرح" : "Asked",
      suggestFaq: isAr ? "اقتراح FAQ" : "Suggest FAQ",
      noSuggestions: isAr
        ? "لا توجد اقتراحات حالياً"
        : "No suggestions at the moment",
      allCovered: isAr
        ? "قاعدة المعرفة تغطي جميع الأسئلة!"
        : "Your knowledge base covers all customer questions!",
      loading: isAr ? "جارِ التحميل..." : "Loading...",
      refresh: isAr ? "تحديث" : "Refresh",
      errorLoading: isAr
        ? "تعذر تحميل الاقتراحات"
        : "Couldn't load suggestions",
      errorActing: isAr
        ? "فشل تنفيذ الإجراء، حاول مجدداً"
        : "Action failed, please try again",
      languageEn: isAr ? "إنجليزي" : "EN",
      languageAr: isAr ? "عربي" : "AR",
    }),
    [isAr],
  );

  // ── State ─────────────────────────────────────────────────────────────────
  const [loading, setLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);
  const [data, setData] = useState<SuggestedFAQsResponse | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [actionState, setActionState] = useState<ActionState>({ kind: "idle" });
  const [csrfToken, setCsrfToken] = useState("");

  // ── Fetch CSRF token (for mutations) ──────────────────────────────────────
  useEffect(() => {
    let cancelled = false;
    fetch("/api/csrf")
      .then((res) => res.json())
      .then((json) => {
        if (!cancelled && json?.csrfToken) {
          setCsrfToken(json.csrfToken as string);
        }
      })
      .catch((err) => {
        console.error("Failed to fetch CSRF token", err);
      });
    return () => {
      cancelled = true;
    };
  }, []);

  // ── Load suggested FAQs ───────────────────────────────────────────────────
  const load = useCallback(
    async (showRefresh = false) => {
      if (!organizationId) return;
      if (showRefresh) setRefreshing(true);
      else setLoading(true);
      setError(null);

      try {
        const res = await fetch(
          `/api/dashboard/suggested-faqs?organizationId=${encodeURIComponent(
            organizationId,
          )}`,
          { cache: "no-store" },
        );

        if (!res.ok) {
          throw new Error(`Request failed: ${res.status}`);
        }

        const json = (await res.json()) as Partial<SuggestedFAQsResponse>;

        setData({
          coverageScore: clampPercent(Number(json.coverageScore ?? 0)),
          answeredCount: Number(json.answeredCount ?? 0),
          totalQuestions: Number(json.totalQuestions ?? 0),
          unansweredThisWeek: Number(json.unansweredThisWeek ?? 0),
          unanswered: Array.isArray(json.unanswered) ? json.unanswered : [],
          suggestions: Array.isArray(json.suggestions) ? json.suggestions : [],
        });
      } catch (err) {
        console.error("Failed to load suggested FAQs", err);
        setError(t.errorLoading);
      } finally {
        setLoading(false);
        setRefreshing(false);
      }
    },
    [organizationId, t.errorLoading],
  );

  useEffect(() => {
    load();
  }, [load]);

  // ── Mutations ─────────────────────────────────────────────────────────────
  const callAction = useCallback(
    async (
      path: "approve" | "reject",
      body: Record<string, unknown>,
      id: string,
    ) => {
      setActionState({ kind: "pending", id });
      try {
        const res = await fetch(`/api/dashboard/suggested-faqs/${path}`, {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            "x-csrf-token": csrfToken,
          },
          body: JSON.stringify({ organizationId, ...body }),
        });

        if (!res.ok) throw new Error(`Request failed: ${res.status}`);

        setActionState({ kind: "idle" });
        await load(true);
      } catch (err) {
        console.error(`Failed to ${path} suggestion`, err);
        setActionState({ kind: "error", id, message: t.errorActing });
      }
    },
    [csrfToken, load, organizationId, t.errorActing],
  );

  const handleApprove = useCallback(
    (suggestionId: string) => callAction("approve", { suggestionId }, suggestionId),
    [callAction],
  );

  const handleReject = useCallback(
    (suggestionId: string) => callAction("reject", { suggestionId }, suggestionId),
    [callAction],
  );

  const handleSuggestFromQuestion = useCallback(
    (questionId: string) =>
      callAction("approve", { questionId, generate: true }, questionId),
    [callAction],
  );

  // ── Derived values ────────────────────────────────────────────────────────
  const score = data ? clampPercent(data.coverageScore) : 0;
  const suggestionsCount = data?.suggestions.length ?? 0;
  const unansweredCount = data?.unanswered.length ?? 0;
  const allCovered = !loading && unansweredCount === 0 && suggestionsCount === 0;

  // ── Render ────────────────────────────────────────────────────────────────
  return (
    <section
      dir={dir}
      className="space-y-4"
      aria-label={t.title}
    >
      {/* Header */}
      <div className="flex items-start justify-between gap-3">
        <div>
          <h2 className="flex items-center gap-2 text-lg font-semibold text-slate-900">
            <Sparkles className="h-5 w-5 text-violet-600" aria-hidden="true" />
            {t.title}
          </h2>
          <p className="mt-0.5 text-sm text-slate-500">{t.subtitle}</p>
        </div>
        <button
          type="button"
          onClick={() => load(true)}
          disabled={loading || refreshing}
          className="flex items-center gap-2 rounded-lg border border-slate-200 bg-white px-3 py-2 text-sm font-medium text-slate-700 transition-colors hover:bg-slate-50 disabled:opacity-50"
          aria-label={t.refresh}
        >
          <RefreshCw
            className={`h-4 w-4 ${refreshing ? "animate-spin" : ""}`}
            aria-hidden="true"
          />
          <span className="hidden sm:inline">{t.refresh}</span>
        </button>
      </div>

      {/* Error banner */}
      {error && (
        <div
          role="alert"
          className="rounded-xl border border-rose-200 bg-rose-50 px-4 py-3 text-sm text-rose-700"
        >
          {error}
        </div>
      )}

      {/* Coverage card */}
      <div className="rounded-xl border border-slate-200 bg-white p-5 shadow-sm">
        <div className="flex items-start justify-between gap-4">
          <div className="flex items-start gap-3">
            <div className="flex h-10 w-10 items-center justify-center rounded-lg bg-gradient-to-br from-blue-50 to-indigo-50 text-blue-600">
              <BarChart3 className="h-5 w-5" aria-hidden="true" />
            </div>
            <div>
              <h3 className="text-sm font-semibold text-slate-900">
                {t.coverage}
              </h3>
              <p className="mt-0.5 text-xs text-slate-500">{t.coverageHint}</p>
            </div>
          </div>
          <div
            className={`text-2xl font-bold tabular-nums ${coverageTextColor(score)}`}
            aria-live="polite"
          >
            {score}%
          </div>
        </div>

        <div
          className="mt-4 h-2 w-full overflow-hidden rounded-full bg-slate-100"
          role="progressbar"
          aria-valuenow={score}
          aria-valuemin={0}
          aria-valuemax={100}
          aria-label={t.coverage}
        >
          <div
            className={`h-full rounded-full transition-[width] duration-500 ${coverageBarColor(score)}`}
            style={{ width: `${score}%` }}
          />
        </div>

        {data && data.totalQuestions > 0 && (
          <p className="mt-2 text-xs text-slate-500 tabular-nums">
            {data.answeredCount} {t.answeredOf} {data.totalQuestions} {t.questions}
          </p>
        )}
      </div>

      {/* Loading skeleton */}
      {loading && !data && (
        <div className="flex items-center justify-center rounded-xl border border-slate-200 bg-white px-4 py-10 text-sm text-slate-500">
          <Loader2 className="mr-2 h-4 w-4 animate-spin" aria-hidden="true" />
          {t.loading}
        </div>
      )}

      {/* Empty state — everything covered */}
      {allCovered && data && (
        <div className="flex flex-col items-center justify-center rounded-xl border border-emerald-200 bg-gradient-to-br from-emerald-50 to-teal-50 px-4 py-10 text-center">
          <CheckCircle2
            className="h-10 w-10 text-emerald-500"
            aria-hidden="true"
          />
          <p className="mt-3 text-sm font-medium text-emerald-800">
            {t.allCovered}
          </p>
        </div>
      )}

      {/* Unanswered questions */}
      {data && unansweredCount > 0 && (
        <div className="rounded-xl border border-slate-200 bg-white shadow-sm">
          <div className="flex items-center justify-between gap-2 border-b border-slate-100 px-5 py-3">
            <div className="flex items-center gap-2">
              <HelpCircle
                className="h-4 w-4 text-amber-600"
                aria-hidden="true"
              />
              <h3 className="text-sm font-semibold text-slate-900">
                {t.unanswered}
              </h3>
            </div>
            <span className="rounded-full bg-amber-50 px-2.5 py-0.5 text-xs font-medium text-amber-700">
              {data.unansweredThisWeek} {t.thisWeek}
            </span>
          </div>
          <ul className="divide-y divide-slate-100">
            {data.unanswered.map((q) => {
              const isPending =
                actionState.kind === "pending" && actionState.id === q.id;
              const hasError =
                actionState.kind === "error" && actionState.id === q.id;
              return (
                <li key={q.id} className="px-5 py-4">
                  <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
                    <div className="min-w-0 flex-1">
                      <p
                        className="truncate text-sm text-slate-800"
                        title={q.question}
                      >
                        &ldquo;{q.question}&rdquo;
                      </p>
                      <p className="mt-1 text-xs text-slate-500 tabular-nums">
                        {t.asked} {q.count} {t.askedTimes}
                        <span className="mx-2 text-slate-300">·</span>
                        <span className="uppercase">
                          {q.language === "ar" ? t.languageAr : t.languageEn}
                        </span>
                      </p>
                      {hasError && (
                        <p className="mt-1 text-xs text-rose-600">
                          {actionState.message}
                        </p>
                      )}
                    </div>
                    <button
                      type="button"
                      onClick={() => handleSuggestFromQuestion(q.id)}
                      disabled={isPending}
                      className="inline-flex shrink-0 items-center gap-1.5 rounded-lg border border-violet-200 bg-violet-50 px-3 py-1.5 text-xs font-medium text-violet-700 transition-colors hover:bg-violet-100 disabled:opacity-50"
                    >
                      {isPending ? (
                        <Loader2
                          className="h-3.5 w-3.5 animate-spin"
                          aria-hidden="true"
                        />
                      ) : (
                        <Lightbulb className="h-3.5 w-3.5" aria-hidden="true" />
                      )}
                      {t.suggestFaq}
                    </button>
                  </div>
                </li>
              );
            })}
          </ul>
        </div>
      )}

      {/* Suggested FAQs */}
      {data && suggestionsCount > 0 && (
        <div className="rounded-xl border border-slate-200 bg-white shadow-sm">
          <div className="flex items-center justify-between gap-2 border-b border-slate-100 px-5 py-3">
            <div className="flex items-center gap-2">
              <Lightbulb
                className="h-4 w-4 text-violet-600"
                aria-hidden="true"
              />
              <h3 className="text-sm font-semibold text-slate-900">
                {t.suggestions}
              </h3>
            </div>
            <span className="rounded-full bg-violet-50 px-2.5 py-0.5 text-xs font-medium text-violet-700">
              {suggestionsCount} {t.pending}
            </span>
          </div>
          <ul className="divide-y divide-slate-100">
            {data.suggestions.map((s) => {
              const isPending =
                actionState.kind === "pending" && actionState.id === s.id;
              const hasError =
                actionState.kind === "error" && actionState.id === s.id;
              return (
                <li key={s.id} className="px-5 py-4">
                  <div className="space-y-2">
                    <p className="text-sm font-medium text-slate-900">
                      <span className="text-slate-400">Q:</span>{" "}
                      &ldquo;{s.question}&rdquo;
                    </p>
                    <p className="text-sm text-slate-600">
                      <span className="text-slate-400">A:</span> {s.answer}
                    </p>
                    {typeof s.sourceCount === "number" && s.sourceCount > 0 && (
                      <p className="text-xs text-slate-400 tabular-nums">
                        {t.asked} {s.sourceCount} {t.askedTimes}
                        <span className="mx-2 text-slate-300">·</span>
                        <span className="uppercase">
                          {s.language === "ar" ? t.languageAr : t.languageEn}
                        </span>
                      </p>
                    )}
                    {hasError && (
                      <p className="text-xs text-rose-600">
                        {actionState.message}
                      </p>
                    )}
                    <div className="flex flex-wrap gap-2 pt-1">
                      <button
                        type="button"
                        onClick={() => handleApprove(s.id)}
                        disabled={isPending}
                        className="inline-flex items-center gap-1.5 rounded-lg bg-emerald-600 px-3 py-1.5 text-xs font-medium text-white transition-colors hover:bg-emerald-700 disabled:opacity-50"
                      >
                        {isPending ? (
                          <Loader2
                            className="h-3.5 w-3.5 animate-spin"
                            aria-hidden="true"
                          />
                        ) : (
                          <CheckCircle2
                            className="h-3.5 w-3.5"
                            aria-hidden="true"
                          />
                        )}
                        {t.approve}
                      </button>
                      <button
                        type="button"
                        onClick={() => handleReject(s.id)}
                        disabled={isPending}
                        className="inline-flex items-center gap-1.5 rounded-lg border border-rose-200 bg-white px-3 py-1.5 text-xs font-medium text-rose-600 transition-colors hover:bg-rose-50 disabled:opacity-50"
                      >
                        <X className="h-3.5 w-3.5" aria-hidden="true" />
                        {t.reject}
                      </button>
                      <button
                        type="button"
                        disabled
                        aria-disabled="true"
                        title={t.edit}
                        className="inline-flex cursor-not-allowed items-center gap-1.5 rounded-lg border border-slate-200 bg-white px-3 py-1.5 text-xs font-medium text-slate-600 opacity-60"
                      >
                        <Pencil className="h-3.5 w-3.5" aria-hidden="true" />
                        {t.edit}
                      </button>
                    </div>
                  </div>
                </li>
              );
            })}
          </ul>
        </div>
      )}

      {/* No suggestions but some unanswered */}
      {data &&
        !loading &&
        suggestionsCount === 0 &&
        unansweredCount > 0 && (
          <div className="rounded-xl border border-dashed border-slate-200 bg-slate-50 px-4 py-6 text-center text-sm text-slate-500">
            {t.noSuggestions}
          </div>
        )}
    </section>
  );
}
