#!/usr/bin/env python3
"""
Format inventory entries for adding to inventory.md.

Usage:
    format_inventory_entry.py --ean EAN [--qty N] [--bb YYYY-MM] [--mass Xg] [--volume Xl]

This script looks up an EAN in the cache and formats it as an inventory entry.
"""

import argparse
import json
import sys
from pathlib import Path
from datetime import datetime, timedelta

DEFAULT_CACHE = Path.home() / "solveig-inventory" / "ean_cache.json"

# Category mappings based on product type
CATEGORY_TAGS = {
    "milk": "food/dairy/milk",
    "cheese": "food/dairy/cheese",
    "yogurt": "food/dairy/yogurt",
    "butter": "food/dairy/butter",
    "chocolate": "food/snacks/chocolate",
    "biscuit": "food/snacks/biscuits",
    "cookie": "food/snacks/biscuits",
    "potato": "food/vegetable/potato",
    "onion": "food/vegetable/onion",
    "tomato": "food/vegetable/tomato",
    "banana": "food/fruit/banana",
    "apple": "food/fruit/apple",
    "bread": "food/bread",
    "seafood": "food/seafood",
    "fish": "food/seafood",
    "shrimp": "food/seafood",
    "gamberi": "food/seafood",
    "meat": "food/meat",
    "chicken": "food/meat/chicken",
    "pork": "food/meat/pork",
    "beef": "food/meat/beef",
    "canned": "food/canned",
    "oil": "food/oil",
    "olive": "food/oil/olive",
    "pasta": "food/pasta",
    "rice": "food/grain/rice",
    "lentil": "food/legumes/lentils",
    "bean": "food/legumes/beans",
    "chickpea": "food/legumes/chickpeas",
    "juice": "food/drinks/juice",
    "water": "food/drinks/water",
    "coffee": "food/drinks/coffee",
    "tea": "food/drinks/tea",
}

# Default best-before estimates (days from purchase)
BB_ESTIMATES = {
    "food/dairy/milk": 10,
    "food/dairy/yogurt": 14,
    "food/dairy/cheese": 30,
    "food/dairy/butter": 60,
    "food/snacks/chocolate": 240,
    "food/snacks/biscuits": 180,
    "food/vegetable/potato": 90,
    "food/vegetable/onion": 60,
    "food/fruit/banana": 7,
    "food/bread": 5,
    "food/seafood": 90,  # Frozen
    "food/canned": 730,
}


def load_cache(path: Path) -> dict:
    """Load the EAN cache."""
    try:
        with open(path) as f:
            return json.load(f)
    except (FileNotFoundError, json.JSONDecodeError):
        return {}


def guess_category(name: str, categories: str = "") -> str:
    """Guess the food category tag based on product name and categories."""
    text = f"{name} {categories}".lower()

    for keyword, tag in CATEGORY_TAGS.items():
        if keyword in text:
            return tag

    return "food"


def estimate_bb(tag: str, days_override: int | None = None) -> str:
    """Estimate best-before date based on category."""
    if days_override:
        days = days_override
    else:
        days = BB_ESTIMATES.get(tag, 180)  # Default 6 months

    bb_date = datetime.now() + timedelta(days=days)

    # Round to month for longer shelf life, exact date for short
    if days > 30:
        return bb_date.strftime("%Y-%m")
    else:
        return bb_date.strftime("%Y-%m-%d")


def generate_id(name: str, brand: str = "") -> str:
    """Generate a reasonable item ID from product name."""
    # Take first word of name and brand
    parts = []
    if brand:
        parts.append(brand.split()[0].lower())
    if name:
        # Skip common words
        for word in name.split():
            word_clean = ''.join(c for c in word.lower() if c.isalnum())
            if word_clean and word_clean not in ('the', 'a', 'an', 'with', 'and'):
                parts.append(word_clean)
                break

    return '-'.join(parts) if parts else "item"


def format_entry(ean: str, info: dict, qty: int = 1, bb: str | None = None,
                 mass: str | None = None, volume: str | None = None) -> str:
    """Format an inventory entry line."""
    name = info.get("name", "Unknown product")
    brand = info.get("brand", "")
    quantity_str = info.get("quantity", "")
    categories = info.get("categories", "")

    # Determine tag
    tag = guess_category(name, categories)

    # Generate ID
    item_id = generate_id(name, brand)

    # Estimate BB if not provided
    if not bb:
        bb = estimate_bb(tag)

    # Build the entry
    parts = [f"* tag:{tag}"]
    parts.append(f"ID:{item_id}")
    parts.append(f"EAN:{ean}")
    parts.append(f"bb:{bb}")

    if qty > 1:
        parts.append(f"qty:{qty}")

    if mass:
        parts.append(f"mass:{mass}")
    elif quantity_str and ('g' in quantity_str.lower() or 'kg' in quantity_str.lower()):
        parts.append(f"mass:{quantity_str}")

    if volume:
        parts.append(f"volume:{volume}")
    elif quantity_str and ('l' in quantity_str.lower() or 'ml' in quantity_str.lower()):
        parts.append(f"volume:{quantity_str}")

    # Product description
    desc_parts = []
    if brand:
        desc_parts.append(brand)
    desc_parts.append(name)
    parts.append(' '.join(desc_parts))

    return ' '.join(parts)


def main():
    parser = argparse.ArgumentParser(description="Format inventory entry from EAN")
    parser.add_argument("--ean", required=True, help="EAN code")
    parser.add_argument("--cache", type=Path, default=DEFAULT_CACHE,
                        help="Path to ean_cache.json")
    parser.add_argument("--qty", type=int, default=1, help="Quantity")
    parser.add_argument("--bb", help="Best-before date (YYYY-MM or YYYY-MM-DD)")
    parser.add_argument("--mass", help="Mass (e.g., 500g)")
    parser.add_argument("--volume", help="Volume (e.g., 1l)")
    args = parser.parse_args()

    cache = load_cache(args.cache)

    if args.ean not in cache or cache[args.ean] is None:
        print(f"EAN {args.ean} not found in cache", file=sys.stderr)
        print(f"* tag:food ID:unknown-{args.ean[-4:]} EAN:{args.ean} bb:{estimate_bb('food')} qty:{args.qty} UNKNOWN PRODUCT")
        sys.exit(1)

    info = cache[args.ean]
    entry = format_entry(args.ean, info, args.qty, args.bb, args.mass, args.volume)
    print(entry)


if __name__ == "__main__":
    main()
