"use client";

import Image from "next/image";
import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import {
  CalendarDays,
  Eye,
  Grid2X2,
  LayoutList,
  Pencil,
  Plus,
  Search,
  Trash2,
  X,
} from "lucide-react";
import { AdminGuard } from "@/components/admin/AdminGuard";
import { AdminShell } from "@/components/admin/AdminShell";
import { adminRequest, type AdminBlog } from "@/lib/admin-api";

const allCategory = "All categories";

export default function AdminBlogListPage() {
  const [blogs, setBlogs] = useState<AdminBlog[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [errorMessage, setErrorMessage] = useState("");
  const [blogToDelete, setBlogToDelete] = useState<AdminBlog | null>(null);
  const [deleteStatus, setDeleteStatus] = useState<"idle" | "deleting">("idle");
  const [viewMode, setViewMode] = useState<"card" | "list">("card");
  const [search, setSearch] = useState("");
  const [category, setCategory] = useState(allCategory);
  const [sortBy, setSortBy] = useState<"newest" | "oldest" | "title">("newest");

  useEffect(() => {
    adminRequest<{ blogs: AdminBlog[] }>("/api/admin/blogs")
      .then((data) => setBlogs(data.blogs))
      .catch((error) => {
        setErrorMessage(error instanceof Error ? error.message : "Could not load blogs");
      })
      .finally(() => setIsLoading(false));
  }, []);

  async function deleteBlog() {
    if (!blogToDelete) {
      return;
    }

    setDeleteStatus("deleting");
    setErrorMessage("");

    try {
      await adminRequest(`/api/admin/blogs/${blogToDelete.id}`, {
        method: "DELETE",
      });
      setBlogs((currentBlogs) => currentBlogs.filter((blog) => blog.id !== blogToDelete.id));
      setBlogToDelete(null);
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : "Could not delete blog");
    } finally {
      setDeleteStatus("idle");
    }
  }

  const categories = useMemo(() => {
    return [
      allCategory,
      ...Array.from(new Set(blogs.map((blog) => blog.category).filter(Boolean))),
    ];
  }, [blogs]);

  const filteredBlogs = useMemo(() => {
    const cleanSearch = search.trim().toLowerCase();

    return blogs
      .filter((blog) => {
        const matchesSearch =
          !cleanSearch ||
          blog.title.toLowerCase().includes(cleanSearch) ||
          blog.slug.toLowerCase().includes(cleanSearch);
        const matchesCategory = category === allCategory || blog.category === category;

        return matchesSearch && matchesCategory;
      })
      .sort((a, b) => {
        if (sortBy === "title") {
          return a.title.localeCompare(b.title);
        }

        const aTime = new Date(a.createdAt).getTime();
        const bTime = new Date(b.createdAt).getTime();

        return sortBy === "newest" ? bTime - aTime : aTime - bTime;
      });
  }, [blogs, category, search, sortBy]);

  return (
    <AdminGuard>
      <AdminShell title="Blog list" lead="Database-backed blogs added from the admin panel.">
        <div className="mb-5 space-y-4 rounded-lg border border-border bg-white p-4 shadow-sm">
          <div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
            <div className="grid gap-3 md:grid-cols-[minmax(0,1fr)_190px_170px] lg:flex-1">
              <div className="relative min-w-0">
                <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
                <input
                  value={search}
                  onChange={(event) => setSearch(event.target.value)}
                  placeholder="Search blogs by title or slug"
                  className="h-11 w-full rounded-md border border-border bg-white pl-10 pr-10 text-sm font-semibold outline-none transition focus:border-primary focus:ring-2 focus:ring-primary/15"
                />
                {search ? (
                  <button
                    type="button"
                    onClick={() => setSearch("")}
                    className="absolute right-2 top-1/2 grid h-7 w-7 -translate-y-1/2 place-items-center rounded-md text-muted-foreground transition hover:bg-slate-100 hover:text-foreground"
                    aria-label="Clear blog search"
                  >
                    <X className="h-4 w-4" />
                  </button>
                ) : null}
              </div>
              <select
                value={category}
                onChange={(event) => setCategory(event.target.value)}
                className="h-11 rounded-md border border-border bg-white px-3 text-sm font-bold outline-none transition focus:border-primary focus:ring-2 focus:ring-primary/15"
              >
                {categories.map((item) => (
                  <option key={item}>{item}</option>
                ))}
              </select>
              <select
                value={sortBy}
                onChange={(event) => setSortBy(event.target.value as typeof sortBy)}
                className="h-11 rounded-md border border-border bg-white px-3 text-sm font-bold outline-none transition focus:border-primary focus:ring-2 focus:ring-primary/15"
              >
                <option value="newest">Newest created</option>
                <option value="oldest">Oldest created</option>
                <option value="title">Name A-Z</option>
              </select>
            </div>

            <div className="flex flex-col gap-3 sm:flex-row sm:items-center lg:shrink-0">
              <div className="hidden rounded-md border border-border bg-slate-50 p-1 lg:flex">
                <button
                  type="button"
                  onClick={() => setViewMode("card")}
                  className={`inline-flex h-9 items-center gap-2 rounded px-3 text-xs font-black transition ${
                    viewMode === "card"
                      ? "bg-primary text-primary-foreground"
                      : "text-muted-foreground hover:bg-white hover:text-foreground"
                  }`}
                >
                  <Grid2X2 className="h-4 w-4" />
                  Card
                </button>
                <button
                  type="button"
                  onClick={() => setViewMode("list")}
                  className={`inline-flex h-9 items-center gap-2 rounded px-3 text-xs font-black transition ${
                    viewMode === "list"
                      ? "bg-primary text-primary-foreground"
                      : "text-muted-foreground hover:bg-white hover:text-foreground"
                  }`}
                >
                  <LayoutList className="h-4 w-4" />
                  List
                </button>
              </div>
              <Link
                href="/admin/blogs/new"
                className="inline-flex h-11 items-center justify-center gap-2 rounded-md bg-primary px-4 text-sm font-black text-primary-foreground transition hover:opacity-95"
              >
                <Plus className="h-4 w-4" />
                Add blog
              </Link>
            </div>
          </div>

          <div className="flex flex-wrap gap-3 text-xs font-black uppercase tracking-[0.14em] text-muted-foreground">
            <span>{isLoading ? "Loading blogs" : `${filteredBlogs.length} shown`}</span>
            <span>{blogs.length} total</span>
          </div>
        </div>

        {isLoading ? (
          <p className="rounded-lg border border-border bg-white px-4 py-8 text-sm font-semibold text-muted-foreground">
            Loading blogs...
          </p>
        ) : null}

        {!isLoading && errorMessage ? (
          <div className="rounded-lg border border-border bg-white px-4 py-8">
            <p className="rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm font-semibold text-destructive">
              {errorMessage}
            </p>
            <p className="mt-3 text-sm font-semibold text-muted-foreground">
              Make sure the Node API is running and the PostgreSQL schema has been applied.
            </p>
          </div>
        ) : null}

        {!isLoading && !errorMessage && filteredBlogs.length === 0 ? (
          <p className="rounded-lg border border-border bg-white px-4 py-8 text-center text-sm font-semibold text-muted-foreground">
            No blogs match the selected filters.
          </p>
        ) : null}

        {!isLoading && !errorMessage && filteredBlogs.length > 0 ? (
          <div className={viewMode === "list" ? "lg:hidden" : ""}>
            <div className="grid gap-6 md:grid-cols-2 xl:grid-cols-3">
              {filteredBlogs.map((blog) => (
                <BlogAdminCard key={blog.id} blog={blog} onDelete={() => setBlogToDelete(blog)} />
              ))}
            </div>
          </div>
        ) : null}

        {!isLoading && !errorMessage && filteredBlogs.length > 0 && viewMode === "list" ? (
          <div className="hidden overflow-hidden rounded-lg border border-border bg-white shadow-sm lg:block">
            <div className="grid gap-4 border-b border-border bg-slate-100 px-4 py-3 text-xs font-black uppercase tracking-[0.14em] text-muted-foreground lg:grid-cols-[1.2fr_160px_140px_180px_220px]">
              <span>Title</span>
              <span>Category</span>
              <span>Published</span>
              <span>Created</span>
              <span>Actions</span>
            </div>

            {filteredBlogs.map((blog) => (
              <div
                key={blog.id}
                className="grid gap-4 border-b border-border px-4 py-4 text-sm last:border-b-0 lg:grid-cols-[1.2fr_160px_140px_180px_220px]"
              >
                <div>
                  <p className="font-black text-foreground">{blog.title}</p>
                  <p className="mt-1 text-xs font-semibold text-muted-foreground">/{blog.slug}</p>
                </div>
                <p className="font-semibold text-muted-foreground">{blog.category}</p>
                <p className="font-semibold text-muted-foreground">{blog.date}</p>
                <p className="font-semibold text-muted-foreground">
                  {new Date(blog.createdAt).toLocaleDateString("en", {
                    month: "short",
                    day: "numeric",
                    year: "numeric",
                  })}
                </p>
                <BlogActions blog={blog} onDelete={() => setBlogToDelete(blog)} />
              </div>
            ))}
          </div>
        ) : null}

        {blogToDelete ? (
          <div className="fixed inset-0 z-[70] grid place-items-center bg-slate-950/45 px-4">
            <div className="w-full max-w-md rounded-lg border border-border bg-white p-5 shadow-2xl">
              <div className="grid h-11 w-11 place-items-center rounded-md bg-destructive/10 text-destructive">
                <Trash2 className="h-5 w-5" />
              </div>
              <h2 className="mt-4 text-xl font-black tracking-tight text-foreground">
                Delete this blog?
              </h2>
              <p className="mt-2 text-sm leading-6 text-muted-foreground">
                This will permanently delete{" "}
                <span className="font-black text-foreground">{blogToDelete.title}</span>. This
                action cannot be undone.
              </p>
              <div className="mt-5 flex justify-end gap-2">
                <button
                  type="button"
                  onClick={() => setBlogToDelete(null)}
                  disabled={deleteStatus === "deleting"}
                  className="h-10 rounded-md border border-border px-4 text-sm font-black text-muted-foreground transition hover:bg-slate-100 hover:text-foreground disabled:opacity-70"
                >
                  Cancel
                </button>
                <button
                  type="button"
                  onClick={deleteBlog}
                  disabled={deleteStatus === "deleting"}
                  className="h-10 rounded-md bg-destructive px-4 text-sm font-black text-destructive-foreground transition hover:opacity-95 disabled:opacity-70"
                >
                  {deleteStatus === "deleting" ? "Deleting..." : "Delete blog"}
                </button>
              </div>
            </div>
          </div>
        ) : null}
      </AdminShell>
    </AdminGuard>
  );
}

function BlogAdminCard({ blog, onDelete }: { blog: AdminBlog; onDelete: () => void }) {
  return (
    <article className="group block h-full overflow-hidden rounded-3xl border border-border bg-card transition-all duration-300 hover:-translate-y-1 hover:border-primary/30">
      <Link href={`/admin/blogs/details?id=${blog.id}`} className="block">
        <div className="relative aspect-[3/2] overflow-hidden bg-slate-100">
          <Image
            src={blog.image}
            alt={blog.imageAlt}
            fill
            sizes="(min-width: 1280px) 33vw, (min-width: 768px) 50vw, 100vw"
            className="object-cover transition-transform duration-700 group-hover:scale-105"
          />
          <span className="absolute left-4 top-4 rounded-full bg-white/90 px-3 py-1 text-[10px] font-black uppercase tracking-[0.18em] text-primary backdrop-blur">
            {blog.category}
          </span>
        </div>
      </Link>

      <div className="p-6">
        <div className="flex items-center gap-2 text-xs font-semibold text-muted-foreground">
          <CalendarDays className="h-4 w-4 text-primary" />
          <span>{blog.date}</span>
          <span aria-hidden="true">&bull;</span>
          <span>{blog.readTime}</span>
        </div>
        <Link href={`/admin/blogs/details?id=${blog.id}`}>
          <h3 className="mt-4 text-xl font-black leading-tight tracking-tight text-foreground group-hover:text-primary">
            {blog.title}
          </h3>
        </Link>
        <p className="mt-3 line-clamp-3 text-sm leading-relaxed text-muted-foreground">
          {truncateText(blog.excerpt)}
        </p>
        <div className="mt-5">
          <BlogActions blog={blog} onDelete={onDelete} />
        </div>
      </div>
    </article>
  );
}

function truncateText(value: string, maxLength = 140) {
  return value.length > maxLength ? `${value.slice(0, maxLength).trim()}...` : value;
}

function BlogActions({ blog, onDelete }: { blog: AdminBlog; onDelete: () => void }) {
  return (
    <div className="flex flex-wrap gap-2">
      <Link
        href={`/admin/blogs/details?id=${blog.id}`}
        className="inline-flex h-9 items-center gap-2 rounded-md border border-border px-3 text-xs font-black text-muted-foreground transition hover:bg-slate-100 hover:text-foreground"
      >
        <Eye className="h-4 w-4" />
        View
      </Link>
      <Link
        href={`/admin/blogs/edit?id=${blog.id}`}
        className="inline-flex h-9 items-center gap-2 rounded-md border border-border px-3 text-xs font-black text-muted-foreground transition hover:bg-slate-100 hover:text-foreground"
      >
        <Pencil className="h-4 w-4" />
        Edit
      </Link>
      <button
        type="button"
        onClick={onDelete}
        className="inline-flex h-9 items-center gap-2 rounded-md border border-destructive/30 px-3 text-xs font-black text-destructive transition hover:bg-destructive/10"
      >
        <Trash2 className="h-4 w-4" />
        Delete
      </button>
    </div>
  );
}
