"use client";

import { FormEvent, useMemo, useState } from "react";
import { Edit3, Plus, Trash2, X } from "lucide-react";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import type { ApiResult } from "@/modules/core/server/api";
import type { Permission } from "@/modules/core/types";
import type { Elder, ElderInput } from "@/modules/elders/types";
import { CARE_LEVEL_LABELS, ELDER_STATUS_LABELS, GENDER_LABELS } from "@/modules/elders/types";

type EldersClientProps = {
  initialElders: Elder[];
  permissions: Permission[];
};

const emptyInput: ElderInput = {
  name: "",
  gender: "male",
  age: 75,
  careLevel: "self-care",
  room: "",
  bed: "",
  status: "active",
  primaryContact: "",
  phone: "",
  medicalNotes: "",
};

function elderToInput(elder: Elder): ElderInput {
  return {
    name: elder.name,
    gender: elder.gender,
    age: elder.age,
    careLevel: elder.careLevel,
    room: elder.room,
    bed: elder.bed,
    status: elder.status,
    primaryContact: elder.primaryContact,
    phone: elder.phone,
    medicalNotes: elder.medicalNotes,
  };
}

export function EldersClient({ initialElders, permissions }: EldersClientProps): React.ReactElement {
  const [elders, setElders] = useState(initialElders);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [form, setForm] = useState<ElderInput>(emptyInput);
  const [message, setMessage] = useState("");
  const [isPending, setIsPending] = useState(false);

  const canCreate = permissions.includes("elder:create");
  const canUpdate = permissions.includes("elder:update");
  const canDelete = permissions.includes("elder:delete");
  const isEditing = editingId !== null;
  const canSubmit = isEditing ? canUpdate : canCreate;

  const metrics = useMemo(() => {
    const activeCount = elders.filter((elder) => elder.status === "active").length;
    const pendingCount = elders.filter((elder) => elder.status === "pending").length;
    const intensiveCount = elders.filter((elder) => elder.careLevel === "intensive").length;
    return { activeCount, pendingCount, intensiveCount };
  }, [elders]);

  function updateField<K extends keyof ElderInput>(key: K, value: ElderInput[K]): void {
    setForm((current) => ({ ...current, [key]: value }));
  }

  function beginCreate(): void {
    setEditingId(null);
    setForm(emptyInput);
    setMessage("");
  }

  function beginEdit(elder: Elder): void {
    setEditingId(elder.id);
    setForm(elderToInput(elder));
    setMessage("");
  }

  async function refreshElders(): Promise<void> {
    const response = await fetch("/api/elders");
    const result = (await response.json()) as ApiResult<{ elders: Elder[] }>;
    if (result.success) {
      setElders(result.elders);
    }
  }

  async function handleSubmit(event: FormEvent<HTMLFormElement>): Promise<void> {
    event.preventDefault();
    if (!canSubmit) {
      setMessage("当前角色无权保存老人档案");
      return;
    }

    setIsPending(true);
    setMessage("");

    const response = await fetch(isEditing ? `/api/elders/${editingId}` : "/api/elders", {
      method: isEditing ? "PATCH" : "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify(form),
    });
    const result = (await response.json()) as ApiResult<{ elder: Elder }>;
    setIsPending(false);

    if (!result.success) {
      setMessage(result.reason);
      return;
    }

    await refreshElders();
    setEditingId(null);
    setForm(emptyInput);
    setMessage(result.reason);
  }

  async function handleDelete(elder: Elder): Promise<void> {
    if (!canDelete) {
      setMessage("当前角色无权删除老人档案");
      return;
    }

    setIsPending(true);
    setMessage("");

    const response = await fetch(`/api/elders/${elder.id}`, { method: "DELETE" });
    const result = (await response.json()) as ApiResult<{ elder: Elder }>;
    setIsPending(false);

    if (!result.success) {
      setMessage(result.reason);
      return;
    }

    await refreshElders();
    setMessage(result.reason);
  }

  return (
    <div className="mx-auto flex w-full max-w-7xl flex-col gap-5">
      <section className="flex flex-col gap-4 border-b pb-5 lg:flex-row lg:items-end lg:justify-between">
        <div>
          <Badge variant="success">全栈 CRUD</Badge>
          <h1 className="mt-3 text-3xl font-semibold tracking-normal">老人档案</h1>
          <p className="mt-2 text-sm text-muted-foreground">服务端持久化档案、权限校验和审计记录。</p>
        </div>
        <div className="grid gap-2 text-sm sm:grid-cols-3">
          <div className="rounded-md border bg-white/72 px-4 py-3">
            <p className="text-muted-foreground">在院老人</p>
            <p className="mt-1 text-2xl font-semibold">{metrics.activeCount}</p>
          </div>
          <div className="rounded-md border bg-white/72 px-4 py-3">
            <p className="text-muted-foreground">待入住</p>
            <p className="mt-1 text-2xl font-semibold">{metrics.pendingCount}</p>
          </div>
          <div className="rounded-md border bg-white/72 px-4 py-3">
            <p className="text-muted-foreground">重点照护</p>
            <p className="mt-1 text-2xl font-semibold">{metrics.intensiveCount}</p>
          </div>
        </div>
      </section>

      <section className="grid gap-4 xl:grid-cols-[0.82fr_1.18fr]">
        <Card>
          <CardHeader className="flex flex-row items-center justify-between">
            <CardTitle>{isEditing ? "编辑档案" : "新增档案"}</CardTitle>
            {isEditing ? (
              <Button type="button" variant="ghost" size="sm" onClick={beginCreate}>
                <X className="size-4" aria-hidden="true" />
                取消
              </Button>
            ) : null}
          </CardHeader>
          <CardContent>
            <form className="grid gap-3" onSubmit={handleSubmit}>
              <label className="grid gap-1.5 text-sm font-medium">
                姓名
                <Input value={form.name} onChange={(event) => updateField("name", event.target.value)} />
              </label>
              <div className="grid gap-3 sm:grid-cols-2">
                <label className="grid gap-1.5 text-sm font-medium">
                  性别
                  <select
                    className="h-11 rounded-md border bg-background px-3 text-sm"
                    value={form.gender}
                    onChange={(event) => updateField("gender", event.target.value as ElderInput["gender"])}
                  >
                    {Object.entries(GENDER_LABELS).map(([value, label]) => (
                      <option key={value} value={value}>
                        {label}
                      </option>
                    ))}
                  </select>
                </label>
                <label className="grid gap-1.5 text-sm font-medium">
                  年龄
                  <Input
                    type="number"
                    min={0}
                    max={130}
                    value={form.age}
                    onChange={(event) => updateField("age", Number(event.target.value))}
                  />
                </label>
              </div>
              <div className="grid gap-3 sm:grid-cols-2">
                <label className="grid gap-1.5 text-sm font-medium">
                  护理等级
                  <select
                    className="h-11 rounded-md border bg-background px-3 text-sm"
                    value={form.careLevel}
                    onChange={(event) => updateField("careLevel", event.target.value as ElderInput["careLevel"])}
                  >
                    {Object.entries(CARE_LEVEL_LABELS).map(([value, label]) => (
                      <option key={value} value={value}>
                        {label}
                      </option>
                    ))}
                  </select>
                </label>
                <label className="grid gap-1.5 text-sm font-medium">
                  状态
                  <select
                    className="h-11 rounded-md border bg-background px-3 text-sm"
                    value={form.status}
                    onChange={(event) => updateField("status", event.target.value as ElderInput["status"])}
                  >
                    {Object.entries(ELDER_STATUS_LABELS).map(([value, label]) => (
                      <option key={value} value={value}>
                        {label}
                      </option>
                    ))}
                  </select>
                </label>
              </div>
              <div className="grid gap-3 sm:grid-cols-2">
                <label className="grid gap-1.5 text-sm font-medium">
                  房间
                  <Input value={form.room} onChange={(event) => updateField("room", event.target.value)} />
                </label>
                <label className="grid gap-1.5 text-sm font-medium">
                  床位
                  <Input value={form.bed} onChange={(event) => updateField("bed", event.target.value)} />
                </label>
              </div>
              <label className="grid gap-1.5 text-sm font-medium">
                联系人
                <Input
                  value={form.primaryContact}
                  onChange={(event) => updateField("primaryContact", event.target.value)}
                />
              </label>
              <label className="grid gap-1.5 text-sm font-medium">
                联系电话
                <Input value={form.phone} onChange={(event) => updateField("phone", event.target.value)} />
              </label>
              <label className="grid gap-1.5 text-sm font-medium">
                健康备注
                <textarea
                  className="min-h-24 rounded-md border bg-background px-3 py-2 text-sm outline-none transition-colors focus-visible:ring-2 focus-visible:ring-ring"
                  value={form.medicalNotes}
                  onChange={(event) => updateField("medicalNotes", event.target.value)}
                />
              </label>

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

              <Button type="submit" disabled={isPending || !canSubmit}>
                <Plus className="size-4" aria-hidden="true" />
                {isEditing ? "保存修改" : "新增老人"}
              </Button>
            </form>
          </CardContent>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle>档案列表</CardTitle>
          </CardHeader>
          <CardContent>
            <div className="overflow-x-auto rounded-md border">
              <table className="w-full min-w-[820px] text-sm">
                <thead className="bg-secondary text-left text-xs text-muted-foreground">
                  <tr>
                    <th className="px-4 py-3 font-medium">姓名</th>
                    <th className="px-4 py-3 font-medium">照护</th>
                    <th className="px-4 py-3 font-medium">床位</th>
                    <th className="px-4 py-3 font-medium">联系人</th>
                    <th className="px-4 py-3 font-medium">状态</th>
                    <th className="px-4 py-3 text-right font-medium">操作</th>
                  </tr>
                </thead>
                <tbody className="divide-y bg-card">
                  {elders.map((elder) => (
                    <tr key={elder.id}>
                      <td className="px-4 py-3">
                        <p className="font-medium">{elder.name}</p>
                        <p className="text-xs text-muted-foreground">
                          {GENDER_LABELS[elder.gender]} · {elder.age} 岁
                        </p>
                      </td>
                      <td className="px-4 py-3">{CARE_LEVEL_LABELS[elder.careLevel]}</td>
                      <td className="px-4 py-3 text-muted-foreground">
                        {elder.room}-{elder.bed}
                      </td>
                      <td className="px-4 py-3 text-muted-foreground">
                        {elder.primaryContact} / {elder.phone}
                      </td>
                      <td className="px-4 py-3">
                        <Badge variant={elder.status === "active" ? "success" : "secondary"}>
                          {ELDER_STATUS_LABELS[elder.status]}
                        </Badge>
                      </td>
                      <td className="px-4 py-3">
                        <div className="flex justify-end gap-2">
                          <Button
                            type="button"
                            variant="outline"
                            size="sm"
                            onClick={() => beginEdit(elder)}
                            disabled={!canUpdate}
                          >
                            <Edit3 className="size-4" aria-hidden="true" />
                            编辑
                          </Button>
                          <Button
                            type="button"
                            variant="destructive"
                            size="sm"
                            onClick={() => void handleDelete(elder)}
                            disabled={!canDelete || isPending}
                          >
                            <Trash2 className="size-4" aria-hidden="true" />
                            删除
                          </Button>
                        </div>
                      </td>
                    </tr>
                  ))}
                  {elders.length === 0 ? (
                    <tr>
                      <td className="px-4 py-8 text-center text-muted-foreground" colSpan={6}>
                        暂无老人档案
                      </td>
                    </tr>
                  ) : null}
                </tbody>
              </table>
            </div>
          </CardContent>
        </Card>
      </section>
    </div>
  );
}

