"use client"

import Link from "next/link"
import type { ColumnDef } from "@tanstack/react-table"

import { Badge } from "@/components/ui/badge"
import { DataTableColumnHeader } from "@/components/ui/data-table"
import { shortDay } from "@/lib/i18n/dates"
import type { Locale, Translate } from "@/lib/i18n"
import type { MessageKey } from "@/lib/i18n/messages"
import type { TaskRow } from "@/lib/services/tasks"

/**
 * The five statuses, as words rather than colours alone. A row that says only
 * "late" in red says nothing to somebody who cannot separate red from green,
 * and this list is read on a factory floor by 193 people.
 *
 * Exported so the team tables read the same five badges rather than keeping a
 * second copy that drifts. Both files are client components, so this crosses no
 * boundary: what may not be shared is a value from a service.
 */
export const STATUS: Record<
  TaskRow["status"],
  {
    label: MessageKey
    variant: "default" | "secondary" | "outline" | "destructive"
  }
> = {
  todo: { label: "status.todo", variant: "outline" },
  started: { label: "status.started", variant: "secondary" },
  finished: { label: "status.finished", variant: "default" },
  checked: { label: "status.checked", variant: "secondary" },
  missed: { label: "status.missed", variant: "destructive" },
}

/**
 * A function of the language and not a constant.
 *
 * TanStack calls `header` and `cell` as plain functions rather than rendering
 * them as components, so a hook inside one of them would break the rules of
 * hooks. The words are resolved once, here, by whoever already holds a
 * translator.
 */
export function taskColumns(
  t: Translate,
  locale: Locale,
): ColumnDef<TaskRow>[] {
  return [
    {
      accessorKey: "dueDate",
      meta: { label: t("tasks.due") },
      header: ({ column }) => (
        <DataTableColumnHeader column={column} title={t("tasks.due")} />
      ),
      cell: ({ row }) => (
        <span className="whitespace-nowrap tabular-nums">
          {shortDay(row.original.dueDate, locale)}
        </span>
      ),
    },
    {
      accessorKey: "description",
      meta: { label: t("tasks.task") },
      header: ({ column }) => (
        <DataTableColumnHeader column={column} title={t("tasks.task")} />
      ),
      cell: ({ row }) => (
        <Link
          href={`/tasks/${row.original.id}`}
          className="font-medium hover:underline"
        >
          {row.original.description}
        </Link>
      ),
    },
    {
      accessorKey: "status",
      meta: { label: t("tasks.status") },
      header: ({ column }) => (
        <DataTableColumnHeader column={column} title={t("tasks.status")} />
      ),
      cell: ({ row }) => {
        const { label, variant } = STATUS[row.original.status]
        return (
          <div className="flex items-center gap-2">
            <Badge variant={variant}>{t(label)}</Badge>
            {/*
              Late is computed from the day and never stored, so it is a second
              fact about a task rather than a sixth status. A task can be To do
              and late; it cannot be Missed and late, because missed already
              means its time ran out.
            */}
            {row.original.late ? (
              <Badge variant="destructive">{t("status.late")}</Badge>
            ) : null}
          </div>
        )
      },
    },
    {
      accessorKey: "checker",
      meta: { label: t("tasks.checkedBy") },
      enableSorting: false,
      header: ({ column }) => (
        <DataTableColumnHeader column={column} title={t("tasks.checkedBy")} />
      ),
      // The name is data, in Thai for 183 of the 193 people, and nothing here
      // translates it.
      cell: ({ row }) => row.original.checker ?? "—",
    },
    // There is no Position column, and there cannot usefully be one. Every task
    // here is assigned from the holder of a position, and a person holds one, so
    // the column read the same title on every row. The position is who the
    // person is, and the sidebar already says it.
  ]
}
