#!/usr/bin/env python3
"""
condo-cost-tracker — Track Davao condo investment costs and ROI.
Local data only. No external APIs.
"""
import json
import csv
import sys
import argparse
from datetime import date, datetime
from pathlib import Path

DATA_DIR = Path.home() / ".condo-tracker"
UNITS_FILE = DATA_DIR / "units.json"
EXPENSES_DIR = DATA_DIR / "expenses"
PROJECTIONS_DIR = DATA_DIR / "projections"

EXPENSE_CATEGORIES = [
    "HOA", "Mortgage", "Utilities", "Cleaning",
    "Maintenance", "Platform", "Insurance", "Tax", "Furnishings", "Other"
]

def ensure_dirs():
    for d in [DATA_DIR, EXPENSES_DIR, PROJECTIONS_DIR]:
        d.mkdir(parents=True, exist_ok=True)
    if not UNITS_FILE.exists():
        UNITS_FILE.write_text(json.dumps({"units": []}, indent=2))

def load_units() -> list:
    return json.loads(UNITS_FILE.read_text()).get("units", [])

def save_units(units: list):
    UNITS_FILE.write_text(json.dumps({"units": units}, indent=2))

def expense_file(unit: str, month: str) -> Path:
    return EXPENSES_DIR / f"{month}-{unit}.json"

def load_expenses(unit: str, month: str) -> list:
    f = expense_file(unit, month)
    return json.loads(f.read_text()) if f.exists() else []

def save_expenses(unit: str, month: str, expenses: list):
    expense_file(unit, month).write_text(json.dumps(expenses, indent=2))

def php_to_usd(amount: float, rate: float = 56.0) -> float:
    return amount / rate

def fmt_php(amount: float) -> str:
    return f"₱{amount:,.0f}"

def fmt_usd(amount: float) -> str:
    return f"${amount:,.2f}"

# ─── Commands ────────────────────────────────────────────────────────────────

def cmd_units(args):
    units = load_units()
    if not units:
        print("No units registered. Add one with: condo-tracker add-unit --name '...' --type STR")
        return
    for u in units:
        print(f"• {u['name']} ({u.get('type','STR')}) — Purchase: {fmt_php(u.get('purchase_price',0))} | HOA: {fmt_php(u.get('hoa_monthly',0))}/mo")

def cmd_add_unit(args):
    units = load_units()
    unit = {
        "name": args.name,
        "type": args.type or "STR",
        "purchase_price": args.purchase_price or 0,
        "hoa_monthly": args.hoa or 0,
        "nightly_rate_usd": args.nightly_rate or 0,
        "added": date.today().isoformat(),
    }
    units.append(unit)
    save_units(units)
    print(f"✅ Unit added: {unit['name']}")

def cmd_log(args):
    if args.category not in EXPENSE_CATEGORIES:
        print(f"❌ Invalid category. Choose from: {', '.join(EXPENSE_CATEGORIES)}")
        sys.exit(1)
    expenses = load_expenses(args.unit, args.month)
    entry = {
        "date": date.today().isoformat(),
        "category": args.category,
        "amount": args.amount,
        "currency": args.currency or "PHP",
        "note": args.note or "",
    }
    expenses.append(entry)
    save_expenses(args.unit, args.month, expenses)
    currency_sym = "₱" if (args.currency or "PHP") == "PHP" else "$"
    print(f"✅ Logged: {args.category} — {currency_sym}{args.amount:,.0f} ({args.month})")

def cmd_summary(args):
    expenses = load_expenses(args.unit, args.month)
    if not expenses:
        print(f"No expenses logged for {args.unit} in {args.month}.")
        return

    # Group by category
    by_cat: dict[str, float] = {}
    total_php = 0.0
    for e in expenses:
        amt = e["amount"]
        if e["currency"] == "USD":
            amt = amt * 56.0  # to PHP
        by_cat[e["category"]] = by_cat.get(e["category"], 0) + amt
        total_php += amt

    print(f"\n{'─'*50}")
    print(f"  Condo Cost Summary — {args.unit} / {args.month}")
    print(f"{'─'*50}")
    for cat, amt in sorted(by_cat.items(), key=lambda x: -x[1]):
        print(f"  {cat:<14} {fmt_php(amt):>12}")
    print(f"{'─'*50}")
    print(f"  {'TOTAL':<14} {fmt_php(total_php):>12}  (~{fmt_usd(php_to_usd(total_php))})")
    print(f"{'─'*50}\n")

def cmd_project(args):
    """12-month STR revenue projection vs. costs."""
    nightly = args.str_rate  # USD
    occ = args.occupancy / 100
    exchange = args.exchange_rate or 56.0

    monthly_gross_usd = nightly * 30 * occ
    platform_fee = monthly_gross_usd * 0.03
    cleaning_turns = int(30 * occ / 3)  # avg 3-night stay
    cleaning_cost_usd = cleaning_turns * (args.cleaning_fee or 15)
    net_str_usd = monthly_gross_usd - platform_fee - cleaning_cost_usd

    hoa_php = args.hoa or 9000
    utilities_php = args.utilities or 5000
    mortgage_php = args.mortgage or 0
    monthly_costs_php = hoa_php + utilities_php + mortgage_php
    monthly_costs_usd = monthly_costs_php / exchange

    net_cash_flow_usd = net_str_usd - monthly_costs_usd

    print(f"\n{'═'*55}")
    print(f"  STR Projection — {args.unit or 'Unit'}")
    print(f"{'═'*55}")
    print(f"  Nightly rate:        {fmt_usd(nightly)}/night")
    print(f"  Occupancy:           {occ*100:.0f}%  ({occ*30:.1f} nights/month)")
    print(f"  Gross revenue:       {fmt_usd(monthly_gross_usd)}/month")
    print(f"  Platform fee (3%):  -{fmt_usd(platform_fee)}")
    print(f"  Cleaning ({cleaning_turns} turns): -{fmt_usd(cleaning_cost_usd)}")
    print(f"  ─────────────────────────────────────────────")
    print(f"  Net STR income:      {fmt_usd(net_str_usd)}/month  (~{fmt_php(net_str_usd*exchange)})")
    print(f"\n  Monthly costs:")
    print(f"    HOA:               {fmt_php(hoa_php)}")
    print(f"    Utilities:         {fmt_php(utilities_php)}")
    if mortgage_php:
        print(f"    Mortgage:          {fmt_php(mortgage_php)}")
    print(f"    Total costs:       {fmt_php(monthly_costs_php)}  (~{fmt_usd(monthly_costs_usd)})")
    print(f"  ─────────────────────────────────────────────")
    cf_label = "💚 POSITIVE" if net_cash_flow_usd > 0 else "🔴 NEGATIVE"
    print(f"  Net cash flow:       {fmt_usd(net_cash_flow_usd)}/month  {cf_label}")
    print(f"  Annual net:          {fmt_usd(net_cash_flow_usd*12)}/year")
    print(f"{'═'*55}\n")

def cmd_compare(args):
    """Compare STR vs long-term rental (LTR)."""
    nightly = args.str_rate or 50
    occ = (args.occupancy or 70) / 100
    exchange = args.exchange_rate or 56.0
    ltr_php = args.ltr_rate or 18000  # monthly PHP

    # STR
    str_gross = nightly * 30 * occ
    str_net = str_gross * 0.97 - int(30 * occ / 3) * 15  # ~3% platform, $15 cleaning/turn

    # LTR
    ltr_usd = ltr_php / exchange

    print(f"\n{'═'*50}")
    print(f"  STR vs LTR Comparison")
    print(f"{'═'*50}")
    print(f"  STR ({nightly}/night, {occ*100:.0f}% occ.):")
    print(f"    Gross:    {fmt_usd(str_gross)}/mo  ({fmt_php(str_gross*exchange)})")
    print(f"    Net:      {fmt_usd(str_net)}/mo   ({fmt_php(str_net*exchange)})")
    print(f"\n  LTR (fixed rent):")
    print(f"    Revenue:  {fmt_usd(ltr_usd)}/mo  ({fmt_php(ltr_php)})")
    print(f"\n  STR advantage: {fmt_usd(str_net - ltr_usd)}/month")
    adv = str_net - ltr_usd
    note = "✅ STR earns more" if adv > 0 else "⚠️  LTR earns more (or similar)"
    print(f"  {note}")
    print(f"{'═'*50}\n")

def cmd_roi(args):
    """ROI and break-even analysis."""
    purchase = args.purchase_price or 3500000  # PHP
    exchange = args.exchange_rate or 56.0
    net_monthly_usd = args.net_monthly_usd or 500

    net_annual_php = net_monthly_usd * 12 * exchange
    roi_pct = (net_annual_php / purchase) * 100
    payback_years = purchase / net_annual_php if net_annual_php > 0 else float("inf")

    print(f"\n{'═'*50}")
    print(f"  ROI Analysis")
    print(f"{'═'*50}")
    print(f"  Purchase price:      {fmt_php(purchase)}")
    print(f"  Net monthly income:  {fmt_usd(net_monthly_usd)} ({fmt_php(net_monthly_usd*exchange)})")
    print(f"  Net annual income:   {fmt_php(net_annual_php)}")
    print(f"  ROI:                 {roi_pct:.1f}%/year")
    print(f"  Payback period:      {payback_years:.1f} years")
    print(f"{'═'*50}\n")

def cmd_export(args):
    unit = args.unit
    year = args.year or date.today().year
    rows = []
    for m in range(1, 13):
        month_str = f"{year}-{m:02d}"
        expenses = load_expenses(unit, month_str)
        for e in expenses:
            rows.append({
                "month": month_str,
                "unit": unit,
                "category": e["category"],
                "amount": e["amount"],
                "currency": e["currency"],
                "note": e.get("note", ""),
                "date": e.get("date", ""),
            })
    if not rows:
        print(f"No expense data found for {unit} in {year}.")
        return
    out = Path(f"condo-{unit}-{year}-{date.today().isoformat()}.csv")
    with open(out, "w", newline="") as f:
        writer = csv.DictWriter(f, fieldnames=rows[0].keys())
        writer.writeheader()
        writer.writerows(rows)
    print(f"✅ Exported {len(rows)} records to {out}")

# ─── Main ────────────────────────────────────────────────────────────────────

def main():
    ensure_dirs()
    parser = argparse.ArgumentParser(description="Condo Cost Tracker — Davao Investment")
    sub = parser.add_subparsers(dest="command")

    sub.add_parser("units", help="List registered units")

    p_add = sub.add_parser("add-unit", help="Register a new condo unit")
    p_add.add_argument("--name", required=True)
    p_add.add_argument("--type", default="STR", choices=["STR", "LTR", "Owner"])
    p_add.add_argument("--purchase-price", type=float)
    p_add.add_argument("--hoa", type=float)
    p_add.add_argument("--nightly-rate", type=float)

    p_log = sub.add_parser("log", help="Log a monthly expense")
    p_log.add_argument("--unit", required=True)
    p_log.add_argument("--month", required=True, help="YYYY-MM")
    p_log.add_argument("--category", required=True, choices=EXPENSE_CATEGORIES)
    p_log.add_argument("--amount", type=float, required=True)
    p_log.add_argument("--currency", default="PHP", choices=["PHP", "USD"])
    p_log.add_argument("--note")

    p_sum = sub.add_parser("summary", help="Monthly expense summary")
    p_sum.add_argument("--unit", required=True)
    p_sum.add_argument("--month", required=True)

    p_proj = sub.add_parser("project", help="STR revenue projection")
    p_proj.add_argument("--unit")
    p_proj.add_argument("--str-rate", type=float, required=True, help="Nightly rate in USD")
    p_proj.add_argument("--occupancy", type=float, default=70, help="Occupancy rate 0-100 (default 70)")
    p_proj.add_argument("--hoa", type=float, help="Monthly HOA in PHP")
    p_proj.add_argument("--utilities", type=float, help="Monthly utilities in PHP")
    p_proj.add_argument("--mortgage", type=float, help="Monthly mortgage in PHP")
    p_proj.add_argument("--cleaning-fee", type=float, help="Cleaning fee per turn USD (default 15)")
    p_proj.add_argument("--exchange-rate", type=float, help="PHP/USD rate (default 56)")

    p_comp = sub.add_parser("compare", help="Compare STR vs LTR income")
    p_comp.add_argument("--unit")
    p_comp.add_argument("--str-rate", type=float)
    p_comp.add_argument("--occupancy", type=float)
    p_comp.add_argument("--ltr-rate", type=float, help="Long-term monthly rent in PHP")
    p_comp.add_argument("--exchange-rate", type=float)

    p_roi = sub.add_parser("roi", help="ROI and payback analysis")
    p_roi.add_argument("--unit")
    p_roi.add_argument("--purchase-price", type=float, help="Purchase price in PHP")
    p_roi.add_argument("--net-monthly-usd", type=float, help="Expected net monthly income USD")
    p_roi.add_argument("--exchange-rate", type=float)

    p_exp = sub.add_parser("export", help="Export to CSV")
    p_exp.add_argument("--unit", required=True)
    p_exp.add_argument("--year", type=int)

    args = parser.parse_args()

    dispatch = {
        "units": cmd_units,
        "add-unit": cmd_add_unit,
        "log": cmd_log,
        "summary": cmd_summary,
        "project": cmd_project,
        "compare": cmd_compare,
        "roi": cmd_roi,
        "export": cmd_export,
    }

    if args.command in dispatch:
        dispatch[args.command](args)
    else:
        parser.print_help()

if __name__ == "__main__":
    main()
