import { describe, expect, it } from "vitest";

import type { AiCitation, ElderAiAnalysisOutput, ElderAiFinding, ElderAiRecommendation, KnowledgeEntryInput } from "@/modules/ai/types";
import {
  parseDataScopes,
  validateElderAiAnalysisOutput,
  validateKnowledgeEntryInput,
} from "@/modules/ai/types";

const validKnowledgeInput: KnowledgeEntryInput = {
  scope: "organization",
  organizationId: "org-1",
  title: "Fall prevention guidance",
  category: "Safety",
  tags: "fall,night",
  body: "Residents with night wandering need bed exit checks and clear walkways.",
  status: "enabled",
};

const validFinding: ElderAiFinding = {
  category: "fall-risk",
  severity: "warning",
  evidence: "Night wandering and prior fall history are present.",
  citationIds: ["resident-1"],
};

const validRecommendation: ElderAiRecommendation = {
  title: "Increase night checks",
  priority: "high",
  rationale: "Additional observation reduces missed night wandering events.",
  suggestedNextStep: "Add a night-shift round note for the next care review.",
  citationIds: ["resident-1"],
};

const validCitation: AiCitation = {
  id: "resident-1",
  sourceType: "resident_context",
  sourceId: "elder-1",
  title: "Resident profile",
  excerpt: "Night wandering and prior fall history.",
};

const validAnalysisOutput: ElderAiAnalysisOutput = {
  overallRiskLevel: "medium",
  summary: "Resident has elevated fall risk at night.",
  keyFindings: [validFinding],
  recommendations: [validRecommendation],
  dataGaps: ["Recent gait assessment is unavailable."],
  citations: [validCitation],
  confidence: 0.72,
  modelSummary: {
    provider: "openai-compatible",
    chatModel: "gpt-test",
    embeddingModel: "embedding-test",
  },
};

describe("AI validators", () => {
  describe("validateKnowledgeEntryInput", () => {
    it("accepts a scoped entry and trims user-authored text fields", () => {
      const result = validateKnowledgeEntryInput({
        ...validKnowledgeInput,
        title: "  Fall prevention guidance  ",
        category: "  Safety  ",
        tags: "  fall,night  ",
        body: "  Residents need clear walkways.  ",
      });

      expect(result).toEqual({
        success: true,
        input: {
          ...validKnowledgeInput,
          title: "Fall prevention guidance",
          category: "Safety",
          tags: "fall,night",
          body: "Residents need clear walkways.",
        },
      });
    });

    it.each([
      { name: "non-object payload", value: null, reason: "请求数据格式无效" },
      { name: "unknown scope", value: { ...validKnowledgeInput, scope: "facility" }, reason: "知识库范围无效" },
      { name: "unknown status", value: { ...validKnowledgeInput, status: "archived" }, reason: "知识库状态无效" },
      { name: "blank title", value: { ...validKnowledgeInput, title: "   " }, reason: "知识标题不能为空" },
      { name: "blank body", value: { ...validKnowledgeInput, body: "\n\t" }, reason: "知识内容不能为空" },
    ])("rejects $name", ({ value, reason }) => {
      expect(validateKnowledgeEntryInput(value)).toEqual({ success: false, reason });
    });
  });

  describe("validateElderAiAnalysisOutput", () => {
    it("accepts valid model output, coerces numeric confidence strings, and clamps the public score", () => {
      const result = validateElderAiAnalysisOutput({
        ...validAnalysisOutput,
        confidence: "1.25",
      });

      expect(result).toEqual({
        ...validAnalysisOutput,
        confidence: 1,
      });
    });

    it.each([
      {
        name: "unknown risk level",
        value: { ...validAnalysisOutput, overallRiskLevel: "urgent" },
      },
      {
        name: "finding with invalid severity",
        value: {
          ...validAnalysisOutput,
          keyFindings: [{ ...validFinding, severity: "debug" }],
        },
      },
      {
        name: "recommendation with invalid priority",
        value: {
          ...validAnalysisOutput,
          recommendations: [{ ...validRecommendation, priority: "soon" }],
        },
      },
      {
        name: "mixed citation id array",
        value: {
          ...validAnalysisOutput,
          keyFindings: [{ ...validFinding, citationIds: ["resident-1", 42] }],
        },
      },
      {
        name: "invalid citation source",
        value: {
          ...validAnalysisOutput,
          citations: [{ ...validCitation, sourceType: "web" }],
        },
      },
      {
        name: "unexpected model provider",
        value: {
          ...validAnalysisOutput,
          modelSummary: { ...validAnalysisOutput.modelSummary, provider: "anthropic" },
        },
      },
      {
        name: "non-finite confidence",
        value: { ...validAnalysisOutput, confidence: "not-a-number" },
      },
    ])("rejects $name", ({ value }) => {
      expect(validateElderAiAnalysisOutput(value)).toBeNull();
    });
  });

  describe("parseDataScopes", () => {
    it("keeps only recognized scope strings in caller order", () => {
      expect(parseDataScopes(["elder", "health", "unknown", 7, "knowledge", "elder"])).toEqual([
        "elder",
        "health",
        "knowledge",
        "elder",
      ]);
    });

    it.each([undefined, null, "elder", { scopes: ["elder"] }])("returns an empty list for non-array input %#", (value) => {
      expect(parseDataScopes(value)).toEqual([]);
    });
  });
});
