"""importer に共通の型（取り込みの文脈・結果）."""

import sqlite3
from dataclasses import dataclass
from pathlib import Path
from typing import Protocol

from tiasdata.config import SourceConfig
from tiasdata.importers.holds import Holds


@dataclass(frozen=True)
class ImportContext:
    """importer に渡す取り込みの文脈．

    Attributes:
        source_name: 取り込み元の名前（設定ファイルの `sources.<名前>`）．
        source: 取り込み元の設定．
        store_dir: ストアのフォルダ．
        holds: 保留の番号．
        show_source_names: エラーメッセージに取り込み元の番号・名前を出すか
            （原因の特定に必要なときだけ明示する．error-handling.md）．
    """

    source_name: str
    source: SourceConfig
    store_dir: Path
    holds: Holds
    show_source_names: bool = False


@dataclass(frozen=True)
class ImportResult:
    """取り込みの結果（件数だけ．CLI がそのまま表示する）．

    Attributes:
        source_name: 取り込み元の名前．
        importer: importer の名前．
        found: 取り込み元で見つけた画像の数（保留を含む）．
        held: 保留リストにより飛ばした数．
        hold_filename: 保留リストのファイル名（`holds/<名前>.toml`）．
        unused_map_rows: 対応表で番号が整数でないため使わなかった行の行番号（xlsx の 1 始まり．
            位置であり対応表の中身ではない．表示は件数だけで，行番号は
            `--show-source-names` を指定したときだけ出す）．
        skipped_existing: 既に登録済みで飛ばした数．
        copied_to_store: ストアにコピーした数（同じ中身が既にあったものは含まない）．
        subjects_added: 登録した症例の数．
        captures_added: 登録した撮影の数．
        assets_added: 登録したファイルの数．
        annotations_added: 登録した所見の数．
        derivations_added: 登録した由来の数．
    """

    source_name: str
    importer: str
    found: int
    held: int
    hold_filename: str
    unused_map_rows: tuple[int, ...]
    skipped_existing: int
    copied_to_store: int
    subjects_added: int
    captures_added: int
    assets_added: int
    annotations_added: int
    derivations_added: int


class Importer(Protocol):
    """importer の関数の形（対応表を ATTACH した目録の接続と文脈を受け取る）．"""

    def __call__(self, conn: sqlite3.Connection, context: ImportContext) -> ImportResult: ...
