"use client";

/**
 * 临床情景对话对练：输入情景标识发起会话 → 逐轮对话 → 结束生成三维评估报告。
 */

import { useState } from "react";
import { Send, Stethoscope } from "lucide-react";

import {
  CredibilityBadge,
  RawDetails,
  ScoreBar,
  StatTile,
} from "@/components/display";
import { ErrorBanner, Loading, PageHeading } from "@/components/feedback";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { UsageGuide } from "@/components/usage-guide";
import { ApiError } from "@/lib/api";
import { clinicalApi } from "@/lib/services";
import type { DialogueReport } from "@/lib/types";
import { cn } from "@/lib/utils";

/* eslint-disable @typescript-eslint/no-explicit-any */

interface ChatTurn {
  role: "student" | "system";
  text: string;
}

export default function ClinicalPage() {
  const [scenarioId, setScenarioId] = useState("");
  const [session, setSession] = useState<any>(null);
  const [turns, setTurns] = useState<ChatTurn[]>([]);
  const [input, setInput] = useState("");
  const [report, setReport] = useState<DialogueReport | null>(null);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);

  async function run<T>(fn: () => Promise<T>, after?: (v: T) => void) {
    setError(null);
    setBusy(true);
    try {
      after?.(await fn());
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "操作失败");
    } finally {
      setBusy(false);
    }
  }

  function extractSystemReply(v: any): string {
    return (
      v?.systemResponse ??
      v?.reply ??
      v?.message ??
      v?.turn?.systemResponse ??
      JSON.stringify(v)
    );
  }

  function sendTurn() {
    if (!input || busy || !session) return;
    const text = input;
    setTurns((t) => [...t, { role: "student", text }]);
    setInput("");
    run(
      () => clinicalApi.sendTurn(session.id, { studentInput: text }),
      (v: any) =>
        setTurns((t) => [...t, { role: "system", text: extractSystemReply(v) }]),
    );
  }

  return (
    <div className="space-y-6">
      <PageHeading
        icon={<Stethoscope className="size-5" />}
        title="临床模拟"
        description="模拟真实问诊、查体与医患沟通情景，与 AI 患者交互后获得多维评估反馈。"
      />

      <UsageGuide
        steps={[
          { title: "输入情景标识", detail: "如「胸痛分诊」，选择要演练的临床情景。" },
          { title: "开始对话", detail: "点击「开始对话」进入情景，AI 扮演患者 / 同行角色。" },
          { title: "逐轮问诊", detail: "在输入框输入问诊或处置内容，回车或「发送」推进对话。" },
          { title: "结束并评估", detail: "点击「结束并评估」获得沟通、临床思维等三维评分与点评。" },
        ]}
        tip="尽量像真实问诊一样有条理地展开；评估报告含可信度标注，注意核验 AI 给出的信息。"
      />

      <Card>
        <CardHeader>
          <CardTitle>发起对练</CardTitle>
        </CardHeader>
        <CardContent>
          <div className="flex flex-wrap items-end gap-3">
            <div className="min-w-[220px] flex-1">
              <Label>情景标识</Label>
              <Input
                value={scenarioId}
                onChange={(e) => setScenarioId(e.target.value)}
                placeholder="如：胸痛分诊"
              />
            </div>
            <Button
              disabled={!scenarioId || busy}
              onClick={() =>
                run(
                  () => clinicalApi.start(scenarioId),
                  (v: any) => {
                    setSession(v);
                    setTurns([]);
                    setReport(null);
                  },
                )
              }
            >
              开始对话
            </Button>
          </div>
          {error && (
            <div className="mt-4">
              <ErrorBanner message={error} />
            </div>
          )}
        </CardContent>
      </Card>

      {session && !report && (
        <Card>
          <CardHeader>
            <CardTitle>对话</CardTitle>
          </CardHeader>
          <CardContent>
            <div className="scrollbar-thin mb-4 max-h-96 space-y-3 overflow-auto">
              {turns.length === 0 && (
                <p className="text-sm text-muted-foreground">
                  输入你的第一句话开始对话。
                </p>
              )}
              {turns.map((t, i) => (
                <div
                  key={i}
                  className={cn(
                    "flex",
                    t.role === "student" ? "justify-end" : "justify-start",
                  )}
                >
                  <div
                    className={cn(
                      "max-w-[80%] rounded-2xl px-4 py-2 text-sm",
                      t.role === "student"
                        ? "bg-primary text-primary-foreground"
                        : "bg-muted text-foreground",
                    )}
                  >
                    {t.text}
                  </div>
                </div>
              ))}
            </div>

            {busy && <Loading />}

            <div className="flex gap-3">
              <Input
                value={input}
                onChange={(e) => setInput(e.target.value)}
                placeholder="输入对话内容…"
                onKeyDown={(e) => {
                  if (e.key === "Enter" && !e.shiftKey) {
                    e.preventDefault();
                    sendTurn();
                  }
                }}
              />
              <Button disabled={!input || busy} onClick={sendTurn}>
                <Send /> 发送
              </Button>
              <Button
                variant="outline"
                disabled={busy}
                onClick={() =>
                  run(
                    () => clinicalApi.finish(session.id),
                    (v: any) => setReport(v),
                  )
                }
              >
                结束并评估
              </Button>
            </div>
          </CardContent>
        </Card>
      )}

      {report && (
        <Card>
          <CardHeader>
            <CardTitle>三维评估报告</CardTitle>
          </CardHeader>
          <CardContent>
            <div className="mb-4 flex items-center gap-4">
              <StatTile
                label="综合评分"
                value={report.overallScore?.toFixed?.(0) ?? report.overallScore}
                tone="primary"
              />
              <div className="text-sm text-muted-foreground">
                共 {report.turnCount} 轮对话
              </div>
            </div>

            <div className="space-y-3">
              {report.dimensions?.map((d) => (
                <div key={d.dimension}>
                  <ScoreBar
                    label={d.dimensionName}
                    score={d.score}
                    tone={d.score >= 60 ? "success" : "warning"}
                  />
                  {d.comment && (
                    <p className="mt-1 text-xs text-muted-foreground">{d.comment}</p>
                  )}
                </div>
              ))}
            </div>

            <div className="mt-4">
              <CredibilityBadge annotation={report.annotation} />
            </div>

            <RawDetails data={report} />
          </CardContent>
        </Card>
      )}
    </div>
  );
}
