"use client";

import { FormEvent, useMemo, useState } from "react";
import { CheckCircle2, Clock3, Play, Search, Siren } from "lucide-react";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Dialog } from "@/components/ui/dialog";
import { Input, Textarea } from "@/components/ui/input";
import { Select } from "@/components/ui/select";
import { Table } from "@/components/ui/table";
import type { ApiResult } from "@/modules/core/server/api";
import type { CareExecutionData, CareTask, CareTaskPriority, CareTaskStatus, CareTaskType } from "@/modules/care/types";
import { CARE_TASK_PRIORITY_LABELS, CARE_TASK_STATUS_LABELS, CARE_TASK_TYPE_LABELS } from "@/modules/care/types";

type CareWorkspaceClientProps = {
  canManage: boolean;
  initialData: CareExecutionData;
};

function formatDateTime(value: string | undefined): string {
  return value ? new Date(value).toLocaleString("zh-CN") : "-";
}

function statusVariant(status: CareTaskStatus): "success" | "secondary" | "warning" {
  if (status === "completed") {
    return "success";
  }

  return status === "pending" ? "warning" : "secondary";
}

function priorityVariant(priority: CareTaskPriority): "danger" | "secondary" | "warning" {
  if (priority === "urgent") {
    return "danger";
  }

  return priority === "high" ? "warning" : "secondary";
}

export function CareWorkspaceClient({ canManage, initialData }: CareWorkspaceClientProps): React.ReactElement {
  const [data, setData] = useState(initialData);
  const [query, setQuery] = useState("");
  const [statusFilter, setStatusFilter] = useState<"all" | CareTaskStatus>("all");
  const [priorityFilter, setPriorityFilter] = useState<"all" | CareTaskPriority>("all");
  const [typeFilter, setTypeFilter] = useState<"all" | CareTaskType>("all");
  const [message, setMessage] = useState("");
  const [isPending, setIsPending] = useState(false);
  const [completeTarget, setCompleteTarget] = useState<CareTask | undefined>();
  const [executionNotes, setExecutionNotes] = useState("");

  const normalizedQuery = query.trim().toLowerCase();
  const filteredTasks = useMemo(
    () =>
      data.tasks.filter((task) => {
        const matchesQuery =
          !normalizedQuery ||
          [task.title, task.elderName, task.assigneeLabel, task.executionNotes].join(" ").toLowerCase().includes(normalizedQuery);
        const matchesStatus = statusFilter === "all" || task.status === statusFilter;
        const matchesPriority = priorityFilter === "all" || task.priority === priorityFilter;
        const matchesType = typeFilter === "all" || task.careType === typeFilter;
        return matchesQuery && matchesStatus && matchesPriority && matchesType;
      }),
    [data.tasks, normalizedQuery, priorityFilter, statusFilter, typeFilter],
  );

  async function refreshData(): Promise<void> {
    const response = await fetch("/api/care/tasks");
    const result = (await response.json()) as ApiResult<{ data: CareExecutionData }>;
    if (result.success) {
      setData(result.data);
    }
  }

  async function updateTask(task: CareTask, status: CareTaskStatus, notes = task.executionNotes): Promise<void> {
    if (!canManage) {
      setMessage("当前角色无权处理护理任务");
      return;
    }

    setIsPending(true);
    setMessage("");
    const response = await fetch(`/api/care/tasks/${task.id}`, {
      method: "PATCH",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ status, executionNotes: notes }),
    });
    const result = (await response.json()) as ApiResult<{ task: CareTask }>;
    setIsPending(false);
    setMessage(result.reason);

    if (result.success) {
      setCompleteTarget(undefined);
      setExecutionNotes("");
      await refreshData();
    }
  }

  function openCompleteDialog(task: CareTask): void {
    setCompleteTarget(task);
    setExecutionNotes(task.executionNotes);
    setMessage("");
  }

  function closeCompleteDialog(): void {
    if (isPending) {
      return;
    }

    setCompleteTarget(undefined);
    setExecutionNotes("");
  }

  async function submitComplete(event: FormEvent<HTMLFormElement>): Promise<void> {
    event.preventDefault();
    if (!completeTarget) {
      return;
    }

    await updateTask(completeTarget, "completed", executionNotes);
  }

  return (
    <div className="mx-auto flex w-full max-w-7xl flex-col gap-5">
      <section className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
        <MetricCard icon={Clock3} label="待处理" value={data.metrics.pending} />
        <MetricCard icon={Play} label="进行中" value={data.metrics.inProgress} />
        <MetricCard icon={CheckCircle2} label="今日完成" value={data.metrics.completedToday} />
        <MetricCard icon={Siren} label="高优先级" value={data.metrics.highPriority} />
      </section>

      <section className="flex flex-col gap-3 border-b pb-4 xl:flex-row xl:items-center xl:justify-between">
        <div>
          <h1 className="text-3xl font-semibold tracking-normal">护理服务</h1>
          <p className="mt-2 text-sm text-muted-foreground">按老人、任务类型、优先级和执行状态推进每日护理服务。</p>
        </div>
        <div className="grid gap-2 sm:grid-cols-2 xl:flex xl:items-center">
          <label className="relative block sm:col-span-2 xl:col-span-1">
            <Search className="pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
            <Input
              className="w-full pl-9 xl:w-72"
              onChange={(event) => setQuery(event.target.value)}
              placeholder="搜索老人、任务或执行人"
              value={query}
            />
          </label>
          <Select
            aria-label="任务状态"
            onValueChange={(value) => setStatusFilter(value as "all" | CareTaskStatus)}
            options={[
              { value: "all", label: "全部状态" },
              ...Object.entries(CARE_TASK_STATUS_LABELS).map(([value, label]) => ({ value, label })),
            ]}
            value={statusFilter}
          />
          <Select
            aria-label="优先级"
            onValueChange={(value) => setPriorityFilter(value as "all" | CareTaskPriority)}
            options={[
              { value: "all", label: "全部优先级" },
              ...Object.entries(CARE_TASK_PRIORITY_LABELS).map(([value, label]) => ({ value, label })),
            ]}
            value={priorityFilter}
          />
          <Select
            aria-label="护理类型"
            onValueChange={(value) => setTypeFilter(value as "all" | CareTaskType)}
            options={[
              { value: "all", label: "全部类型" },
              ...Object.entries(CARE_TASK_TYPE_LABELS).map(([value, label]) => ({ value, label })),
            ]}
            value={typeFilter}
          />
        </div>
      </section>

      {message ? (
        <p className="rounded-md bg-secondary px-3 py-2 text-sm text-secondary-foreground" role="status">
          {message}
        </p>
      ) : null}

      <Card>
        <CardHeader>
          <CardTitle>护理任务</CardTitle>
          <CardDescription>任务状态更新会写入审计日志，完成时保存执行备注和完成时间。</CardDescription>
        </CardHeader>
        <CardContent className="overflow-x-auto">
          <Table className="w-full min-w-[980px] text-sm">
            <Table.Header className="bg-secondary text-left text-xs text-muted-foreground">
              <Table.Row>
                <Table.Head className="px-4 py-3 font-medium">任务</Table.Head>
                <Table.Head className="px-4 py-3 font-medium">老人</Table.Head>
                <Table.Head className="px-4 py-3 font-medium">类型</Table.Head>
                <Table.Head className="px-4 py-3 font-medium">优先级</Table.Head>
                <Table.Head className="px-4 py-3 font-medium">状态</Table.Head>
                <Table.Head className="px-4 py-3 font-medium">计划时间</Table.Head>
                <Table.Head className="px-4 py-3 font-medium">执行人</Table.Head>
                <Table.Head className="px-4 py-3 font-medium">完成时间</Table.Head>
                <Table.Head className="px-4 py-3 text-right font-medium">操作</Table.Head>
              </Table.Row>
            </Table.Header>
            <Table.Body className="divide-y bg-card">
              {filteredTasks.map((task) => (
                <Table.Row key={task.id}>
                  <Table.Cell className="px-4 py-3">
                    <p className="font-medium">{task.title}</p>
                    <p className="text-xs text-muted-foreground">{task.executionNotes || "-"}</p>
                  </Table.Cell>
                  <Table.Cell className="px-4 py-3 text-muted-foreground">{task.elderName || "公共区域"}</Table.Cell>
                  <Table.Cell className="px-4 py-3 text-muted-foreground">{CARE_TASK_TYPE_LABELS[task.careType]}</Table.Cell>
                  <Table.Cell className="px-4 py-3">
                    <Badge variant={priorityVariant(task.priority)}>{CARE_TASK_PRIORITY_LABELS[task.priority]}</Badge>
                  </Table.Cell>
                  <Table.Cell className="px-4 py-3">
                    <Badge variant={statusVariant(task.status)}>{CARE_TASK_STATUS_LABELS[task.status]}</Badge>
                  </Table.Cell>
                  <Table.Cell className="px-4 py-3 text-muted-foreground">{formatDateTime(task.scheduledAt)}</Table.Cell>
                  <Table.Cell className="px-4 py-3 text-muted-foreground">{task.assigneeLabel || "-"}</Table.Cell>
                  <Table.Cell className="px-4 py-3 text-muted-foreground">{formatDateTime(task.completedAt)}</Table.Cell>
                  <Table.Cell className="px-4 py-3">
                    <div className="flex justify-end gap-2">
                      {task.status === "pending" ? (
                        <Button disabled={!canManage || isPending} onClick={() => updateTask(task, "in_progress")} size="sm" type="button" variant="outline">
                          开始
                        </Button>
                      ) : null}
                      {task.status === "pending" || task.status === "in_progress" ? (
                        <Button disabled={!canManage || isPending} onClick={() => openCompleteDialog(task)} size="sm" type="button">
                          完成
                        </Button>
                      ) : null}
                    </div>
                  </Table.Cell>
                </Table.Row>
              ))}
              {filteredTasks.length === 0 ? (
                <Table.Row>
                  <Table.Cell className="px-4 py-8 text-center text-muted-foreground" colSpan={9}>
                    暂无护理任务
                  </Table.Cell>
                </Table.Row>
              ) : null}
            </Table.Body>
          </Table>
        </CardContent>
      </Card>

      <Dialog description={completeTarget?.title} onClose={closeCompleteDialog} open={completeTarget !== undefined} title="完成护理任务">
        <form className="grid gap-3" onSubmit={submitComplete}>
          <Textarea label="执行备注" onChange={(event) => setExecutionNotes(event.target.value)} value={executionNotes} />
          <div className="flex flex-col-reverse gap-2 sm:flex-row sm:justify-end">
            <Button disabled={isPending} onClick={closeCompleteDialog} type="button" variant="outline">
              取消
            </Button>
            <Button disabled={isPending} type="submit">
              保存完成
            </Button>
          </div>
        </form>
      </Dialog>
    </div>
  );
}

function MetricCard({
  icon: Icon,
  label,
  value,
}: {
  icon: React.ComponentType<{ "aria-hidden"?: boolean; className?: string }>;
  label: string;
  value: number;
}): React.ReactElement {
  return (
    <Card>
      <CardHeader className="flex flex-row items-center justify-between p-4">
        <div>
          <CardDescription>{label}</CardDescription>
          <CardTitle className="mt-2 text-3xl">{value}</CardTitle>
        </div>
        <Icon className="size-5 text-primary" aria-hidden={true} />
      </CardHeader>
    </Card>
  );
}
