#!/usr/bin/env python3
"""
Carica tutte le immagini di storage/agenzie/ su Cloudflare R2 mantenendo lo
stesso path. Skip degli oggetti già presenti per ripartenza idempotente.

Variabili ambiente richieste:
  R2_ACCOUNT_ID, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_BUCKET

Usa: python3 import-tools/scripts/upload_images_r2.py
"""
from __future__ import annotations
import mimetypes
import os
import sys
from pathlib import Path

try:
    import boto3
    from botocore.exceptions import ClientError
    from botocore.config import Config
except ImportError:
    sys.exit("boto3 mancante. pip3 install --user boto3")

ROOT = Path(__file__).resolve().parents[2]
STORAGE = ROOT / "storage" / "agenzie"

ACCOUNT_ID = os.environ.get("R2_ACCOUNT_ID")
ACCESS_KEY = os.environ.get("R2_ACCESS_KEY_ID")
SECRET_KEY = os.environ.get("R2_SECRET_ACCESS_KEY")
BUCKET = os.environ.get("R2_BUCKET")

if not all([ACCOUNT_ID, ACCESS_KEY, SECRET_KEY, BUCKET]):
    sys.exit("Mancano env vars R2_ACCOUNT_ID / R2_ACCESS_KEY_ID / R2_SECRET_ACCESS_KEY / R2_BUCKET")

ENDPOINT = f"https://{ACCOUNT_ID}.r2.cloudflarestorage.com"

s3 = boto3.client(
    "s3",
    endpoint_url=ENDPOINT,
    aws_access_key_id=ACCESS_KEY,
    aws_secret_access_key=SECRET_KEY,
    config=Config(signature_version="s3v4", retries={"max_attempts": 3, "mode": "standard"}),
    region_name="auto",
)


def list_existing_keys() -> set[str]:
    """Lista oggetti già nel bucket per skip idempotente."""
    keys: set[str] = set()
    paginator = s3.get_paginator("list_objects_v2")
    for page in paginator.paginate(Bucket=BUCKET):
        for obj in page.get("Contents", []) or []:
            keys.add(obj["Key"])
    return keys


def main():
    if not STORAGE.exists():
        sys.exit(f"Cartella sorgente non trovata: {STORAGE}")

    print(f"Sorgente:  {STORAGE}")
    print(f"Bucket:    {BUCKET}")
    print(f"Endpoint:  {ENDPOINT}")
    print()

    files = sorted([p for p in STORAGE.rglob("*") if p.is_file()])
    print(f"File da caricare: {len(files):,}")
    total_bytes = sum(p.stat().st_size for p in files)
    print(f"Spazio totale:    {total_bytes / 1024 / 1024:.1f} MB")

    print("Verifico oggetti già presenti su R2...")
    existing = list_existing_keys()
    print(f"Già presenti: {len(existing):,}")

    uploaded = skipped = errors = 0
    bytes_uploaded = 0
    for i, p in enumerate(files, 1):
        key = "agenzie/" + str(p.relative_to(STORAGE))
        if key in existing:
            skipped += 1
        else:
            mime, _ = mimetypes.guess_type(str(p))
            try:
                s3.upload_file(
                    str(p),
                    BUCKET,
                    key,
                    ExtraArgs={"ContentType": mime or "application/octet-stream"},
                )
                uploaded += 1
                bytes_uploaded += p.stat().st_size
            except ClientError as e:
                errors += 1
                print(f"  ✗ {key}: {e}")

        if i % 200 == 0:
            print(
                f"  ... {i}/{len(files)}  uploaded={uploaded:,}  skipped={skipped:,}  errors={errors}"
                f"  ({bytes_uploaded / 1024 / 1024:.0f} MB)"
            )

    print()
    print("=" * 60)
    print(f"FINE. uploaded={uploaded:,}  skipped={skipped:,}  errors={errors}")
    print(f"Spazio caricato: {bytes_uploaded / 1024 / 1024:.0f} MB")


if __name__ == "__main__":
    main()
