# vouchers/management/commands/sync_brands.py
# vouchers/management/commands/sync_brands.py
from django.core.management.base import BaseCommand
from django.utils import timezone
from django.db import transaction
from vouchers.services import get_token, BASE_URL
from vouchers.models import Brand
from vouchers.utils import decrypt_payload
import requests
from datetime import datetime
from datetime import datetime, timezone  # add timezone from stdlib
from django.utils import timezone as dj_timezone

def normalize_denomination(raw):
    """
    Ensure denomination_list is always a list of ints when possible.
    Examples:
      "1000" -> [1000]
      1000   -> [1000]
      ["100", "200"] -> [100, 200]
      None   -> []
    """
    if not raw:
        return []
    if isinstance(raw, list):
        out = []
        for x in raw:
            try:
                out.append(int(str(x).strip()))
            except (TypeError, ValueError):
                # ignore non-numeric entries
                pass
        return out
    # single value
    try:
        return [int(str(raw).strip())]
    except (TypeError, ValueError):
        return []

def parse_updated_at(s):
    """
    Parse provider updated_at to aware datetime.
    Accepts common ISO strings; falls back to now() if missing/invalid.
    """
    if not s:
        return dj_timezone.now()
    s = str(s).strip()
    for fmt in ("%Y-%m-%dT%H:%M:%S.%fZ",
                "%Y-%m-%dT%H:%M:%SZ",
                "%Y-%m-%d %H:%M:%S",
                "%Y-%m-%d"):
        try:
            dt = datetime.strptime(s, fmt)
            if dt.tzinfo is None:
                return dj_timezone.make_aware(dt, timezone.utc)  # ✅ use stdlib utc
            return dt
        except ValueError:
            continue
    return dj_timezone.now()


class Command(BaseCommand):
    help = "Sync brands from API"

    def handle(self, *args, **kwargs):
        token = get_token()
        if not token:
            self.stdout.write(self.style.ERROR("Token fetch failed."))
            return

        headers = {"Content-Type": "application/json", "token": token}
        try:
            res = requests.post(f"{BASE_URL}/getbrands", headers=headers, json={}, timeout=30)
        except requests.RequestException as e:
            self.stdout.write(self.style.ERROR(f"HTTP error: {e}"))
            return

        if res.status_code != 200:
            self.stdout.write(self.style.ERROR(f"HTTP {res.status_code}"))
            return

        data = res.json()
        if data.get('status') != 'success':
            self.stdout.write(self.style.WARNING(f"Provider error: {data.get('desc') or data}"))
            return

        decrypted = decrypt_payload(data.get('data'))
        if not isinstance(decrypted, (list, tuple)):
            self.stdout.write(self.style.ERROR("Decrypted payload is not a list."))
            return

        created_count = 0
        updated_count = 0

        with transaction.atomic():
            for brand in decrypted:
                # read raw fields with safeguards
                product_code = brand.get('BrandProductCode') or brand.get('productCode')
                if not product_code:
                    # skip bad record
                    continue

                denom_list = normalize_denomination(brand.get('denominationList'))
                stock_available = str(brand.get('stockAvailable')).lower() == "true"
                updated_at = parse_updated_at(brand.get('updated_at'))

                defaults = {
                    'name': brand.get('BrandName') or brand.get('name') or "",
                    'redemption_type': brand.get('RedemptionType') or None,
                    'brand_type': brand.get('Brandtype') or None,
                    'online_redemption_url': brand.get('OnlineRedemptionUrl') or None,
                    'image_url': brand.get('BrandImage') or "",
                    'category': brand.get('Category', '') or '',
                    'description': brand.get('Descriptions') or None,
                    'tnc': brand.get('tnc', '') or '',
                    'important_instruction': brand.get('importantInstruction') or None,
                    'redeem_steps': brand.get('redeemSteps') or None,
                    'denomination_list': denom_list,
                    'stock_available': stock_available,
                    'updated_at': updated_at,
                }

                obj, created = Brand.objects.update_or_create(
                    product_code=product_code,
                    defaults=defaults
                )
                if created:
                    created_count += 1
                else:
                    updated_count += 1

        self.stdout.write(self.style.SUCCESS(
            f"Brands synced successfully. Created: {created_count}, Updated: {updated_count}."
        ))
