#!/usr/bin/env python3
"""
BOM CSV Exporter
================
Reads extract_symbols.json and writes bom.csv with columns:
    Reference, MPN, MFG

Power symbols (#PWR, #FLG) are excluded.

Usage:
    python3 export_bom.py [project_dir]
"""

import csv
import json
import sys
from pathlib import Path


def main(project_dir: Path):
    json_path = project_dir / 'extract_symbols.json'
    if not json_path.exists():
        print(f"Error: {json_path} not found. Run extract_symbols.py first.", file=sys.stderr)
        sys.exit(1)

    data = json.loads(json_path.read_text(encoding='utf-8'))
    symbols = data['symbols']

    # Filter out power/flag symbols, DNP parts, and parts excluded from BOM
    parts = [
        s for s in symbols
        if not (s.get('reference') or '').startswith(('#', '~'))
        and not (s.get('lib_id') or '').startswith('power:')
        and s.get('in_bom') is not False
        and not s.get('dnp')
    ]

    # Collapse multi-unit / duplicate records to one row per reference.
    # If multiple records exist for the same ref, pick the one with the
    # most complete MPN/MFG data (longest non-placeholder string).
    def data_score(s):
        props = s.get('properties', {})
        mpn = props.get('MPN', '')
        mfg = props.get('MFG') or props.get('MANUFACTURER', '')
        placeholder = mpn.strip().lower() in ('', 'x', 'tbd', 'n/a', 'na')
        return (0 if placeholder else len(mpn) + len(mfg))

    from collections import defaultdict
    by_ref: dict[str, list] = defaultdict(list)
    for s in parts:
        by_ref[s.get('reference', '')].append(s)

    best: list[dict] = []
    for ref, recs in by_ref.items():
        best.append(max(recs, key=data_score))

    # Sort by reference
    def ref_sort_key(r):
        ref = r.get('reference') or ''
        letters = ''.join(c for c in ref if c.isalpha())
        digits  = ''.join(c for c in ref if c.isdigit())
        return (letters, int(digits) if digits else 0)

    best.sort(key=ref_sort_key)

    out_path = project_dir / 'bom.csv'
    with out_path.open('w', newline='', encoding='utf-8') as f:
        writer = csv.writer(f)
        writer.writerow(['Reference', 'MPN', 'MFG'])
        for s in best:
            props = s.get('properties', {})
            writer.writerow([
                s.get('reference', ''),
                props.get('MPN', ''),
                props.get('MFG') or props.get('MANUFACTURER', ''),
            ])

    excluded_bom = sum(1 for s in symbols if s.get('in_bom') is False
                       and not (s.get('reference') or '').startswith(('#', '~')))
    excluded_dnp = sum(1 for s in symbols if s.get('dnp')
                       and not (s.get('reference') or '').startswith(('#', '~'))
                       and s.get('in_bom') is not False)
    print(f"Excluded: {excluded_bom} 'exclude from BOM', {excluded_dnp} DNP")
    print(f"Wrote {len(best)} unique references to {out_path} (collapsed from {len(parts)} records)")


if __name__ == '__main__':
    project_dir = Path(sys.argv[1]).resolve() if len(sys.argv) > 1 else Path(__file__).parent.resolve()
    main(project_dir)
