# -*- coding: utf-8 -*-
"""推論CLI（利用システム）。

入力（濃度数値 ＋ 動画由来のLLM画像評価 ＋ 時間帯）から推論し、結果を出力する。

  ※ 「動画」は上流前処理（最良フレーム抽出 → LLM画像評価）で
     visual_density / water_level / oil_emulsification / boiling_heat_state /
     photo_quality / image_condition_score に変換された状態で渡す。
     （上流の実体は local_batch_api/。本システムは後段の採点を担う。）

使い方:
    python infer.py --demo                         # サンプル2件（scored / 要確認）
    python infer.py --record rec.json              # 単件JSON
    python infer.py --input batch.csv --output out.csv   # バッチ（training_dataset互換CSV）
    python infer.py --brix 12 --slot 開店前 --density 12 --water 水位良好 \
                    --oil 乳化が進んでいる --boiling 良い --photo 良い --image-score 8
"""
from __future__ import annotations
import argparse
import json
from pathlib import Path

import pandas as pd
import scoring_engine as E

HERE = Path(__file__).resolve().parent
MODEL_DIR = HERE / "models"

DEMO_SCOREABLE = {
    "video_path": "demo_ok.MOV", "brix_raw": 12.0, "slot": "開店前", "store": "demo",
    "visual_density": "12", "water_level": "水位良好",
    "oil_emulsification": "乳化が進んでいる", "boiling_heat_state": "良い",
    "photo_quality": "良い", "image_condition_score": 8,
}
DEMO_UNASSESSABLE = {
    "video_path": "demo_ng.MOV", "brix_raw": None, "slot": "昼", "store": "demo",
    "visual_density": "判定不可", "water_level": "判定不可",
    "oil_emulsification": "判定不可", "boiling_heat_state": "判定不可",
    "photo_quality": "湯気が多い", "image_condition_score": 2,
}


def main() -> None:
    ap = argparse.ArgumentParser()
    ap.add_argument("--input", help="バッチ入力CSV（training_dataset互換）")
    ap.add_argument("--output", help="バッチ結果CSV")
    ap.add_argument("--record", help="単件JSONファイル")
    ap.add_argument("--demo", action="store_true")
    ap.add_argument("--model-dir", default=str(MODEL_DIR))
    # 直接指定（単件）
    ap.add_argument("--brix", type=float)
    ap.add_argument("--slot")
    ap.add_argument("--density")
    ap.add_argument("--water")
    ap.add_argument("--oil")
    ap.add_argument("--boiling")
    ap.add_argument("--photo")
    ap.add_argument("--image-score", type=float, dest="image_score")
    args = ap.parse_args()

    models = E.load_models(args.model_dir)

    if args.demo:
        for rec in (DEMO_SCOREABLE, DEMO_UNASSESSABLE):
            print(json.dumps(E.score_record(rec, models), ensure_ascii=False, indent=2))
        return

    if args.record:
        rec = json.loads(Path(args.record).read_text(encoding="utf-8"))
        print(json.dumps(E.score_record(rec, models), ensure_ascii=False, indent=2))
        return

    if args.input:
        out_csv = args.output or str(HERE / "predictions_out.csv")
        res = E.score_batch(pd.read_csv(args.input), models)
        res.to_csv(out_csv, index=False, encoding="utf-8-sig")
        n = len(res); scored = int((res["status"] == "scored").sum())
        print(f"バッチ推論完了: {n}件中 scored={scored} / 要確認={n - scored}")
        print("出力:", out_csv)
        return

    # 直接指定（単件）
    if args.slot or args.density:
        rec = {
            "brix_raw": args.brix, "slot": args.slot, "visual_density": args.density,
            "water_level": args.water, "oil_emulsification": args.oil,
            "boiling_heat_state": args.boiling, "photo_quality": args.photo,
            "image_condition_score": args.image_score,
        }
        print(json.dumps(E.score_record(rec, models), ensure_ascii=False, indent=2))
        return

    ap.error("--demo / --record / --input / 直接指定 のいずれかを指定してください")


if __name__ == "__main__":
    main()
