import { createFileRoute, Link, redirect } from "@tanstack/react-router";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useState } from "react";
import { Plus, FileText, ExternalLink, Trash2, Eye, EyeOff } from "lucide-react";
import { toast } from "sonner";

import { authStore } from "@/lib/auth";
import {
  adminBlogApi,
  adminBlogQueryKeys,
  type AdminPost,
} from "@/lib/admin-blog";
import { Button, EmptyState } from "@rubis/ui";

export const Route = createFileRoute("/_app/admin/blog")({
  beforeLoad: () => {
    // Gate côté client : si pas admin, on redirige vers / (404 visuel).
    // Le backend re-vérifie de toute façon (middleware admin sur API).
    if (!authStore.user?.isAdmin) {
      throw redirect({ to: "/" });
    }
  },
  loader: ({ context }) => {
    void context.queryClient.prefetchQuery({
      queryKey: adminBlogQueryKeys.list(),
      queryFn: () => adminBlogApi.list(),
    });
  },
  component: AdminBlogList,
});

function AdminBlogList() {
  const qc = useQueryClient();
  const { data: posts = [], isPending } = useQuery({
    queryKey: adminBlogQueryKeys.list(),
    queryFn: () => adminBlogApi.list(),
    staleTime: 5_000,
  });

  const [creating, setCreating] = useState(false);
  const createMut = useMutation({
    mutationFn: () =>
      adminBlogApi.create({
        slug: `nouveau-brouillon-${Date.now()}`,
        title: "Nouveau brouillon",
        excerpt:
          "Brouillon vide à compléter avant publication — fais une description suffisamment longue pour le SEO (minimum 120 caractères).",
        contentMd:
          "# Brouillon\n\nÉcris ton contenu ici. **Markdown** supporté.",
      }),
    onSuccess: (post) => {
      qc.invalidateQueries({ queryKey: adminBlogQueryKeys.all() });
      toast.success("Brouillon créé.");
      setCreating(false);
      window.location.href = `/admin/blog/${post.id}`;
    },
    onError: (err: Error) => {
      toast.error(`Échec création : ${err.message}`);
      setCreating(false);
    },
  });

  return (
    <div className="container mx-auto max-w-[1100px] px-5 py-8">
      <div className="flex items-baseline justify-between mb-8">
        <div>
          <h1 className="font-display text-[28px] font-bold tracking-[-0.02em] text-ink">
            Articles du blog
          </h1>
          <p className="text-[14px] text-ink-3 mt-1">
            Crée, édite et publie sur{" "}
            <a href="https://rubis.pro/blog" target="_blank" rel="noopener" className="underline">
              rubis.pro/blog
            </a>
            .
          </p>
        </div>
        <Button
          onClick={() => {
            setCreating(true);
            createMut.mutate();
          }}
          loading={creating || createMut.isPending}
        >
          <Plus size={16} />
          Nouveau brouillon
        </Button>
      </div>

      {isPending ? (
        <div className="text-ink-3 text-sm">Chargement…</div>
      ) : posts.length === 0 ? (
        <EmptyState
          icon={<FileText size={32} />}
          title="Aucun article"
          description="Tu n'as pas encore d'article. Clique sur Nouveau brouillon pour commencer."
        />
      ) : (
        <div className="bg-white rounded-card border border-line shadow-soft overflow-hidden">
          <table className="w-full text-[14px]">
            <thead className="bg-cream-2 text-[11.5px] uppercase tracking-[0.08em] font-semibold text-ink-3">
              <tr>
                <th className="text-left px-5 py-3">Statut</th>
                <th className="text-left px-5 py-3">Titre</th>
                <th className="text-left px-5 py-3">Slug</th>
                <th className="text-left px-5 py-3">Mots</th>
                <th className="text-left px-5 py-3">Mise à jour</th>
                <th className="text-right px-5 py-3" />
              </tr>
            </thead>
            <tbody className="divide-y divide-line">
              {posts.map((post) => (
                <PostRow key={post.id} post={post} />
              ))}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
}

function PostRow({ post }: { post: AdminPost }) {
  const qc = useQueryClient();

  const deleteMut = useMutation({
    mutationFn: () => adminBlogApi.delete(post.id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: adminBlogQueryKeys.all() });
      toast.success("Article supprimé.");
    },
    onError: (err: Error) => toast.error(`Échec suppression : ${err.message}`),
  });

  const unpublishMut = useMutation({
    mutationFn: () => adminBlogApi.unpublish(post.id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: adminBlogQueryKeys.all() });
      toast.success("Article repassé en brouillon.");
    },
    onError: (err: Error) => toast.error(`Échec : ${err.message}`),
  });

  return (
    <tr className="hover:bg-cream-2/40 transition-colors">
      <td className="px-5 py-4">
        <StatusBadge status={post.status} />
      </td>
      <td className="px-5 py-4">
        <Link
          to="/admin/blog/$id"
          params={{ id: post.id }}
          className="font-medium text-ink hover:text-rubis"
        >
          {post.title}
        </Link>
      </td>
      <td className="px-5 py-4 text-ink-3 font-mono text-[12.5px]">{post.slug}</td>
      <td className="px-5 py-4 text-ink-2 tabular-nums">
        {post.wordCount} <span className="text-ink-3">·</span> {post.readingTimeMinutes} min
      </td>
      <td className="px-5 py-4 text-ink-3 text-[13px]">
        {new Intl.DateTimeFormat("fr-FR", {
          dateStyle: "medium",
          timeStyle: "short",
        }).format(new Date(post.updatedAt ?? post.createdAt))}
      </td>
      <td className="px-5 py-4 text-right whitespace-nowrap">
        {post.status === "published" && (
          <a
            href={`https://rubis.pro/blog/${post.slug}`}
            target="_blank"
            rel="noopener"
            className="inline-flex items-center gap-1 text-[12.5px] text-ink-3 hover:text-rubis mr-3"
            title="Voir sur rubis.pro"
          >
            <ExternalLink size={13} />
          </a>
        )}
        {post.status === "published" && (
          <button
            type="button"
            onClick={() => unpublishMut.mutate()}
            className="inline-flex items-center gap-1 text-[12.5px] text-ink-3 hover:text-rubis-deep mr-3"
            title="Dépublier"
          >
            <EyeOff size={13} />
          </button>
        )}
        {post.status === "draft" && (
          <Link
            to="/admin/blog/$id"
            params={{ id: post.id }}
            className="inline-flex items-center gap-1 text-[12.5px] text-ink-3 hover:text-rubis mr-3"
            title="Éditer"
          >
            <Eye size={13} />
          </Link>
        )}
        <button
          type="button"
          onClick={() => {
            if (confirm(`Supprimer "${post.title}" ?`)) {
              deleteMut.mutate();
            }
          }}
          className="inline-flex items-center gap-1 text-[12.5px] text-ink-3 hover:text-rubis-deep"
          title="Supprimer"
        >
          <Trash2 size={13} />
        </button>
      </td>
    </tr>
  );
}

function StatusBadge({ status }: { status: AdminPost["status"] }) {
  if (status === "published") {
    return (
      <span className="inline-flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-[0.08em] text-rubis">
        <span aria-hidden className="size-1.5 rounded-full bg-rubis" />
        Publié
      </span>
    );
  }
  return (
    <span className="inline-flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-[0.08em] text-ink-3">
      <span aria-hidden className="size-1.5 rounded-full bg-ink-3" />
      Brouillon
    </span>
  );
}
