#!/usr/bin/env python3
"""
Pobiera dane e-commerce ze Shoper API (zamówienia, przychody, AOV).

Użycie:
    python scripts/reports/fetch_shoper_data.py --domain innsi.pl --month 2026-02
"""

import argparse
import json
import os
import sys
import io
from collections import defaultdict
from pathlib import Path

if __name__ == "__main__":
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

import requests
ROOT = Path(__file__).parent.parent.parent
sys.path.insert(0, str(ROOT))
from src.gads_v2.config import load_env

load_env(ROOT / ".env")


def _shoper_auth(domain):
    """Authenticate to Shoper API, return (base_url, headers)."""
    base = os.environ[f"SHOPER_API_URL_{domain}"].rstrip("/")
    login = os.environ[f"SHOPER_API_LOGIN_{domain}"]
    password = os.environ[f"SHOPER_API_PASSWORD_{domain}"]

    r = requests.post(f"{base}/auth", auth=(login, password), timeout=15)
    r.raise_for_status()
    token = r.json()["access_token"]
    return base, {"Authorization": f"Bearer {token}"}


def _collect_orders_for_month(base, headers, target_month):
    """Paginate orders (newest first) and collect all for target_month."""
    orders = []
    page = 1
    found = False

    while page < 100:
        r = requests.get(
            f"{base}/orders?limit=50&page={page}&order=date+desc",
            headers=headers, timeout=20,
        )
        r.raise_for_status()
        data = r.json()
        page_orders = data.get("list", [])
        if not page_orders:
            break

        for o in page_orders:
            month = o["date"][:7]
            if month == target_month:
                found = True
                orders.append(o)
            elif found and month < target_month:
                return orders

        page += 1

    return orders


def fetch_shoper_ecommerce(domain, month, prev_month):
    """Fetch Shoper e-commerce data for month and previous month.

    Returns dict compatible with ga4.ecommerce structure.
    """
    base, headers = _shoper_auth(domain)

    # Collect orders for both months in one pass
    current_orders = []
    prev_orders = []
    page = 1
    found_current = False
    found_prev = False
    passed_prev = False

    while page < 200 and not passed_prev:
        r = requests.get(
            f"{base}/orders?limit=50&page={page}&order=date+desc",
            headers=headers, timeout=20,
        )
        r.raise_for_status()
        data = r.json()
        page_orders = data.get("list", [])
        if not page_orders:
            break

        for o in page_orders:
            m = o["date"][:7]
            if m == month:
                found_current = True
                current_orders.append(o)
            elif m == prev_month:
                found_prev = True
                prev_orders.append(o)
            elif found_prev and m < prev_month:
                passed_prev = True
                break

        page += 1

    def _summarize(orders):
        if not orders:
            return {"transactions": 0, "revenue": 0.0, "aov": 0.0}
        total = sum(float(o["sum"]) for o in orders)
        count = len(orders)
        return {
            "transactions": count,
            "revenue": round(total, 2),
            "aov": round(total / count, 2),
        }

    current = _summarize(current_orders)
    previous = _summarize(prev_orders)

    # Daily breakdown
    daily_map = defaultdict(lambda: {"revenue": 0.0, "transactions": 0})
    for o in current_orders:
        day = o["date"][:10]
        daily_map[day]["revenue"] += float(o["sum"])
        daily_map[day]["transactions"] += 1

    daily = []
    for day in sorted(daily_map.keys()):
        daily.append({
            "date": day,
            "revenue": round(daily_map[day]["revenue"], 2),
            "transactions": daily_map[day]["transactions"],
        })

    # MoM change
    def _pct(cur, prev):
        if prev == 0:
            return 100.0 if cur > 0 else 0.0
        return round(((cur - prev) / prev) * 100, 1)

    mom = {
        "transactions_pct": _pct(current["transactions"], previous["transactions"]),
        "revenue_pct": _pct(current["revenue"], previous["revenue"]),
        "aov_pct": _pct(current["aov"], previous["aov"]),
    }

    return {
        "source": "shoper",
        "current": current,
        "previous": previous,
        "mom_change": mom,
        "daily": daily,
    }


def main():
    parser = argparse.ArgumentParser(description="Pobierz dane e-commerce ze Shoper")
    parser.add_argument("--domain", required=True)
    parser.add_argument("--month", required=True, help="YYYY-MM")
    args = parser.parse_args()

    # Calculate prev month
    y, m = map(int, args.month.split("-"))
    if m == 1:
        prev = f"{y-1}-12"
    else:
        prev = f"{y}-{m-1:02d}"

    data = fetch_shoper_ecommerce(args.domain, args.month, prev)
    print(json.dumps(data, indent=2, ensure_ascii=False))
    cur = data["current"]
    print(f"\n{args.month}: {cur['transactions']} zamówień, {cur['revenue']:.2f} PLN, AOV {cur['aov']:.2f} PLN")


if __name__ == "__main__":
    main()
