from django.db.models import Count, Q
from django.utils import timezone

from creative_module.models import AdCreativeData
from creative_module.types import UpdateStatus
from data_pipeline_module.services.ad_creative_sync import (
    build_ad_creative_row,
    push_ad_creatives_to_clickhouse,
)


ACCOUNT_IDS = [
    "1b18d586-1c24-4272-882c-c1b979d06686",  # STAGE - Acquisition 1
    "26bef1e6-fdba-4580-a7cc-3665767bac84",  # STAGE Retargeting - 1
    "9c84bf17-60fe-4086-a04a-a0d7eef5f514",  # Stage_Haryanavi_2025
    "d933447c-0190-48b3-b6b4-949f4f53fa99",  # Stage_HR_Branding
]

# False matches the existing reconcile_ad_creatives command:
#   push only rows where sync_status='success' and ch_pushed_at is NULL.
# True pushes every ch_pushed_at NULL row for these accounts, including failed rows
# with no linked Creative. It does not change sync_status, labels, or overviews.
PUSH_FAILED_ROWS = True

BATCH_SIZE = 1000
DRY_RUN = False


base_qs = (
    AdCreativeData.objects.filter(
        account_id__in=ACCOUNT_IDS,
        ch_pushed_at__isnull=True,
    )
    .select_related("account", "creative")
    .order_by("account__ad_account_name", "ad_id")
)

if not PUSH_FAILED_ROWS:
    base_qs = base_qs.filter(sync_status=UpdateStatus.SUCCESS.value)


print("Target rows by account/status:")
for row in (
    base_qs.values("account__ad_account_name", "account_id", "sync_status")
    .annotate(count=Count("id"))
    .order_by("account__ad_account_name", "sync_status")
):
    print(row)

total = base_qs.count()
print(f"Total rows selected: {total}")
print(f"PUSH_FAILED_ROWS={PUSH_FAILED_ROWS} DRY_RUN={DRY_RUN} BATCH_SIZE={BATCH_SIZE}")

if DRY_RUN or total == 0:
    raise SystemExit

total_rows_built = 0
total_inserted = 0
total_marked = 0
total_skipped = 0
total_failed = 0

batch = []
batch_ids = []


def flush_batch():
    global total_inserted, total_marked, total_failed
    if not batch:
        return

    inserted = push_ad_creatives_to_clickhouse(batch)
    total_inserted += inserted

    if inserted:
        now = timezone.now()
        updated = AdCreativeData.objects.filter(id__in=batch_ids).update(ch_pushed_at=now)
        total_marked += updated
        print(f"Pushed batch rows={len(batch)} inserted={inserted} marked={updated}")
    else:
        total_failed += len(batch)
        print(f"WARNING: ClickHouse push returned 0 for batch size={len(batch)}; not marking pushed")

    batch.clear()
    batch_ids.clear()


for ad in base_qs.iterator(chunk_size=BATCH_SIZE):
    row = build_ad_creative_row(ad)
    if row is None:
        total_skipped += 1
        continue

    batch.append(row)
    batch_ids.append(ad.id)
    total_rows_built += 1

    if len(batch) >= BATCH_SIZE:
        flush_batch()

flush_batch()

print(
    {
        "selected": total,
        "rows_built": total_rows_built,
        "inserted": total_inserted,
        "marked_ch_pushed_at": total_marked,
        "skipped_no_row": total_skipped,
        "failed_not_marked": total_failed,
    }
)

print("Remaining ch_pushed_at NULL by account/status:")
remaining_qs = AdCreativeData.objects.filter(
    account_id__in=ACCOUNT_IDS,
    ch_pushed_at__isnull=True,
)
for row in (
    remaining_qs.values("account__ad_account_name", "account_id", "sync_status")
    .annotate(count=Count("id"))
    .order_by("account__ad_account_name", "sync_status")
):
    print(row)
