#!/usr/bin/env python3
import re
import csv
import argparse
from pathlib import Path

MONTHS_3 = {
    "JAN": "January", "FEB": "February", "MAR": "March", "APR": "April",
    "MAY": "May", "JUN": "June", "JUL": "July", "AUG": "August",
    "SEP": "September", "OCT": "October", "NOV": "November", "DEC": "December",
}
MONTHS_2 = {
    "01": "January", "02": "February", "03": "March", "04": "April",
    "05": "May", "06": "June", "07": "July", "08": "August",
    "09": "September", "10": "October", "11": "November", "12": "December",
}

def title_person(person_raw: str) -> str:
    parts = [p for p in str(person_raw).split("_") if p]
    # drop single-letter middle tokens (e.g., danielle_c_mercurio -> danielle mercurio)
    if len(parts) >= 3:
        parts = [parts[0]] + [p for p in parts[1:-1] if len(p) != 1] + [parts[-1]]

    out = []
    for p in parts:
        if len(p) == 1:
            out.append(p.upper())
        else:
            out.append(p[:1].upper() + p[1:].lower())
    return " ".join(out)

def strip_ots(s: str):
    s = str(s).strip()
    if s.lower().endswith(".ots"):
        return s[:-4], True
    return s, False

def ext_label(filename_tail: str) -> str:
    base, ots = strip_ots(filename_tail)
    lower = base.lower()
    if lower.endswith(".raw.json"):
        ext = "Raw JSON"
    else:
        ext = Path(base).suffix.lower().lstrip(".").upper()
    if ots:
        ext = (ext + " OTS").strip()
    return ext

def doc_base(filename_tail: str) -> str:
    base, _ots = strip_ots(filename_tail)
    lower = base.lower()
    if lower.endswith(".raw.json"):
        return base[:-8]  # strip ".raw.json"
    if "." in base:
        return base.rsplit(".", 1)[0]  # strip last extension
    return base

def doc_label_structured(rest: str) -> str:
    """
    rest examples:
      hearing.pdf
      hearings__CLEANED.csv
      hearings__TRANSPOSED_SPLIT.csv.ots
      ots_timestamp_report.pdf
    """
    base = doc_base(rest)
    parts = [p for p in re.split(r"_+", base) if p]
    if not parts:
        return base

    # Sometimes rest begins with doc type already included in structured filenames (CR/MH/etc),
    # but for the JUN_2025__raissa_carpenter__... block it's typically just 'hearings...' or 'master...'
    # So we treat first token as the "main label".
    main = parts[0].lower()
    tail = parts[1:]

    # Normalize weird "hearings_" (with trailing underscore)
    if main == "hearings" and tail == []:
        return "Hearings"

    # Common top-level labels
    if main == "hearing":
        label = "Hearing"
    elif main == "hearings":
        label = "Hearings"
    elif main == "master":
        return "Master"
    elif main == "ots" and "_".join([t.lower() for t in tail]) == "timestamp_report":
        return "Timestamp Report"
    else:
        # fallback title case
        label = main.replace("-", " ").title()

    # Sub-flags after "hearings__..."
    # e.g., hearings__CLEANED, hearings__TRANSPOSED_SPLIT, hearings__TRANSPOSED_clusters
    sub = None
    if main in ("hearing", "hearings") and tail:
        # detect known suffixes in a stable way
        tail_join = "_".join(tail).lower()

        if "cleaned" in tail_join:
            sub = "Cleaned"
        elif "transposed_split" in tail_join:
            sub = "Transposed Split"
        elif "transposed_clusters" in tail_join or "clusters" in tail_join:
            sub = "Transposed Clusters"
        elif "transposed" in tail_join:
            sub = "Transposed"

    return f"{label} | {sub}" if sub else label

def pretty_structured(fn: str) -> str:
    """
    Matches: MON_YYYY__person__rest
    Example: JUN_2025__raissa_carpenter__hearings__CLEANED.csv.ots
    """
    m = re.match(r"^(?P<mon>[A-Z]{3})_(?P<year>\d{4})__(?P<person>.+?)__(?P<rest>.+)$", fn)
    if not m:
        return None

    mon3 = m.group("mon")
    year = m.group("year")
    month = MONTHS_3.get(mon3, mon3)
    person = title_person(m.group("person"))
    rest = m.group("rest")

    doc = doc_label_structured(rest)
    ext = ext_label(rest)

    return f"{month}, {year} | {person} | {doc} | {ext}"

def pretty_monthly_archive(fn: str) -> str:
    """
    Matches: name-YYYY-MM.ext(.ots)
    Example: raissa-2018-01.html.ots
    Output: January, 2018 | Raissa | HTML OTS
    """
    base, ots = strip_ots(fn)
    m = re.match(r"^(?P<name>[a-zA-Z]+)-(?P<year>\d{4})-(?P<mm>\d{2})\.(?P<ext>[^.]+)$", base)
    if not m:
        return None

    name = m.group("name")[:1].upper() + m.group("name")[1:].lower()
    year = m.group("year")
    mm = m.group("mm")
    month = MONTHS_2.get(mm, mm)
    ext = m.group("ext").upper()

    ext_out = ext + (" OTS" if ots else "")
    return f"{month}, {year} | {name} | {ext_out}"

def filename_to_pretty(fn: str) -> str:
    fn = str(fn).strip()
    if not fn:
        return ""

    # Try the structured style first
    out = pretty_structured(fn)
    if out:
        return out

    # Then try the monthly archive style
    out = pretty_monthly_archive(fn)
    if out:
        return out

    # fallback
    return fn

def read_lines_file(path: str):
    with open(path, "r", encoding="utf-8") as f:
        for line in f:
            s = line.strip()
            if s:
                yield s

def read_csv_file(path: str, col: str | None):
    import pandas as pd
    df = pd.read_csv(path)
    if col is None:
        # try common names
        for c in df.columns:
            if c.strip().lower() in ("filename", "file", "path", "key"):
                col = c
                break
        if col is None:
            col = df.columns[0]
    df["filename_pretty"] = df[col].map(filename_to_pretty)
    return df

def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("input", help="Input .txt (one filename per line) OR .csv")
    ap.add_argument("output", help="Output .csv")
    ap.add_argument("--col", help="CSV column name if input is CSV", default=None)
    args = ap.parse_args()

    in_path = args.input
    out_path = args.output

    if in_path.lower().endswith(".csv"):
        df = read_csv_file(in_path, args.col)
        df.to_csv(out_path, index=False)
    else:
        rows = [{"filename": fn, "filename_pretty": filename_to_pretty(fn)} for fn in read_lines_file(in_path)]
        with open(out_path, "w", encoding="utf-8", newline="") as f:
            w = csv.DictWriter(f, fieldnames=["filename", "filename_pretty"])
            w.writeheader()
            w.writerows(rows)

if __name__ == "__main__":
    main()
