"""
Repair Apr 29 BACKFILL AccountSyncLog rows that are stuck because every
required default AI report failed with "No data to analyze".

Dry run:
    UV_CACHE_DIR=/tmp/uv-cache uv run python manage.py shell < /tmp/repair_no_data_ai_reports_backfill_20260429.py

Apply:
    UV_CACHE_DIR=/tmp/uv-cache APPLY=1 uv run python manage.py shell < /tmp/repair_no_data_ai_reports_backfill_20260429.py
"""

import os

from django.db import transaction

from creative_module.models import AccountSyncLog, Report
from creative_module.services.onboarding_service import (
    DEFAULT_AI_REPORT_TITLES,
    NO_DATA_TO_ANALYZE_ERROR,
    refresh_onboarding_run,
)
from creative_module.types import UpdateStatus


APPLY = 1

TARGET_RUNS = {
    "fdde801b-f426-4de0-9ade-fe7dd29411fb": "10a81928-45b1-4577-8b57-79fe7690dce9",
    "80aa6647-4d6e-4d3f-92d3-cbc69f7035d9": "7d6e0349-9b11-492e-9695-50816ff5f1b3",
}


def get_ai_report_counts(run):
    required_reports = Report.objects.filter(
        account=run.account,
        title__in=DEFAULT_AI_REPORT_TITLES,
        is_deleted=False,
    )
    return {
        "required_ai_reports": required_reports.count(),
        "no_data_failed": required_reports.filter(
            sync_status=UpdateStatus.FAILED.value,
            error_message=NO_DATA_TO_ANALYZE_ERROR,
        ).count(),
        "pending": required_reports.filter(sync_status=UpdateStatus.PENDING.value).count(),
        "success": required_reports.filter(sync_status=UpdateStatus.SUCCESS.value).count(),
        "blocking_failed": required_reports.filter(
            sync_status=UpdateStatus.FAILED.value,
        ).exclude(error_message=NO_DATA_TO_ANALYZE_ERROR).count(),
    }


def validate_target(run, expected_account_id):
    problems = []
    if str(run.account_id) != expected_account_id:
        problems.append(f"account mismatch: expected {expected_account_id}, got {run.account_id}")
    if run.sync_type != AccountSyncLog.SyncType.BACKFILL:
        problems.append(f"sync_type is {run.sync_type}, expected BACKFILL")
    if run.stats_sync_status != AccountSyncLog.StageStatus.SUCCESS:
        problems.append(f"stats_sync_status is {run.stats_sync_status}, expected success")
    if run.overall_status == AccountSyncLog.OverallStatus.SUCCESS:
        problems.append("already success")

    counts = get_ai_report_counts(run)
    if counts["required_ai_reports"] <= 0:
        problems.append("no required AI report rows found; this is not the no-data repair case")
    if counts["required_ai_reports"] != counts["no_data_failed"]:
        problems.append(f"not all required AI reports are failed/no-data: {counts}")
    if counts["pending"] or counts["success"] or counts["blocking_failed"]:
        problems.append(f"unexpected AI report statuses: {counts}")

    return problems, counts


def repair_run(run):
    # This activates the existing BACKFILL freeze branch; refresh still derives
    # creative/materialization and stats statuses before deciding terminal state.
    run.ai_reports_status = AccountSyncLog.StageStatus.SUCCESS
    run.save(update_fields=["ai_reports_status", "updated_at"])
    return refresh_onboarding_run(run)


print(f"Mode: {'APPLY' if APPLY else 'DRY RUN'}")

for run_id, expected_account_id in TARGET_RUNS.items():
    with transaction.atomic():
        run = (
            AccountSyncLog.objects.select_for_update()
            .select_related("account")
            .get(id=run_id)
        )
        before = {
            "overall_status": run.overall_status,
            "current_stage": run.current_stage,
            "ad_creative_sync_status": run.ad_creative_sync_status,
            "stats_sync_status": run.stats_sync_status,
            "ai_reports_status": run.ai_reports_status,
        }
        problems, counts = validate_target(run, expected_account_id)

        if problems:
            print(f"SKIP {run_id} {run.account.ad_account_name}: {'; '.join(problems)}")
            continue

        if APPLY:
            run = repair_run(run)
            after = {
                "overall_status": run.overall_status,
                "current_stage": run.current_stage,
                "ad_creative_sync_status": run.ad_creative_sync_status,
                "stats_sync_status": run.stats_sync_status,
                "ai_reports_status": run.ai_reports_status,
            }
            print(
                f"REPAIRED {run_id} {run.account.ad_account_name}: "
                f"ai_reports={counts}, before={before}, after={after}"
            )
        else:
            print(
                f"WOULD REPAIR {run_id} {run.account.ad_account_name}: "
                f"ai_reports={counts}, before={before}"
            )
