"use client";

import { DataTableSkeleton } from "@/components/ui/data-table-skeleton";
import { PreviousWorkDeleteDialog } from "@/components/dashboard/previous-work/previous-work-delete-dialog";
import { PreviousWorkDuplicateDialog } from "@/components/dashboard/previous-work/previous-work-duplicate-dialog";
import { PreviousWorkFilterPanel } from "@/components/dashboard/previous-work/previous-work-filter-panel";
import { PreviousWorkTable } from "@/components/dashboard/previous-work/previous-work-table";
import type { DashboardPreviousWorkItem } from "@/components/dashboard/previous-work/previous-work-types";
import {
  buildVisibleReorderItems,
  deleteWork,
  duplicateWork,
  getWorksQueryParams,
  reorderWorks,
  toggleWork,
  useWorks,
} from "@/lib/api/dashboard/works-api";
import { FilterButton } from "@/components/ui/filter/filter-button";
import { Pagination } from "@/components/ui/pagination";
import { SearchInput } from "@/components/ui/search-input";
import { cn } from "@/lib/utils";
import { X } from "lucide-react";
import { useTranslations } from "next-intl";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useMemo, useState } from "react";

type PendingAction = "delete" | "duplicate" | "toggle" | "reorder" | null;

function getVisibleReorderItems(previousWorks: DashboardPreviousWorkItem[], index: number, direction: "up" | "down") {
  const nextItems = [...previousWorks];
  const adjacentIndex = direction === "up" ? index - 1 : index + 1;

  if (adjacentIndex < 0 || adjacentIndex >= nextItems.length) {
    return null;
  }

  [nextItems[index], nextItems[adjacentIndex]] = [nextItems[adjacentIndex], nextItems[index]];
  return buildVisibleReorderItems(nextItems);
}

export function PreviousWorkPageView() {
  const t = useTranslations("dashboard.previousWork");
  const tCommon = useTranslations("common");
  const pathname = usePathname();
  const router = useRouter();
  const searchParams = useSearchParams();
  const params = useMemo(() => getWorksQueryParams(searchParams), [searchParams]);

  const [isFilterOpen, setIsFilterOpen] = useState(false);
  const [workToDelete, setWorkToDelete] = useState<DashboardPreviousWorkItem | null>(null);
  const [workToDuplicate, setWorkToDuplicate] = useState<DashboardPreviousWorkItem | null>(null);
  const [pendingAction, setPendingAction] = useState<PendingAction>(null);
  const [pendingWorkId, setPendingWorkId] = useState<number | null>(null);

  const worksState = useWorks(params);

  const activeFilters = useMemo(() => {
    const filters: Array<{ key: string; label: string; value?: string }> = [];
    const search = (searchParams.get("search") || "").trim();
    const serviceId = searchParams.get("service_id");
    const isActive = searchParams.get("is_active");
    const isFeatured = searchParams.get("is_featured");

    if (search) {
      filters.push({ key: "search", label: `${tCommon("search")}: ${search}` });
    }

    if (serviceId) {
      const selectedWork = worksState.works?.find((work) => String(work.service_id) === serviceId);
      const serviceLabel =
        typeof selectedWork?.service === "string"
          ? selectedWork.service
          : selectedWork?.service?.title || selectedWork?.service?.name || serviceId;
      filters.push({ key: "service_id", label: `${t("form.fields.service")}: ${String(serviceLabel)}` });
    }

    if (isActive === "1" || isActive === "0") {
      filters.push({
        key: "is_active",
        label: `${t("filters.active")}: ${isActive === "1" ? tCommon("yes") : tCommon("no")}`,
      });
    }

    if (isFeatured === "1" || isFeatured === "0") {
      filters.push({
        key: "is_featured",
        label: `${t("filters.featured")}: ${isFeatured === "1" ? tCommon("yes") : tCommon("no")}`,
      });
    }

    return filters;
  }, [searchParams, t, tCommon, worksState.works]);

  const removeFilter = (key: string) => {
    const nextParams = new URLSearchParams(searchParams.toString());
    nextParams.delete(key);
    nextParams.set("page", "1");
    const nextQuery = nextParams.toString();
    router.push(nextQuery ? `${pathname}?${nextQuery}` : pathname, { scroll: false });
  };

  const handleMutation = async (
    action: PendingAction,
    workId: number,
    run: () => Promise<unknown>,
  ) => {
    setPendingAction(action);
    setPendingWorkId(workId);
    try {
      await run();
    } finally {
      setPendingAction(null);
      setPendingWorkId(null);
    }
  };

  const handleDelete = async () => {
    if (!workToDelete) return;
    await handleMutation("delete", workToDelete.id, () => deleteWork(workToDelete.id));
    setWorkToDelete(null);
  };

  const handleDuplicate = async () => {
    if (!workToDuplicate) return;
    await handleMutation("duplicate", workToDuplicate.id, () => duplicateWork(workToDuplicate.id));
    setWorkToDuplicate(null);
  };

  const handleToggle = async (work: DashboardPreviousWorkItem) => {
    await handleMutation("toggle", work.id, () => toggleWork(work.id));
  };

  const handleMove = async (index: number, direction: "up" | "down") => {
    const works = worksState.works || [];
    const items = getVisibleReorderItems(works, index, direction);
    if (!items) return;
    const workId = works[index]?.id;
    if (!workId) return;
    await handleMutation("reorder", workId, () => reorderWorks(items));
  };

  const totalItems = worksState.meta.total;
  const totalPages = worksState.meta.last_page;

  if (worksState.isLoading) {
    return (
      <section className="overflow-hidden rounded-2xl border border-border bg-card">
        <DataTableSkeleton rows={8} columns={5} />
      </section>
    );
  }

  if (worksState.error) {
    return (
      <section className="overflow-hidden rounded-2xl border border-border bg-card">
        <div className="flex h-52 items-center justify-center text-sm text-muted-foreground" role="alert">
          {t("error")}
          <button type="button" className="ml-3 text-primary underline" onClick={() => worksState.refetch()}>
            {t("retry")}
          </button>
        </div>
      </section>
    );
  }

  return (
    <section className="overflow-hidden rounded-2xl border border-border bg-card">
      <div className="flex flex-wrap items-center justify-between gap-3 p-6">
        <div className="flex flex-wrap items-center gap-3">
          <SearchInput />
          <FilterButton isActive={isFilterOpen} onClick={() => setIsFilterOpen((currentValue) => !currentValue)} />
        </div>
      </div>

      {isFilterOpen ? (
        <div className="px-6 pb-6">
          <PreviousWorkFilterPanel key={searchParams.toString()} isOpen={isFilterOpen} onClose={() => setIsFilterOpen(false)} />
        </div>
      ) : activeFilters.length ? (
        <div className="flex flex-wrap gap-2 px-6 pb-4">
          {activeFilters.map((filter, index) => (
            <div key={`${filter.key}-${index}`} className={cn("flex h-10 items-center gap-2 rounded-[12px] border border-border bg-muted px-3")}>
              <span className="text-sm text-foreground">{filter.label}</span>
              <button
                type="button"
                onClick={() => removeFilter(filter.key)}
                className="text-muted-foreground transition-colors hover:text-foreground"
                aria-label={tCommon("close")}
              >
                <X className="size-4" />
              </button>
            </div>
          ))}
        </div>
      ) : null}

      <PreviousWorkTable
        previousWorks={worksState.works || []}
        page={params.page}
        perPage={params.per_page}
        pendingWorkId={pendingWorkId}
        onToggle={handleToggle}
        onMove={handleMove}
        onRequestEdit={(work) => router.push(`/dashboard/previous-work/${work.id}/edit`)}
        onRequestDelete={setWorkToDelete}
        onRequestDuplicate={setWorkToDuplicate}
      />

      <Pagination
        currentPage={params.page}
        totalPages={totalPages}
        totalItems={totalItems}
        itemsPerPage={params.per_page}
        className="border-t border-border"
        perPageParamName="per_page"
      />

      <PreviousWorkDeleteDialog
        open={Boolean(workToDelete)}
        onOpenChange={(open) => {
          if (!open) setWorkToDelete(null);
        }}
        onConfirm={handleDelete}
        isLoading={pendingAction === "delete"}
      />

      <PreviousWorkDuplicateDialog
        open={Boolean(workToDuplicate)}
        onOpenChange={(open) => {
          if (!open) setWorkToDuplicate(null);
        }}
        onConfirm={handleDuplicate}
        isLoading={pendingAction === "duplicate"}
      />
    </section>
  );
}
