import type { Permission } from "@/modules/core/types";

export const AI_KNOWLEDGE_SCOPES = ["platform", "organization"] as const;
export type AiKnowledgeScope = (typeof AI_KNOWLEDGE_SCOPES)[number];

export const AI_KNOWLEDGE_STATUSES = ["enabled", "disabled"] as const;
export type AiKnowledgeStatus = (typeof AI_KNOWLEDGE_STATUSES)[number];

export const ELDER_AI_ANALYSIS_STATUSES = ["completed", "failed"] as const;
export type ElderAiAnalysisStatus = (typeof ELDER_AI_ANALYSIS_STATUSES)[number];

export const ELDER_AI_DATA_SCOPES = [
  "elder",
  "health",
  "care",
  "family",
  "admission",
  "facility",
  "alert",
  "incident",
  "knowledge",
] as const;
export type ElderAiDataScope = (typeof ELDER_AI_DATA_SCOPES)[number];

export const ELDER_AI_RISK_LEVELS = ["low", "medium", "high", "critical", "unknown"] as const;
export type ElderAiRiskLevel = (typeof ELDER_AI_RISK_LEVELS)[number];

export const ELDER_AI_SEVERITIES = ["info", "warning", "critical"] as const;
export type ElderAiSeverity = (typeof ELDER_AI_SEVERITIES)[number];

export const ELDER_AI_RECOMMENDATION_PRIORITIES = ["low", "normal", "high", "urgent"] as const;
export type ElderAiRecommendationPriority = (typeof ELDER_AI_RECOMMENDATION_PRIORITIES)[number];

export const AI_ERROR_CATEGORIES = [
  "missing_config",
  "provider_error",
  "timeout",
  "schema_validation_failed",
  "retrieval_failed",
  "unknown",
] as const;
export type AiErrorCategory = (typeof AI_ERROR_CATEGORIES)[number];

export type AiCitation = {
  id: string;
  sourceType: "resident_context" | "knowledge";
  sourceId: string;
  title: string;
  excerpt: string;
};

export type ElderAiFinding = {
  category: string;
  severity: ElderAiSeverity;
  evidence: string;
  citationIds: string[];
};

export type ElderAiRecommendation = {
  title: string;
  priority: ElderAiRecommendationPriority;
  rationale: string;
  suggestedNextStep: string;
  citationIds: string[];
};

export type ElderAiModelSummary = {
  provider: "openai-compatible";
  chatModel: string;
  embeddingModel: string;
};

export type ElderAiAnalysisOutput = {
  overallRiskLevel: ElderAiRiskLevel;
  summary: string;
  keyFindings: ElderAiFinding[];
  recommendations: ElderAiRecommendation[];
  dataGaps: string[];
  citations: AiCitation[];
  confidence: number;
  modelSummary: ElderAiModelSummary;
};

export type ElderAiAnalysisHistoryItem = {
  id: string;
  elderId: string;
  status: ElderAiAnalysisStatus;
  dataScopes: ElderAiDataScope[];
  createdAt: string;
  restricted: boolean;
  result?: ElderAiAnalysisOutput;
  errorCategory?: AiErrorCategory;
  errorReason?: string;
};

export type KnowledgeEntryInput = {
  scope: AiKnowledgeScope;
  organizationId?: string;
  title: string;
  category: string;
  tags: string;
  body: string;
  status: AiKnowledgeStatus;
};

export type KnowledgeEntry = KnowledgeEntryInput & {
  id: string;
  createdAt: string;
  updatedAt: string;
};

export type KnowledgeRetrievalResult = {
  entryId: string;
  chunkId: string;
  title: string;
  category: string;
  content: string;
  score: number;
};

const DATA_SCOPE_PERMISSION_MAP: Record<Exclude<ElderAiDataScope, "elder" | "knowledge">, Permission> = {
  health: "health:read",
  care: "care:read",
  family: "family:read",
  admission: "admission:read",
  facility: "facility:read",
  alert: "alert:read",
  incident: "incident:read",
};

export function isElderAiDataScope(value: string): value is ElderAiDataScope {
  return (ELDER_AI_DATA_SCOPES as readonly string[]).includes(value);
}

export function getPermissionForDataScope(scope: ElderAiDataScope): Permission {
  if (scope === "elder") {
    return "elder:read";
  }
  if (scope === "knowledge") {
    return "knowledge:read";
  }
  return DATA_SCOPE_PERMISSION_MAP[scope];
}

export function canViewAnalysisScopes(scopes: readonly ElderAiDataScope[], permissions: readonly Permission[]): boolean {
  return scopes.every((scope) => permissions.includes(getPermissionForDataScope(scope)));
}

export function parseDataScopes(value: unknown): ElderAiDataScope[] {
  if (!Array.isArray(value)) {
    return [];
  }
  return value.filter((item): item is ElderAiDataScope => typeof item === "string" && isElderAiDataScope(item));
}

function isRecord(value: unknown): value is Record<string, unknown> {
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
}

function readStringArray(value: unknown): string[] | null {
  if (!Array.isArray(value)) {
    return null;
  }
  const items = value.filter((item): item is string => typeof item === "string");
  return items.length === value.length ? items : null;
}

function validateCitation(value: unknown): AiCitation | null {
  if (!isRecord(value)) {
    return null;
  }
  const sourceType = value.sourceType;
  if (sourceType !== "resident_context" && sourceType !== "knowledge") {
    return null;
  }
  if (
    typeof value.id !== "string" ||
    typeof value.sourceId !== "string" ||
    typeof value.title !== "string" ||
    typeof value.excerpt !== "string"
  ) {
    return null;
  }
  return {
    id: value.id,
    sourceType,
    sourceId: value.sourceId,
    title: value.title,
    excerpt: value.excerpt,
  };
}

function validateFinding(value: unknown): ElderAiFinding | null {
  if (!isRecord(value)) {
    return null;
  }
  const citationIds = readStringArray(value.citationIds);
  if (
    typeof value.category !== "string" ||
    typeof value.evidence !== "string" ||
    !ELDER_AI_SEVERITIES.includes(value.severity as ElderAiSeverity) ||
    !citationIds
  ) {
    return null;
  }
  return {
    category: value.category,
    severity: value.severity as ElderAiSeverity,
    evidence: value.evidence,
    citationIds,
  };
}

function validateRecommendation(value: unknown): ElderAiRecommendation | null {
  if (!isRecord(value)) {
    return null;
  }
  const citationIds = readStringArray(value.citationIds);
  if (
    typeof value.title !== "string" ||
    typeof value.rationale !== "string" ||
    typeof value.suggestedNextStep !== "string" ||
    !ELDER_AI_RECOMMENDATION_PRIORITIES.includes(value.priority as ElderAiRecommendationPriority) ||
    !citationIds
  ) {
    return null;
  }
  return {
    title: value.title,
    priority: value.priority as ElderAiRecommendationPriority,
    rationale: value.rationale,
    suggestedNextStep: value.suggestedNextStep,
    citationIds,
  };
}

function validateModelSummary(value: unknown): ElderAiModelSummary | null {
  if (!isRecord(value)) {
    return null;
  }
  if (
    value.provider !== "openai-compatible" ||
    typeof value.chatModel !== "string" ||
    typeof value.embeddingModel !== "string"
  ) {
    return null;
  }
  return {
    provider: "openai-compatible",
    chatModel: value.chatModel,
    embeddingModel: value.embeddingModel,
  };
}

export function validateElderAiAnalysisOutput(value: unknown): ElderAiAnalysisOutput | null {
  if (!isRecord(value)) {
    return null;
  }
  const confidenceValue = typeof value.confidence === "string" ? Number(value.confidence) : value.confidence;
  const keyFindings = Array.isArray(value.keyFindings) ? value.keyFindings.map(validateFinding) : null;
  const recommendations = Array.isArray(value.recommendations) ? value.recommendations.map(validateRecommendation) : null;
  const citations = Array.isArray(value.citations) ? value.citations.map(validateCitation) : null;
  const dataGaps = readStringArray(value.dataGaps);
  const modelSummary = validateModelSummary(value.modelSummary);

  if (
    !ELDER_AI_RISK_LEVELS.includes(value.overallRiskLevel as ElderAiRiskLevel) ||
    typeof value.summary !== "string" ||
    typeof confidenceValue !== "number" ||
    !Number.isFinite(confidenceValue) ||
    !keyFindings ||
    keyFindings.includes(null) ||
    !recommendations ||
    recommendations.includes(null) ||
    !dataGaps ||
    !citations ||
    citations.includes(null) ||
    !modelSummary
  ) {
    return null;
  }

  return {
    overallRiskLevel: value.overallRiskLevel as ElderAiRiskLevel,
    summary: value.summary,
    keyFindings: keyFindings.filter((item): item is ElderAiFinding => Boolean(item)),
    recommendations: recommendations.filter((item): item is ElderAiRecommendation => Boolean(item)),
    dataGaps,
    citations: citations.filter((item): item is AiCitation => Boolean(item)),
    confidence: Math.max(0, Math.min(1, confidenceValue)),
    modelSummary,
  };
}

export function validateKnowledgeEntryInput(value: unknown): { success: true; input: KnowledgeEntryInput } | { success: false; reason: string } {
  if (!value || typeof value !== "object") {
    return { success: false, reason: "请求数据格式无效" };
  }
  const record = value as Record<string, unknown>;
  const scope = typeof record.scope === "string" ? record.scope : "";
  const title = typeof record.title === "string" ? record.title.trim() : "";
  const category = typeof record.category === "string" ? record.category.trim() : "";
  const tags = typeof record.tags === "string" ? record.tags.trim() : "";
  const body = typeof record.body === "string" ? record.body.trim() : "";
  const status = typeof record.status === "string" ? record.status : "enabled";
  const organizationId = typeof record.organizationId === "string" && record.organizationId.trim() ? record.organizationId.trim() : undefined;

  if (!AI_KNOWLEDGE_SCOPES.includes(scope as AiKnowledgeScope)) {
    return { success: false, reason: "知识库范围无效" };
  }
  if (!AI_KNOWLEDGE_STATUSES.includes(status as AiKnowledgeStatus)) {
    return { success: false, reason: "知识库状态无效" };
  }
  if (!title) {
    return { success: false, reason: "知识标题不能为空" };
  }
  if (!body) {
    return { success: false, reason: "知识内容不能为空" };
  }
  return {
    success: true,
    input: {
      scope: scope as AiKnowledgeScope,
      organizationId,
      title,
      category,
      tags,
      body,
      status: status as AiKnowledgeStatus,
    },
  };
}
