from __future__ import annotations

import json
import re
import sys
from pathlib import Path


ROOT_DIR = Path(__file__).resolve().parents[1]
OVERRIDE_PATH = ROOT_DIR / "scripts" / "data" / "plant_name_overrides.json"

JAPANESE_CHAR_REGEX = re.compile(r"[\u3040-\u30FF\u3400-\u9FFF]")
SPACE_BETWEEN_JA_REGEX = re.compile(r"(?<=[\u3040-\u30FF\u3400-\u9FFF])\s+(?=[\u3040-\u30FF\u3400-\u9FFF])")

MANUAL_JA_FIXES: dict[str, str] = {
    "Actaea pachypoda": "ドールズアイ",
    "Anacamptis morio": "アナカンプティス・モリオ",
    "Brassica rapa": "カブ",
    "Amelanchier arborea": "ジューンベリー",
    "Callicarpa americana": "アメリカムラサキシキブ",
    "Carpinus caroliniana": "アメリカンホーンビーム",
    "Carya cordiformis": "ビターナットヒッコリー",
    "Carya ovata": "シャグバークヒッコリー",
    "Cakile maritima": "カキレ・マリティマ",
    "Cephalanthus occidentalis": "ボタンブッシュ",
    "Cirsium palustre": "キルシウム・パルストレ",
    "Chasmanthium latifolium": "リバーオーツ",
    "Clematis virginiana": "クレマティス・ヴィルギニアーナ",
    "Clematis vitalba": "クレマチス・ビタルバ",
    "Claytonia perfoliata": "マイナーズレタス",
    "Comptonia peregrina": "スイートファーン",
    "Dorstenia foetida": "ドルステニア・フォエチダ",
    "Eriogonum fasciculatum": "カリフォルニアバックウィート",
    "Eryngium yuccifolium": "ラトルスネークマスター",
    "Eupatorium cannabinum": "エウパトーリウム・カンナビーヌム",
    "Euonymus americanus": "ストロベリーブッシュ",
    "Frangula californica": "コーヒーベリー",
    "Fraxinus americana": "アメリカトネリコ",
    "Fritillaria affinis": "チェッカーリリー",
    "Fouquieria splendens": "フォークイエリア・スプレンデンス",
    "Geum triflorum": "プレーリースモーク",
    "Haworthia cooperi": "ハオルチア・クーペリー",
    "Heteromeles arbutifolia": "トヨン",
    "Hoya kerrii": "ホヤ・カーリー",
    "Hoya obovata": "ホヤオボバータ",
    "Hyacinthoides non-scripta": "イングリッシュブルーベル",
    "Anemone virginiana": "アネモネ・バージニアナ",
    "Conopholis americana": "コノフォリス・アメリカーナ",
    "Medeola virginiana": "メデオラ・バージニアナ",
    "Mitchella repens": "ミッチェラ・レペンス",
    "Prunus virginiana": "チョークチェリー",
    "Lysichiton americanus": "キバナミズバショウ",
    "Rhamnus cathartica": "セイヨウクロウメモドキ",
    "Cornus sanguinea": "セイヨウミズキ",
    "Celtis laevigata": "シュガーハックベリー",
    "Lonicera hispidula": "ピンクハニーサックル",
    "Lobelia siphilitica": "オオロベリアソウ",
    "Sambucus cerulea": "ブルーエルダー",
    "Vaccinium ovatum": "エバーグリーンハックルベリー",
    "Quercus montana": "チェスナットオーク",
    "Rhus typhina": "アメリカハゼノキ",
    "Solidago caesia": "ブルーステムアキノキリンソウ",
    "Solidago flexicaulis": "広葉アキノキリンソウ",
    "Solidago rugosa": "シワ葉アキノキリンソウ",
    "Potentilla reptans": "ポテンティラ・レプタンス",
    "Geum urbanum": "ゲウム・ウルバヌム",
    "jack-in-the-pulpit": "アリサエマ・トリフィラム",
    "Lupinus bicolor": "ルピナス・ビコロル",
    "Ophrys apifera": "オフリス・アピフェラ",
    "Parkinsonia aculeata": "パーキンソニア・アクレアタ",
    "Plantago media": "ホーリーオオバコ",
    "Quercus garryana": "オレゴンホワイトオーク",
    "New Guinea Impatiens": "ニューギニア・インパチェンス",
    "Salvia lyrata": "サルビア・リラータ",
    "Salvia pratensis": "メドーセージ",
    "Scilla siberica": "シラー・シベリカ",
    "Scindapsus treubii": "スキンダプサス・トレビー",
    "Vaccinium parvifolium": "レッド・ハックルベリー",
}

STRING_NORMALIZATION_FIXES: dict[str, str] = {
    "マイアンテマムム": "マイアンテムム",
}


def normalize_japanese_name(value: str) -> str:
    value = " ".join((value or "").strip().split())
    if not value:
        return ""
    value = SPACE_BETWEEN_JA_REGEX.sub("・", value)
    value = value.replace(" · ", "・").replace("·", "・")
    value = value.replace(" ・ ", "・").replace(" ・", "・").replace("・ ", "・")
    for bad, good in STRING_NORMALIZATION_FIXES.items():
        value = value.replace(bad, good)
    return value


def main() -> None:
    try:
        sys.stdout.reconfigure(encoding="utf-8")
    except Exception:
        pass

    payload = json.loads(OVERRIDE_PATH.read_text(encoding="utf-8"))
    updated = 0
    sample: list[dict[str, str]] = []

    for scientific_name, entry in payload.items():
        has_manual_fix = scientific_name in MANUAL_JA_FIXES
        if entry.get("ja_source") not in {"translate_fallback", "manual_localization"} and not has_manual_fix:
            continue

        next_value = MANUAL_JA_FIXES.get(scientific_name, entry.get("ja", ""))
        next_value = normalize_japanese_name(next_value)
        if not next_value or not JAPANESE_CHAR_REGEX.search(next_value):
            continue

        if entry.get("ja") != next_value or entry.get("ja_source") != "manual_localization":
            entry["ja"] = next_value
            entry["ja_source"] = "manual_localization"
            updated += 1

        if len(sample) < 80:
            sample.append(
                {
                    "scientific_name": scientific_name,
                    "ja": entry["ja"],
                }
            )

    ordered = {name: payload[name] for name in sorted(payload)}
    OVERRIDE_PATH.write_text(json.dumps(ordered, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")

    print(
        json.dumps(
            {
                "updated": updated,
                "sample": sample,
            },
            ensure_ascii=False,
            indent=2,
        )
    )


if __name__ == "__main__":
    main()
