"""Export a company's Form 4 insider transactions to CSV.

Flattens each filing's transaction legs into one row per transaction and coerces
the schema's strings-as-filed numerics to Decimal at the edge (the API never
coerces for you — see the schema guarantees in the docs).

Usage:
    export FILINGPULSE_API_KEY=fp_your_key
    python export_insider_trades_csv.py KMI --since 2026-01-01

Requires: pip install filingpulse
"""
import argparse
import csv
import os
import sys
from decimal import Decimal, InvalidOperation

from filingpulse import FilingPulse

PAGE_SIZE = 200  # API maximum


def to_decimal(value):
    """Values arrive exactly as filed; not every filing states every number."""
    if value is None:
        return None
    try:
        return Decimal(value)
    except InvalidOperation:
        return None  # as-filed junk ("N/A", ...) — keep the row, drop the number


def main() -> None:
    ap = argparse.ArgumentParser(description=__doc__)
    ap.add_argument("ticker", help="Issuer trading symbol, e.g. KMI")
    ap.add_argument("--since", help="Only filings filed on/after YYYY-MM-DD")
    ap.add_argument("--out", help="Output path (default <TICKER>_insider_trades.csv)")
    args = ap.parse_args()

    api_key = os.environ.get("FILINGPULSE_API_KEY")
    if not api_key:
        sys.exit("Set FILINGPULSE_API_KEY (free key: https://filingpulse.io/signup.html)")
    fp = FilingPulse(api_key=api_key,
                     base_url=os.environ.get("FILINGPULSE_BASE_URL",
                                             "https://api.filingpulse.io"))

    out_path = args.out or f"{args.ticker.upper()}_insider_trades.csv"
    fields = ["period", "form_type", "owner", "officer_title", "security_title",
              "transaction_date", "transaction_code", "acquired_disposed",
              "shares", "price_per_share", "shares_owned_after", "is_derivative"]

    rows, offset = [], 0
    while True:
        page = fp.insider_trades(ticker=args.ticker, since=args.since,
                                 limit=PAGE_SIZE, offset=offset)
        for filing in page["data"]:
            owner = filing["reporting_owners"][0]
            for tx in filing["transactions"]:
                rows.append({
                    "period": filing["period"],
                    "form_type": filing["form_type"],
                    "owner": owner["name"],
                    "officer_title": owner["officer_title"] or "",
                    "security_title": tx["security_title"],
                    "transaction_date": tx["transaction_date"],
                    "transaction_code": tx["transaction_code"],
                    "acquired_disposed": tx["acquired_disposed"],
                    "shares": to_decimal(tx["shares"]),
                    "price_per_share": to_decimal(tx["price_per_share"]),
                    "shares_owned_after": to_decimal(tx["shares_owned_after"]),
                    "is_derivative": tx["is_derivative"],
                })
        offset += PAGE_SIZE
        if offset >= page["total"]:
            break

    with open(out_path, "w", newline="", encoding="utf-8") as f:
        writer = csv.DictWriter(f, fieldnames=fields)
        writer.writeheader()
        writer.writerows(rows)
    print(f"{len(rows)} transactions from {page['total']} filings -> {out_path}")


if __name__ == "__main__":
    main()
