import { AppShell } from "@/components/app-shell"
import { myTasks } from "@/lib/services/tasks"
import { isOwed } from "@/lib/task-actions"
import { isView, type View } from "@/lib/task-views"
import { groupRuns } from "@/lib/team-view"
import { requireUser } from "@/lib/services/session"
import { translator } from "@/lib/i18n"
import { CarriedOverTable } from "./carried-over"
import { TasksTable } from "./tasks-table"
import { ViewSwitch } from "./view-switch"

/**
 * My Tasks, the screen every one of the 193 people opens.
 *
 * Personal, per routes.json, and personal for an admin too. Work waiting for
 * somebody's check is a different question and a different page. There is no
 * bigger version of this list for a bigger role: what a tier changes is what
 * can be done to one task, not how many tasks somebody is shown.
 */
export default async function Page({
  searchParams,
}: {
  searchParams: Promise<Record<string, string | string[] | undefined>>
}) {
  const user = await requireUser()
  const params = await searchParams
  const view: View = isView(params.view) ? params.view : "day"

  const list = await myTasks(user, view)
  const t = translator(user.language)

  // "Still to do" counts everything still owed, so a missed instance inside the
  // window counts: it was never done, and a figure that left it out would tell
  // somebody they had less to do because a day passed.
  const open = list.rows.filter((r) => isOwed(r.status)).length

  /*
    Grouped on the duty alone, which is the whole key here.

    `myTasks` selects on `assignee_person_id = me`, so every row in this list is
    the reader's and the person the team overview puts in its key is a constant
    on all of them. Carrying it would be spelling out a value that cannot vary.
  */
  const carriedOver = groupRuns(list.overdue, (row) => row.templateId)

  return (
    <AppShell title={"tasks.title"} user={user}>
      <div className="flex flex-col gap-4">
        <div className="flex flex-wrap items-center justify-between gap-3">
          <p className="text-foreground/80">
            {list.rows.length === 0
              ? t("tasks.nothingDue")
              : t("tasks.stillToDo", { open, total: list.rows.length })}
          </p>
          <ViewSwitch current={view} />
        </div>

        {/*
          Carried over, above the window and not below it. A task left undone on
          Tuesday is the first thing somebody should see on Thursday, and a list
          that puts it under today's work is a list that hides it.

          Nothing carried over means no section, so somebody with a clean slate
          meets none of the grouping: no table, no chevrons, no line telling
          them what they do not owe.

          The heading counts dates and not lines. It is the size of the debt,
          and the number that would drop from 12 to 3 the day this screen
          started grouping is the number nobody may be told is smaller.
        */}
        {carriedOver.length > 0 ? (
          <section className="flex flex-col gap-2">
            <h2 className="text-lg font-semibold">
              {t("tasks.carriedOver")}{" "}
              <span className="font-normal text-foreground/70">
                ({list.overdue.length})
              </span>
            </h2>
            <CarriedOverTable groups={carriedOver} />
          </section>
        ) : null}

        {/*
          Today, ungrouped. Each row is a different thing to do and the list is
          short, so there is no repetition for a group to collapse and a chevron
          would only put the work behind a click.
        */}
        <TasksTable
          rows={list.rows}
          empty={
            view === "day" ? "tasks.nothingDueToday" : "tasks.nothingInWindow"
          }
          pageSize={25}
        />
      </div>
    </AppShell>
  )
}
