import { useMemo, useState } from "react";
import { Grid2X2, List, RefreshCw, Search, UserRoundCheck } from "lucide-react";
import { Button } from "@/shared/common/ui/button";
import { AdvancedTable } from "@/shared/common/ui/table/AdvancedTable";
import { useEmployeePositionChangeRequests } from "@/user-management/hooks/useEmployeePositionChangeRequests";
import type { EmployeePositionChangeRequest } from "@/user-management/services/api/employeePositionChangeRequestService";
import UserPositionApprovalCards from "./UserPositionApprovalCards";
import { createUserPositionApprovalColumns } from "./UserPositionApprovalColumns";
import UserPositionApprovalDecisionDialog from "./UserPositionApprovalDecisionDialog";
import type { UserPositionApprovalDecision } from "./UserPositionApprovalActions";
import { getDisplayName } from "./userPositionApprovalUtils";

type ViewMode = "table" | "card";
const PAGE_SIZE = 10;

export default function UserPositionApprovalList() {
  const [viewMode, setViewMode] = useState<ViewMode>("table");
  const [search, setSearch] = useState("");
  const [pageIndex, setPageIndex] = useState(0);
  const [decision, setDecision] = useState<{
    type: UserPositionApprovalDecision;
    item: EmployeePositionChangeRequest;
  } | null>(null);
  const [comment, setComment] = useState("");

  const { requestsQuery, approve, reject, isApproving, isRejecting } =
    useEmployeePositionChangeRequests({ take: 50, skip: 0, status: "pending" });

  const items = useMemo(() => {
    const term = search.trim().toLowerCase();
    const source = requestsQuery.data?.items ?? [];
    if (!term) return source;
    return source.filter((item) =>
      [
        getDisplayName(item.employee?.name),
        item.employee?.user?.email,
        getDisplayName(item.fromPosition?.name),
        getDisplayName(item.toPosition?.name),
        item.status,
      ].some((value) => value?.toLowerCase().includes(term)),
    );
  }, [requestsQuery.data?.items, search]);

  const isSubmitting = isApproving || isRejecting;
  const paginatedItems = useMemo(() => {
    const start = pageIndex * PAGE_SIZE;
    return items.slice(start, start + PAGE_SIZE);
  }, [items, pageIndex]);

  const openDecision = (
    type: UserPositionApprovalDecision,
    item: EmployeePositionChangeRequest,
  ) => {
    setComment("");
    setDecision({ type, item });
  };

  const closeDecision = () => {
    setDecision(null);
    setComment("");
  };

  const submitDecision = async () => {
    if (!decision) return;
    const payload = { id: decision.item.id, comment: comment.trim() };
    if (decision.type === "approve") {
      await approve(payload);
    } else {
      await reject(payload);
    }
    closeDecision();
  };

  const columns = useMemo(
    () => createUserPositionApprovalColumns(openDecision),
    [],
  );

  const handlePageChange = (newPage: number) => {
    setPageIndex(newPage);
  };

  return (
    <div className="w-full space-y-6 p-4 sm:p-6">
      <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
        <div>
          <h1 className="flex items-center gap-2 text-2xl font-bold text-slate-900 dark:text-slate-100">
            <UserRoundCheck className="h-6 w-6 text-primary" />
            User Position Approvals
          </h1>
          <p className="mt-1 text-sm text-slate-500 dark:text-slate-400">
            Review pending employee position change requests.
          </p>
        </div>
        <span className="w-fit rounded-full bg-amber-100 px-3 py-1 text-sm font-medium text-amber-800 dark:bg-amber-950 dark:text-amber-200">
          {requestsQuery.data?.count ?? 0} pending
        </span>
      </div>

      <div className="flex flex-col gap-3 sm:flex-row sm:items-center">
        <div className="relative flex-1">
          <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400" />
          <input
            value={search}
            onChange={(event) => {
              setSearch(event.target.value);
              setPageIndex(0);
            }}
            placeholder="Search by user, email, position, or status"
            className="h-10 w-full rounded-md border border-slate-200 bg-white pl-9 pr-3 text-sm outline-none focus:ring-2 focus:ring-primary/30 dark:border-slate-700 dark:bg-slate-900"
          />
        </div>
        <div className="flex rounded-md border border-slate-200 p-1 dark:border-slate-700">
          <Button
            size="sm"
            variant={viewMode === "table" ? "default" : "ghost"}
            onClick={() => setViewMode("table")}
            aria-label="Table view"
          >
            <List className="h-4 w-4" />
          </Button>
          <Button
            size="sm"
            variant={viewMode === "card" ? "default" : "ghost"}
            onClick={() => setViewMode("card")}
            aria-label="Card view"
          >
            <Grid2X2 className="h-4 w-4" />
          </Button>
        </div>
      </div>

      {requestsQuery.isError ? (
        <div className="rounded-lg border border-red-200 bg-red-50 p-8 text-center dark:border-red-900 dark:bg-red-950/30">
          <p className="text-sm text-red-700 dark:text-red-300">
            The employee position change request API is not available.
          </p>
          <Button
            variant="outline"
            className="mt-4 gap-2"
            onClick={() => requestsQuery.refetch()}
          >
            <RefreshCw className="h-4 w-4" /> Retry
          </Button>
        </div>
      ) : viewMode === "card" ? (
        requestsQuery.isLoading ? (
          <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-3">
            {[1, 2, 3, 4, 5, 6].map((item) => (
              <div
                key={item}
                className="h-44 animate-pulse rounded-lg bg-slate-200 dark:bg-slate-800"
              />
            ))}
          </div>
        ) : items.length === 0 ? (
          <div className="rounded-lg border border-dashed p-12 text-center text-slate-500 dark:border-slate-700">
            <UserRoundCheck className="mx-auto mb-3 h-9 w-9" />
            <p className="font-medium">No pending user position approvals</p>
          </div>
        ) : (
          <UserPositionApprovalCards items={items} onDecision={openDecision} />
        )
      ) : (
        <AdvancedTable
          columns={columns}
          data={paginatedItems}
          tableName="User Position Approvals"
          itemCount={items.length}
          pageIndex={pageIndex}
          pageSize={PAGE_SIZE}
          onPageChange={handlePageChange}
          nextFunction={() => handlePageChange(pageIndex + 1)}
          prevFunction={() => handlePageChange(Math.max(pageIndex - 1, 0))}
          refresh={() => requestsQuery.refetch()}
          isLoading={requestsQuery.isLoading}
          hideToolbarFilter
        />
      )}

      <UserPositionApprovalDecisionDialog
        decision={decision}
        comment={comment}
        isSubmitting={isSubmitting}
        onCommentChange={setComment}
        onClose={closeDecision}
        onSubmit={submitDecision}
      />
    </div>
  );
}
