"use client";

import { useRouter } from "next/navigation";
import {
  flexRender,
  getCoreRowModel,
  type ColumnDef,
  useReactTable,
} from "@tanstack/react-table";
import { useMemo } from "react";

import type { MaestroListItem } from "@/lib/maestros";
import { cn } from "@/lib/utils";
import {
  formatDate,
  getAccountTypeLabel,
  getActivateStatusLabel,
} from "@/lib/utils";

type MaestrosTableProps = {
  data: MaestroListItem[];
};

export function MaestrosTable({ data }: MaestrosTableProps) {
  const router = useRouter();
  const columns = useMemo<ColumnDef<MaestroListItem>[]>(
    () => [
      {
        accessorKey: "maestroID",
        header: "ID",
        cell: ({ row }) => (
          <span className="font-mono text-xs tabular-nums">
            {row.original.maestroID}
          </span>
        ),
      },
      {
        accessorKey: "name",
        header: "이름",
        cell: ({ row }) => (
          <div className="min-w-32">
            <p className="font-medium">{row.original.name}</p>
            <p className="mt-1 text-xs text-muted-foreground md:hidden">
              {row.original.email}
            </p>
          </div>
        ),
      },
      {
        accessorKey: "email",
        header: "이메일",
        cell: ({ row }) => (
          <span className="text-muted-foreground">{row.original.email}</span>
        ),
      },
      {
        accessorKey: "accountType",
        header: "계정 유형",
        cell: ({ row }) => getAccountTypeLabel(row.original.accountType),
      },
      {
        accessorKey: "activateStatus",
        header: "상태",
        cell: ({ row }) => (
          <span
            className={cn(
              "inline-flex h-6 items-center rounded-md border px-2 text-xs font-medium",
              getActivateStatusBadgeClass(row.original)
            )}
          >
            {getActivateStatusLabel(row.original.activateStatus)}
          </span>
        ),
      },
      {
        accessorKey: "playerCount",
        header: "학생 수",
        cell: ({ row }) => (
          <span className="tabular-nums">
            {row.original.playerCount.toLocaleString()}
          </span>
        ),
      },
      {
        accessorKey: "acceptClausesDateTime",
        header: "가입일",
        cell: ({ row }) => formatDate(row.original.acceptClausesDateTime),
      },
      {
        accessorKey: "availableActivateDateTime",
        header: "사용 가능일",
        cell: ({ row }) => formatDate(row.original.availableActivateDateTime),
      },
    ],
    []
  );

  // TanStack Table manages internal functions that React Compiler should not memoize.
  // eslint-disable-next-line react-hooks/incompatible-library
  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
  });

  return (
    <div className="overflow-hidden rounded-lg border bg-background">
      <div className="overflow-x-auto">
        <table className="w-full min-w-[980px] border-collapse text-sm">
          <thead className="bg-muted/60">
            {table.getHeaderGroups().map((headerGroup) => (
              <tr className="border-b" key={headerGroup.id}>
                {headerGroup.headers.map((header) => (
                  <th
                    className="h-10 px-3 text-left text-xs font-medium text-muted-foreground"
                    key={header.id}
                  >
                    {header.isPlaceholder
                      ? null
                      : flexRender(
                          header.column.columnDef.header,
                          header.getContext()
                        )}
                  </th>
                ))}
              </tr>
            ))}
          </thead>
          <tbody>
            {table.getRowModel().rows.length > 0 ? (
              table.getRowModel().rows.map((row) => (
                <tr
                  aria-label={`${row.original.name} 마에스트로 상세 보기`}
                  className="cursor-pointer border-b transition-colors last:border-b-0 hover:bg-muted/60 focus-visible:bg-muted/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset"
                  key={row.id}
                  onClick={() => {
                    router.push(`/maestros/${row.original.maestroID}`);
                  }}
                  onKeyDown={(event) => {
                    if (event.key === "Enter" || event.key === " ") {
                      event.preventDefault();
                      router.push(`/maestros/${row.original.maestroID}`);
                    }
                  }}
                  role="link"
                  tabIndex={0}
                >
                  {row.getVisibleCells().map((cell) => (
                    <td className="h-12 px-3 align-middle" key={cell.id}>
                      {flexRender(
                        cell.column.columnDef.cell,
                        cell.getContext()
                      )}
                    </td>
                  ))}
                </tr>
              ))
            ) : (
              <tr>
                <td
                  className="h-28 px-3 text-center text-sm text-muted-foreground"
                  colSpan={columns.length}
                >
                  조건에 맞는 마에스트로가 없습니다.
                </td>
              </tr>
            )}
          </tbody>
        </table>
      </div>
    </div>
  );
}

function getActivateStatusBadgeClass(maestro: MaestroListItem) {
  if (
    maestro.activateStatus === 2 &&
    isBeforeToday(maestro.availableActivateDateTime)
  ) {
    return "border-rose-200 bg-rose-50 text-rose-700";
  }

  if (maestro.activateStatus === 2) {
    return "border-emerald-200 bg-emerald-50 text-emerald-700";
  }

  if (maestro.activateStatus === 100) {
    return "border-muted bg-muted text-muted-foreground";
  }

  return "border-amber-200 bg-amber-50 text-amber-700";
}

function isBeforeToday(value: string) {
  const date = new Date(value);

  if (Number.isNaN(date.getTime())) {
    return false;
  }

  const targetDate = new Date(date);
  const today = new Date();

  targetDate.setHours(0, 0, 0, 0);
  today.setHours(0, 0, 0, 0);

  return targetDate.getTime() < today.getTime();
}
