/**
 * シルギア 漢字API v1 の型定義
 * https://api.shirugear.com/kanji/
 *
 * 互換の方針: v1 の中では項目を「足す」ことはあっても、名前や意味は変えません。
 * 知らない項目が増えていても無視してください。
 *
 * 出典: 常用漢字表（平成22年内閣告示第2号）・学年別漢字配当表（平成29年文部科学省告示第63号。令和2年度から）・
 *       音訓の小・中・高等学校段階別割り振り表（文部科学省・平成29年3月）・
 *       戸籍法施行規則 別表第三（人名用漢字。令和8年法務省令第43号による改正まで）。
 * 画数は入れていません（画数を定めた公的な表が無く、数え方が辞書によって違うため）。
 */

/** 音か訓か。音は片仮名、訓は平仮名で書かれています */
export type ReadingType = "on" | "kun";

/** 学校段階。音訓の段階別割り振り表で、その音訓を習う目安の段階 */
export type Stage = "小" | "中" | "高";

/** その字を習う学校。小学校＝学年別漢字配当表の字、中学校＝それ以外の常用漢字。人名用漢字は null */
export type School = "小学校" | "中学校";

/** 常用漢字表の音訓（1つ分） */
export interface Reading {
  /** 音訓。音は片仮名（"カン"）、訓は平仮名（"ゆだねる"） */
  reading: string;
  type: ReadingType;
  /** 常用漢字表で1字下げになっている音訓（「特別なものか、又は用法のごく狭いもの」）なら true */
  special: boolean;
  /** 習う学校段階の目安（音訓の段階別割り振り表） */
  stage: Stage;
  /**
   * 訓の送り仮名（訓だけにある項目）。"ゆだねる" なら "ねる"、"あらし" のように送り仮名が無ければ ""。
   * 常用漢字表の例欄から求めた値で、例から決められないものは null
   */
  okurigana?: string | null;
  /** 常用漢字表の例欄の語（"漢字"・"委ねる" など）。無ければ []。〔副〕〔接〕などの記号もそのまま */
  examples: string[];
}

/** 常用漢字としての情報 */
export interface JoyoInfo {
  /** 常用漢字表の並び順（1〜2136。字音の五十音順） */
  order: number;
  /** 表の丸括弧の字（いわゆる康熙字典体）。無ければ []。「弁」だけ3字（辨・瓣・辯）。互換漢字（U+F900〜）のことがある */
  kyujitai: string[];
  /**
   * 許容字体があれば、違う部分（"辶" または "飠"）。遡・遜・謎・餌・餅の5字だけ。無ければ null。
   * 許容字体は Unicode では通用字体と同じ文字コードです（字形の違い）
   */
  allowed_form: "辶" | "飠" | null;
  /** 音の一覧（readings の type が "on" のもの・表の順） */
  on: string[];
  /** 訓の一覧（readings の type が "kun" のもの・表の順） */
  kun: string[];
  readings: Reading[];
  /** この字を括弧内に掲げる人名用漢字 表(二) の字（常用漢字の異体字で、名前に使えるもの。例: 亜 → ["亞"]）。無ければ [] */
  jinmei_variants: string[];
}

/** 人名用漢字としての情報 */
export interface JinmeiInfo {
  /** 1 = 表(一)（常用漢字ではない字）、2 = 表(二)（常用漢字の異体字） */
  table: 1 | 2;
  /** 表(一) で「―」で結ばれた同じ字種の字（例: 亘 ↔ 亙）。無ければ null。表(二) では null */
  same_as: string | null;
  /** 表(二) の括弧内の常用漢字（例: 亞 → "亜"）。表(一) では null */
  joyo_form: string | null;
}

/** GET /kanji/v1/{漢字1字}.json */
export interface KanjiResponse {
  /** 字（1文字。CJK拡張B の 𠮟 のようにサロゲートペアになる字もある） */
  kanji: string;
  /** Unicode のコードポイント（"U+6F22"） */
  codepoint: string;
  /** 常用漢字なら情報、そうでなければ null */
  joyo: JoyoInfo | null;
  /** 学年別漢字配当表の学年（1〜6）。配当外は null */
  grade: number | null;
  /** 小学校＝学年別漢字配当表の字、中学校＝それ以外の常用漢字。人名用漢字は null */
  school: School | null;
  /** 子の名前に使える字か。このAPIが返す字（常用漢字・人名用漢字）はすべて true */
  name_ok: boolean;
  /** 人名用漢字なら情報、そうでなければ null（常用漢字は人名用漢字の表には入っていない） */
  jinmei: JinmeiInfo | null;
  data_version: string;
}

/** 一覧の1件（学年ごとの一覧） */
export interface GradeKanji {
  kanji: string;
  codepoint: string;
  on: string[];
  kun: string[];
}

/** GET /kanji/v1/grade/{1-6}.json */
export interface GradeResponse {
  grade: number;
  count: number;
  /** 常用漢字表の順 */
  kanji: GradeKanji[];
  data_version: string;
}

/** GET /kanji/v1/joyo.json の1件 */
export interface JoyoListItem {
  kanji: string;
  codepoint: string;
  grade: number | null;
  school: School;
  kyujitai: string[];
  on: string[];
  kun: string[];
}

/** GET /kanji/v1/joyo.json */
export interface JoyoListResponse {
  count: number;
  /** 常用漢字表の順（2136件） */
  kanji: JoyoListItem[];
  data_version: string;
}

/** GET /kanji/v1/jinmei.json の1件 */
export interface JinmeiListItem {
  kanji: string;
  codepoint: string;
  table: 1 | 2;
  same_as: string | null;
  joyo_form: string | null;
}

/** GET /kanji/v1/jinmei.json */
export interface JinmeiListResponse {
  count: number;
  /** 戸籍法施行規則 別表第三の順（表(一) 652件のあとに表(二) 212件） */
  kanji: JinmeiListItem[];
  data_version: string;
}

/** 出典1つ分 */
export interface Source {
  title: string;
  law: string;
  url: string;
  note?: string;
}

/** GET /kanji/v1/meta.json */
export interface KanjiMetaResponse {
  data_version: string;
  sources: {
    joyo: Source;
    grade: Source;
    stage: Source;
    jinmei: Source;
  };
  counts: {
    joyo: number;
    joyo_on: number;
    joyo_kun: number;
    grade: Record<"1" | "2" | "3" | "4" | "5" | "6", number>;
    grade_total: number;
    junior_high: number;
    jinmei: number;
    jinmei_table1: number;
    jinmei_table2: number;
    kanji_files: number;
  };
}

/** エラー（400 / 404 / 405） */
export interface ErrorResponse {
  error: {
    status: number;
    /** "invalid_kanji" | "kanji_not_found" | "not_found" | "method_not_allowed" */
    code: string;
    message: string;
  };
}
