"""
BSS Skill: CSV Data Summarizer
Detects CSV content in PROMPT, extracts schema + statistics, and outputs
a compact summary that gives the LLM everything it needs without the raw data.
"""
import csv
import io
import re
import statistics

text = PROMPT

# ── Find CSV block in the prompt ──────────────────────────────────────────────
# Accept raw CSV or CSV inside a code fence
csv_match = re.search(r"```(?:csv)?\s*\n(.*?)```", text, re.DOTALL)
if csv_match:
    csv_text = csv_match.group(1).strip()
else:
    # Heuristic: look for lines that all contain at least one comma
    lines = text.splitlines()
    csv_lines = [l for l in lines if l.count(",") >= 1]
    csv_text = "\n".join(csv_lines) if len(csv_lines) >= 2 else text

# ── Parse CSV ─────────────────────────────────────────────────────────────────
try:
    reader = csv.DictReader(io.StringIO(csv_text))
    rows = list(reader)
    headers = reader.fieldnames or []
except Exception:
    # Not parseable — pass through truncated
    print(text[:600])
    raise SystemExit

if not rows or not headers:
    print(text[:600])
    raise SystemExit

# ── Compute per-column stats ──────────────────────────────────────────────────
col_stats = {}
for col in headers:
    values = [r[col].strip() for r in rows if col in r and r[col].strip()]
    numeric = []
    for v in values:
        try:
            numeric.append(float(v.replace(",", ".")))
        except ValueError:
            pass

    if numeric and len(numeric) >= len(values) * 0.7:
        col_stats[col] = {
            "type": "numeric",
            "count": len(numeric),
            "min": min(numeric),
            "max": max(numeric),
            "mean": round(statistics.mean(numeric), 4),
            "nulls": len(rows) - len(values),
        }
    else:
        unique = set(values)
        col_stats[col] = {
            "type": "categorical",
            "count": len(values),
            "unique": len(unique),
            "top5": list(unique)[:5],
            "nulls": len(rows) - len(values),
        }

# ── Extract non-CSV context from the prompt ───────────────────────────────────
# Keep any instructions/questions outside the CSV block
if csv_match:
    instructions = re.sub(r"```(?:csv)?.*?```", "", text, flags=re.DOTALL).strip()
else:
    # Exclude lines identified as CSV rows (those with commas)
    all_lines = text.splitlines()
    instructions = " ".join(l.strip() for l in all_lines if l.count(",") < 1 and l.strip())

# ── Output ────────────────────────────────────────────────────────────────────
print("=== BIBIVIDI CSV SUMMARY ===")
print(f"Rows: {len(rows)} | Columns: {len(headers)}")
print(f"Headers: {', '.join(headers)}")
print()

for col, stats in col_stats.items():
    if stats["type"] == "numeric":
        print(f"[{col}] numeric — min={stats['min']} max={stats['max']} "
              f"mean={stats['mean']} nulls={stats['nulls']}")
    else:
        top = ", ".join(str(v) for v in stats["top5"])
        print(f"[{col}] categorical — {stats['unique']} unique values "
              f"(e.g. {top}) nulls={stats['nulls']}")

print()
print(f"Sample rows (first 3):")
for row in rows[:3]:
    print("  " + " | ".join(f"{k}={v}" for k, v in list(row.items())[:6]))

if instructions:
    print()
    print(f"User request: {instructions[:300]}")

print("=== END CSV SUMMARY ===")
