#!/usr/bin/env python3
"""フラッシュカードCSVの機械チェック。
使い方: python3 card_lint.py cards.csv
先頭2列を「表(問い)」「裏(答え)」として読む。ヘッダー行があれば自動で飛ばす。
機械でできるのは「怪しい箇所の洗い出し」まで。正誤の判定は人間が教材で行う。
"""
import csv
import re
import sys
from collections import Counter

MAX_FRONT = 80      # 表がこれより長いなら「1枚に詰めすぎ」の疑い
MAX_BACK = 100      # 裏がこれより長いなら分割の疑い


def norm(s):
    return re.sub(r"\s+", "", s).lower()


def main(path):
    with open(path, newline="", encoding="utf-8-sig") as f:
        rows = [r for r in csv.reader(f) if len(r) >= 2 and any(c.strip() for c in r)]
    if rows and re.fullmatch(r"(?i)\s*(front|question|表|問題|質問)\s*", rows[0][0]):
        rows = rows[1:]
    fronts = Counter(norm(r[0]) for r in rows)
    backs = Counter(norm(r[1]) for r in rows)
    problems = []
    for i, r in enumerate(rows, 1):
        q, a = r[0].strip(), r[1].strip()
        why = []
        if len(q) > MAX_FRONT:
            why.append(f"表が長い({len(q)}字)")
        if len(a) > MAX_BACK:
            why.append(f"裏が長い({len(a)}字)。複数の論点が混ざっていないか")
        if len(re.findall(r"[?？]", q)) >= 2:
            why.append("問いが2つ以上ある")
        if fronts[norm(q)] > 1:
            why.append("同じ表のカードが他にもある")
        if backs[norm(a)] > 1 and len(a) > 4:
            why.append("同じ裏のカードが他にもある（問いの重複か）")
        if norm(a) and norm(a) in norm(q):
            why.append("答えが問いの中に書かれている")
        if re.search(r"(すべて|常に|必ず|決して|のみ)", a):
            why.append("断定語(すべて/常に/必ず/のみ)。例外が教材にないか確認")
        if why:
            problems.append((i, q, why))
    print(f"カード {len(rows)} 枚中、要確認 {len(problems)} 枚")
    for i, q, why in problems:
        print(f"- #{i} {q[:40]}")
        for w in why:
            print(f"    * {w}")


if __name__ == "__main__":
    if len(sys.argv) != 2:
        sys.exit(__doc__)
    main(sys.argv[1])
