#!/usr/bin/env python3
"""Log work expenses to MongoDB (wip.work_expenses).

Usage:
    python log_expense.py <type> <account> <date> <note> <s2_url_1> [s2_url_2] [--route stop1|stop2]
    python log_expense.py update <doc_id> [--account X] [--note X] [--route stop1|stop2]

    type:    "meal" or "mileage"
    account: e.g. "LTISD"
    date:    YYYY-MM-DD
    note:    free-text context (quote if it has spaces)
    s2_url:  one or more S2 URLs of uploaded files
    --route: pipe-separated list of stops (mileage only). Home address is
             automatically prepended and appended.

    update:  Modify an existing entry by doc ID. Accepts --account, --note,
             and/or --route.

Rules enforced:
    - meal:    exactly 1 file per invocation
    - mileage: exactly 2 files per invocation (start + end odometer)
"""

import sys
from datetime import datetime
from bson import ObjectId
from pymongo import MongoClient

HOME = "11600 Minda Cir Austin, TX 78758"
ALIASES = {
    "airport": "3201 Presidential Blvd, Austin, TX 78719",
    "aus": "3201 Presidential Blvd, Austin, TX 78719",
}

MONGO_URI = "mongodb://root:3wwfoUjyk2E2zWELXFlLuHqfw1ALlOp4pb2H5Vq3TImbMIHL2h1u8Jej2mjzCPl@docdb.connorrhodes.com:35563?tls=true&tlsAllowInvalidCertificates=true"


def handle_update(args):
    if not args:
        print("Usage: log_expense.py update <doc_id> [--account X] [--note X] [--route stop1|stop2]")
        sys.exit(1)
    doc_id = args.pop(0)
    updates = {}
    i = 0
    while i < len(args):
        if args[i] == "--account" and i + 1 < len(args):
            updates["account"] = args[i + 1]; i += 2
        elif args[i] == "--note" and i + 1 < len(args):
            updates["note"] = args[i + 1]; i += 2
        elif args[i] == "--route" and i + 1 < len(args):
            raw = [s.strip() for s in args[i + 1].split("|") if s.strip()]
            raw = [ALIASES.get(s.lower(), s) for s in raw]
            updates["route"] = [HOME] + raw + [HOME]
            i += 2
        else:
            print(f"Error: unknown argument '{args[i]}'"); sys.exit(1)
    if not updates:
        print("Error: no fields to update"); sys.exit(1)
    client = MongoClient(MONGO_URI)
    result = client["wip"]["work_expenses"].update_one({"_id": ObjectId(doc_id)}, {"$set": updates})
    if result.matched_count:
        print(f"Updated {doc_id}: {list(updates.keys())}")
    else:
        print(f"Error: document {doc_id} not found")


def main():
    args = sys.argv[1:]

    # Handle update subcommand first
    if args and args[0] == "update":
        handle_update(args[1:])
        return

    # Parse --route for insert
    route_stops = None
    if "--route" in args:
        idx = args.index("--route")
        args.pop(idx)
        if idx >= len(args):
            print("Error: --route requires a value")
            sys.exit(1)
        route_val = args.pop(idx)
        route_stops = [s.strip() for s in route_val.split("|") if s.strip()]
        route_stops = [ALIASES.get(s.lower(), s) for s in route_stops]
        route_stops = [HOME] + route_stops + [HOME]

    if len(args) < 5:
        print('Usage: log_expense.py <type> <account> <date> <note> <s2_url_1> [s2_url_2] [--route stop1|stop2]')
        sys.exit(1)

    exp_type = args[0]
    account = args[1]
    date = args[2]
    note = args[3]
    files = args[4:]

    if exp_type not in ("meal", "mileage"):
        print(f"Error: type must be 'meal' or 'mileage', got '{exp_type}'")
        sys.exit(1)

    if exp_type == "meal" and len(files) != 1:
        print(f"Error: meal entries must have exactly 1 file, got {len(files)}")
        sys.exit(1)

    if exp_type == "mileage" and len(files) != 2:
        print(f"Error: mileage entries must have exactly 2 files (start + end odometer), got {len(files)}")
        sys.exit(1)

    if route_stops is not None and exp_type != "mileage":
        print("Error: --route is only valid for mileage entries")
        sys.exit(1)

    client = MongoClient(MONGO_URI)
    db = client["wip"]
    col = db["work_expenses"]

    doc = {
        "files": files,
        "date": datetime.strptime(date, "%Y-%m-%d"),
        "type": exp_type,
        "account": account,
        "note": note,
        "status": "todo"
    }

    if route_stops is not None:
        doc["route"] = route_stops

    result = col.insert_one(doc)
    print(f"Inserted {exp_type} for {account} on {date}: {result.inserted_id}")

if __name__ == "__main__":
    main()
