"""
Requeue non-auth creative materialization blockers for failed onboarding runs.

Default mode is dry-run. To dispatch:

  APPLY=1 UV_CACHE_DIR=/tmp/uv-cache uv run python manage.py shell < /tmp/requeue_non_auth_pending_creatives.py

Optional env:
  MAX_PER_ACCOUNT=10        limit rows per account while testing
  ONLY_ACCOUNT_ID=<uuid>    restrict to one account
  SCHEDULE_RECONCILE=1      schedule onboarding reconcile after dispatch

Scope:
  Only pending AdCreativeData rows for the non-auth blocker accounts called out
  in the investigation. This intentionally excludes auth/token/credential
  failure rows.
"""

import os

from celery import chord
from django.utils import timezone

from common.utils import calculate_task_countdowns
from creative_module.models import AccountSyncLog, AdCreativeData
from creative_module.tasks.ad_creative_task import (
    fetch_ad_creative_data_task,
    schedule_onboarding_reconcile,
    trigger_batch_incremental_assign,
)
from creative_module.types import UpdateStatus
from crux_ferrous_insights_app.celery import Priority
from organization_auth.models import Account


APPLY = 1
SCHEDULE_RECONCILE = os.environ.get("SCHEDULE_RECONCILE") == "1"
ONLY_ACCOUNT_ID = os.environ.get("ONLY_ACCOUNT_ID")
MAX_PER_ACCOUNT = 1


TARGETS = [
    {
        "name": "CF_EMEA_ APEX.DE_ Stellantis-Opel_DE_Automotive_CL*",
        "account_id": "ddc8c9a0-9cbb-4160-8fe5-e1c445da4439",
        "run_id": "e4880251-5ecd-4efa-9e3d-53406ec551e4",
    },
    {
        "name": "CF_EMEA_ APEX.IT_GSK_IT_CPG*CL 2",
        "account_id": "326578b0-fd74-44eb-a25c-06c6ad23b26a",
        "run_id": "787fdb0b-3f3c-4bd3-8de6-f1551c1c938c",
    },
    {
        "name": "CF EMEA_Brightfish.BE_Brightfish.BE_Belgium_Arts & Entertainment*CL",
        "account_id": "2c46b0eb-217f-4dca-912b-8288aab015a3",
        "run_id": "702112d6-532b-46f3-88c5-6bfcae75ba08",
    },
    {
        "name": "CF_EMEA_Dentsu.HU_Zwack Inc_Hungary_Alcohol/LDA*CL",
        "account_id": "55b54c1d-213f-42be-9557-4fe199a2ae0c",
        "run_id": "7d23af7e-025d-49de-99eb-89fcc4fbabe1",
    },
    {
        "name": "CF_EMEA_HandicapNL_IGM Network_Charitable Foundations*CL",
        "account_id": "aab443ee-7f13-404f-91d9-004afdd20d81",
        "run_id": "ade22646-896b-48d8-8af0-b1a8db16f949",
    },
    {
        "name": "CF_EMEA_OMD.QA (974)_Qatar Central Bank_Travel & Tourism*CL",
        "account_id": "dadfc906-8169-4b17-931c-1cd60aed79f1",
        "run_id": "e8859667-436e-4bfa-b3c5-760806506762",
    },
    {
        "name": "Meta_IN_Publicis-Groupe-IN_Cathay-Pacific_IN_Airline*AX-1022",
        "account_id": "ec4cfcf6-0a97-4c9e-ba94-af3b41ba390b",
        "run_id": "b65e559e-277f-4f94-8cbc-567dc4b1e410",
    },
    {
        "name": "Meta_IN_Publicis-Groupe-IN_EFL_IN_Home-Appliances*AX-1022",
        "account_id": "bceff4f0-d150-4d68-a0d6-8c23a5bc6403",
        "run_id": "667de63a-72bb-474e-b275-c83f5493480d",
    },
    {
        "name": "Platzi MX",
        "account_id": "29ec4a5f-facd-466f-83d9-2fcd14488078",
        "run_id": "5ae66125-74de-4654-aee9-ed62f7475b15",
    },
]


def pending_rows_for_account(account_id):
    qs = (
        AdCreativeData.objects
        .filter(account_id=account_id, sync_status=UpdateStatus.PENDING.value)
        .exclude(ad_id__isnull=True)
        .order_by("updated_at", "id")
    )
    if MAX_PER_ACCOUNT:
        return list(qs[:MAX_PER_ACCOUNT])
    return list(qs)


total_rows = 0
total_dispatched = 0

print(f"mode={'APPLY' if APPLY else 'DRY_RUN'}")
print("scope=pending AdCreativeData rows only; auth/token failure rows are excluded")

for target in TARGETS:
    if ONLY_ACCOUNT_ID and target["account_id"] != ONLY_ACCOUNT_ID:
        continue

    account = Account.objects.get(id=target["account_id"])
    run = AccountSyncLog.objects.get(id=target["run_id"], account=account)
    rows = pending_rows_for_account(str(account.id))
    total_rows += len(rows)

    print()
    print(f"{target['name']} ({account.id})")
    print(f"  run={run.id} platform={account.platform} pending_rows={len(rows)}")

    if not rows:
        continue

    scoped = sum(1 for row in rows if str(row.account_sync_log_id) == str(run.id))
    sample_ad_ids = ", ".join(str(row.ad_id) for row in rows[:8])
    print(f"  scoped_to_run={scoped} unscoped_or_other_run={len(rows) - scoped}")
    print(f"  sample_ad_ids={sample_ad_ids}")

    if not APPLY:
        continue

    AdCreativeData.objects.filter(id__in=[row.id for row in rows]).update(
        error_message=None,
        error_type=None,
        task_id=None,
        sync_status=UpdateStatus.PENDING.value,
        updated_at=timezone.now(),
    )

    countdowns = calculate_task_countdowns(
        platform=account.platform,
        account_id=None,
        num_tasks=len(rows),
    )
    fetch_tasks = [
        fetch_ad_creative_data_task.s(
            str(row.ad_id),
            str(account.id),
            str(run.triggered_by_id),
            account.platform,
        ).set(countdown=countdowns[index], priority=Priority.LOW)
        for index, row in enumerate(rows)
    ]
    callback = trigger_batch_incremental_assign.s(
        account_id=str(account.id),
    ).set(priority=Priority.LOW)
    result = chord(fetch_tasks, callback).apply_async(priority=Priority.LOW)

    print(f"  dispatched_chord={result.id}")
    total_dispatched += len(rows)

    if SCHEDULE_RECONCILE:
        schedule_onboarding_reconcile(str(run.id))
        print("  scheduled_onboarding_reconcile=1")

print()
print(f"total_pending_rows={total_rows}")
if APPLY:
    print(f"total_dispatched_rows={total_dispatched}")
else:
    print("dry_run_done=1")
