export const GENDER_VALUES = ["male", "female", "other"] as const;
export type Gender = (typeof GENDER_VALUES)[number];

export const CARE_LEVEL_VALUES = ["self-care", "semi-assisted", "assisted", "intensive"] as const;
export type CareLevel = (typeof CARE_LEVEL_VALUES)[number];

export const ELDER_STATUS_VALUES = ["active", "pending", "discharged"] as const;
export type ElderStatus = (typeof ELDER_STATUS_VALUES)[number];

export const GENDER_LABELS: Record<Gender, string> = {
  male: "男",
  female: "女",
  other: "其他",
};

export const CARE_LEVEL_LABELS: Record<CareLevel, string> = {
  "self-care": "自理",
  "semi-assisted": "半失能",
  assisted: "失能",
  intensive: "重点照护",
};

export const ELDER_STATUS_LABELS: Record<ElderStatus, string> = {
  active: "在院",
  pending: "待入住",
  discharged: "已退住",
};

export type Elder = {
  id: string;
  organizationId?: string;
  name: string;
  gender: Gender;
  age: number;
  careLevel: CareLevel;
  room: string;
  bed: string;
  bedId?: string;
  status: ElderStatus;
  primaryContact: string;
  phone: string;
  medicalNotes: string;
  createdAt: string;
  updatedAt: string;
};

export type ElderInput = Omit<Elder, "id" | "createdAt" | "updatedAt">;

type ValidationSuccess<T> = {
  success: true;
  data: T;
};

type ValidationFailure = {
  success: false;
  reason: string;
};

export type ValidationResult<T> = ValidationSuccess<T> | ValidationFailure;

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

function readRequiredString(
  source: Record<string, unknown>,
  key: keyof ElderInput,
  label: string,
): ValidationResult<string> {
  const value = source[key];
  if (typeof value !== "string" || value.trim().length === 0) {
    return { success: false, reason: `${label}不能为空` };
  }

  return { success: true, data: value.trim() };
}

function readOptionalString(source: Record<string, unknown>, key: string): string | undefined {
  const value = source[key];
  if (typeof value !== "string") {
    return undefined;
  }

  const trimmed = value.trim();
  return trimmed.length > 0 ? trimmed : undefined;
}

function readEnum<T extends string>(
  source: Record<string, unknown>,
  key: keyof ElderInput,
  values: readonly T[],
  label: string,
): ValidationResult<T> {
  const value = source[key];
  if (typeof value !== "string") {
    return { success: false, reason: `${label}无效` };
  }

  const matched = values.find((item) => item === value);
  if (!matched) {
    return { success: false, reason: `${label}无效` };
  }

  return { success: true, data: matched };
}

function readAge(source: Record<string, unknown>): ValidationResult<number> {
  const value = source.age;
  const numeric = typeof value === "number" ? value : Number(value);

  if (!Number.isInteger(numeric) || numeric < 0 || numeric > 130) {
    return { success: false, reason: "年龄需为0到130之间的整数" };
  }

  return { success: true, data: numeric };
}

export function validateElderInput(value: unknown): ValidationResult<ElderInput> {
  if (!isRecord(value)) {
    return { success: false, reason: "请求数据格式无效" };
  }

  const name = readRequiredString(value, "name", "姓名");
  if (!name.success) {
    return name;
  }

  const gender = readEnum(value, "gender", GENDER_VALUES, "性别");
  if (!gender.success) {
    return gender;
  }

  const age = readAge(value);
  if (!age.success) {
    return age;
  }

  const careLevel = readEnum(value, "careLevel", CARE_LEVEL_VALUES, "护理等级");
  if (!careLevel.success) {
    return careLevel;
  }

  const room = readOptionalString(value, "room") ?? "";
  const bed = readOptionalString(value, "bed") ?? "";
  const bedId = readOptionalString(value, "bedId");

  const status = readEnum(value, "status", ELDER_STATUS_VALUES, "状态");
  if (!status.success) {
    return status;
  }

  const primaryContact = readRequiredString(value, "primaryContact", "联系人");
  if (!primaryContact.success) {
    return primaryContact;
  }

  const phone = readRequiredString(value, "phone", "联系电话");
  if (!phone.success) {
    return phone;
  }

  const medicalNotesValue = value.medicalNotes;
  const medicalNotes = typeof medicalNotesValue === "string" ? medicalNotesValue.trim() : "";

  return {
    success: true,
    data: {
      name: name.data,
      gender: gender.data,
      age: age.data,
      careLevel: careLevel.data,
      room,
      bed,
      bedId,
      status: status.data,
      primaryContact: primaryContact.data,
      phone: phone.data,
      medicalNotes,
    },
  };
}
