"""DB名カタログ。

APIDOC「Ⅱ.3.（2）DB名」に基づく静的カタログを提供する。
"""

from __future__ import annotations

from dataclasses import dataclass


@dataclass(frozen=True, slots=True)
class DBInfo:
    """DBコードの属性情報。

    Attributes:
        code: DBコード（例: "IR01"）。
        name_ja: DB名称（日本語）。
        category_ja: 統計分野（日本語）。
    """

    code: str
    name_ja: str
    category_ja: str

    def __str__(self) -> str:
        return f"{self.code}: {self.name_ja}"


def _build_catalog() -> dict[str, DBInfo]:
    """カタログ辞書を構築する。"""
    entries: list[tuple[str, str, str]] = [
        # 金利（預金・貸出関連）
        ("IR01", "基準割引率および基準貸付利率（従来「公定歩合」として掲載されていたもの）の推移", "金利（預金・貸出関連）"),
        ("IR02", "預金種類別店頭表示金利の平均年利率等", "金利（預金・貸出関連）"),
        ("IR03", "定期預金の預入期間別平均金利", "金利（預金・貸出関連）"),
        ("IR04", "貸出約定平均金利", "金利（預金・貸出関連）"),
        # マーケット関連
        ("FM01", "無担保コール〇／N物レート（毎営業日）", "マーケット関連"),
        ("FM02", "短期金融市場金利", "マーケット関連"),
        ("FM03", "短期金融市場残高", "マーケット関連"),
        ("FM04", "コール市場残高", "マーケット関連"),
        ("FM05", "公社債発行・償還および現存額", "マーケット関連"),
        ("FM06", "公社債消化状況（利付国債）", "マーケット関連"),
        ("FM07", "（参考）国債窓口販売額・窓口販売率（2004年1月まで）", "マーケット関連"),
        ("FM08", "外国為替市況", "マーケット関連"),
        ("FM09", "実効為替レート", "マーケット関連"),
        # 決済関連
        ("PS01", "各種決済", "決済関連"),
        ("PS02", "フェイルの発生状況", "決済関連"),
        # 預金・マネー・貸出
        ("MD01", "マネタリーベース", "預金・マネー・貸出"),
        ("MD02", "マネーストック", "預金・マネー・貸出"),
        ("MD03", "マネタリーサーベイ", "預金・マネー・貸出"),
        ("MD04", "（参考）マネーサプライ（M2+CD）増減と信用面の対応", "預金・マネー・貸出"),
        ("MD05", "通貨流通高", "預金・マネー・貸出"),
        ("MD06", "日銀当座預金増減要因と金融調節（実績）", "預金・マネー・貸出"),
        ("MD07", "準備預金額", "預金・マネー・貸出"),
        ("MD08", "業態別の日銀当座預金残高", "預金・マネー・貸出"),
        ("MD09", "マネタリーベースと日本銀行の取引", "預金・マネー・貸出"),
        ("MD10", "預金者別預金", "預金・マネー・貸出"),
        ("MD11", "預金・現金・貸出金", "預金・マネー・貸出"),
        ("MD12", "都道府県別預金・現金・貸出金", "預金・マネー・貸出"),
        ("MD13", "貸出・預金動向", "預金・マネー・貸出"),
        ("MD14", "定期預金の残高および新規受入高", "預金・マネー・貸出"),
        ("LA01", "貸出先別貸出金", "預金・マネー・貸出"),
        ("LA02", "日本銀行貸出", "預金・マネー・貸出"),
        ("LA03", "その他貸出残高", "預金・マネー・貸出"),
        ("LA04", "コミットメントライン契約額、利用額", "預金・マネー・貸出"),
        ("LA05", "主要銀行貸出動向アンケート調査", "預金・マネー・貸出"),
        # 金融機関バランスシート
        ("BS01", "日本銀行勘定", "金融機関バランスシート"),
        ("BS02", "民間金融機関の資産・負債", "金融機関バランスシート"),
        # 資金循環
        ("FF", "資金循環", "資金循環"),
        # その他の日本銀行関連
        ("OB01", "日本銀行の対政府取引", "その他の日本銀行関連"),
        ("OB02", "日本銀行が受入れている担保の残高", "その他の日本銀行関連"),
        # 短観
        ("CO", "短観", "短観"),
        # 物価
        ("PR01", "企業物価指数", "物価"),
        ("PR02", "企業向けサービス価格指数", "物価"),
        ("PR03", "製造業部門別投入・産出物価指数", "物価"),
        ("PR04", "＜サテライト指数＞最終需要・中間需要物価指数", "物価"),
        # 財政関連
        ("PF01", "財政資金収支", "財政関連"),
        ("PF02", "政府債務", "財政関連"),
        # 国際収支・BIS関連
        ("BIS", "BIS 国際資金取引統計および国際与信統計の日本分集計結果", "国際収支・BIS関連"),
        ("BP01", "国際収支統計", "国際収支・BIS関連"),
        ("DER", "デリバティブ取引に関する定例市場報告", "国際収支・BIS関連"),
        # その他
        ("OT", "その他", "その他"),
    ]
    return {code: DBInfo(code=code, name_ja=name, category_ja=cat) for code, name, cat in entries}


DB_CATALOG: dict[str, DBInfo] = _build_catalog()
"""全DBコードのカタログ辞書。キーは大文字DBコード。"""


def list_dbs(*, category: str | None = None) -> list[DBInfo]:
    """DB一覧を返す。

    Args:
        category: 統計分野で部分一致フィルタ。Noneの場合は全件。

    Returns:
        条件に一致するDBInfo一覧。カタログ登録順を保持。
    """
    if category is None:
        return list(DB_CATALOG.values())
    return [info for info in DB_CATALOG.values() if category in info.category_ja]


def get_db_info(db: str) -> DBInfo | None:
    """DBコードから属性情報を取得する。

    Args:
        db: DBコード。大小文字不問。

    Returns:
        対応するDBInfo。未知の場合はNone。
    """
    return DB_CATALOG.get(db.strip().upper())


def is_known_db(db: str) -> bool:
    """既知のDBコードかどうか判定する。

    Args:
        db: DBコード。大小文字不問。

    Returns:
        既知ならTrue。
    """
    return db.strip().upper() in DB_CATALOG
