"""Configurable tag-column registry shared by the UI and table model."""

from __future__ import annotations

from typing import Any


TAG_KEYS = (
    "album",
    "albumartist",
    "albumartistsort",
    "albumsort",
    "artist",
    "artistsort",
    "bpm",
    "comment",
    "compilation",
    "composer",
    "composersort",
    "conductor",
    "contentgroup",
    "copyright",
    "date",
    "discnumber",
    "disctotal",
    "encodedby",
    "encodersettings",
    "encoderingtime",
    "fileowner",
    "filetype",
    "genre",
    "initialkey",
    "involevedpeople",
    "isrc",
    "ituesmediatype",
    "language",
    "length",
    "lyricist",
    "mediatype",
    "mixarist",
    "mood",
    "movement",
    "movementname",
    "movementtotal",
    "netradioowner",
    "netradiostation",
    "origalbum",
    "origartist",
    "origfilename",
    "origlyricist",
    "origyear",
    "podcast",
    "podcastcategory",
    "podcastdesc",
    "podcastpodcastid",
    "podcastkeywords",
    "podcasturl",
    "publisher",
    "rating mm",
    "rating winamp",
    "rating wmp",
    "releasetime",
    "setsubtitle",
    "showmovement",
    "subtitle",
    "taggingtime",
    "title",
    "titlesort",
    "track",
    "tracktotal",
    "tvepisode",
    "tvepisodeid",
    "tvnetwork",
    "tvseason",
    "unsycedlyrics",
    "work",
    "www",
    "wwwartis",
    "wwwaudiofile",
    "wwwaudiosource",
    "wwwcomercialinfo",
    "wwwcopyright",
    "wwwpayment",
    "wwwpublisher",
    "wwwradiopage",
    "year",
)

DEFAULT_TAG_KEYS = (
    "title",
    "artist",
    "album",
    "genre",
    "discnumber",
    "disctotal",
    "track",
    "tracktotal",
)

DEFAULT_BULK_TAG_KEYS = (
    "artist",
    "album",
    "genre",
)

ENGLISH_TAG_NAMES = {
    "title": "Title",
    "artist": "Artist",
    "album": "Album",
    "genre": "Genre",
    "discnumber": "Disc",
    "disctotal": "Disc Total",
    "track": "Track",
    "tracktotal": "Track Total",
    "rating mm": "Rating MM",
    "rating winamp": "Rating Winamp",
    "rating wmp": "Rating WMP",
}

JAPANESE_TAG_NAMES = {
    "album": "アルバム",
    "albumartist": "アルバムアーティスト",
    "albumartistsort": "アルバムアーティスト並べ替え",
    "albumsort": "アルバム並べ替え",
    "artist": "アーティスト",
    "artistsort": "アーティスト並べ替え",
    "bpm": "BPM",
    "comment": "コメント",
    "compilation": "コンピレーション",
    "composer": "作曲者",
    "composersort": "作曲者並べ替え",
    "conductor": "指揮者",
    "contentgroup": "グループ",
    "copyright": "著作権",
    "date": "日付",
    "discnumber": "Disc",
    "disctotal": "Disc合計",
    "encodedby": "エンコード者",
    "encodersettings": "エンコーダー設定",
    "encoderingtime": "エンコード日時",
    "fileowner": "ファイル所有者",
    "filetype": "ファイル形式",
    "genre": "ジャンル",
    "initialkey": "調",
    "involevedpeople": "関係者",
    "isrc": "ISRC",
    "ituesmediatype": "iTunesメディア形式",
    "language": "言語",
    "length": "長さタグ",
    "lyricist": "作詞者",
    "mediatype": "メディア形式",
    "mixarist": "ミックス担当",
    "mood": "ムード",
    "movement": "楽章番号",
    "movementname": "楽章名",
    "movementtotal": "楽章合計",
    "origalbum": "オリジナルアルバム",
    "origartist": "オリジナルアーティスト",
    "origfilename": "元ファイル名",
    "origlyricist": "オリジナル作詞者",
    "origyear": "オリジナル年",
    "publisher": "発行者",
    "rating mm": "評価 MM",
    "rating winamp": "評価 Winamp",
    "rating wmp": "評価 WMP",
    "releasetime": "リリース日時",
    "setsubtitle": "セット副題",
    "showmovement": "楽章表示",
    "subtitle": "副題",
    "taggingtime": "タグ更新日時",
    "title": "タイトル",
    "titlesort": "タイトル並べ替え",
    "track": "Track",
    "tracktotal": "Track合計",
    "tvepisode": "TVエピソード",
    "tvepisodeid": "TVエピソードID",
    "tvnetwork": "TVネットワーク",
    "tvseason": "TVシーズン",
    "unsycedlyrics": "非同期歌詞",
    "work": "作品",
    "year": "年",
}


def english_tag_name(key: str) -> str:
    return ENGLISH_TAG_NAMES.get(key, key)


def default_japanese_tag_name(key: str) -> str:
    return JAPANESE_TAG_NAMES.get(key, english_tag_name(key))


def default_tag_columns() -> list[dict[str, str]]:
    return [
        {"key": key, "ja": default_japanese_tag_name(key)}
        for key in DEFAULT_TAG_KEYS
    ]


def normalize_tag_columns(value: Any) -> list[dict[str, str]]:
    if value is None:
        return default_tag_columns()
    if not isinstance(value, list):
        return default_tag_columns()
    allowed = set(TAG_KEYS)
    normalized: list[dict[str, str]] = []
    seen: set[str] = set()
    for entry in value:
        if isinstance(entry, str):
            key = entry.strip().casefold()
            japanese = default_japanese_tag_name(key)
        elif isinstance(entry, dict):
            key = str(entry.get("key", "")).strip().casefold()
            japanese = str(entry.get("ja", "")).strip()
        else:
            continue
        if key not in allowed or key in seen:
            continue
        normalized.append(
            {
                "key": key,
                "ja": japanese or default_japanese_tag_name(key),
            }
        )
        seen.add(key)
    return normalized


def normalize_bulk_tag_keys(
    value: Any,
    columns: list[dict[str, str]],
) -> list[str]:
    """Keep unique bulk-edit keys that are also visible table tags."""

    displayed = [entry["key"] for entry in normalize_tag_columns(columns)]
    displayed_set = set(displayed)
    if value is None:
        requested = list(DEFAULT_BULK_TAG_KEYS)
    elif isinstance(value, (list, tuple, set)):
        requested = [str(key).strip().casefold() for key in value]
    else:
        requested = []
    requested_set = {
        key for key in requested if key in TAG_KEYS and key in displayed_set
    }
    # The bulk window follows the visible column order, regardless of the
    # order in which its checkboxes were selected in Settings.
    return [key for key in displayed if key in requested_set]
