"""
inventory/migrations/0012_backfill_bookstore_listings.py
One-off backfill for books that went live (or were already dispatched to an
external bookstore) BEFORE the unified BookstoreListing mechanism shipped —
without this, those books would silently keep using the old net-amount-scaled
2-way split forever, since the one-time "book.is_listed" and dispatch events
that would normally trigger auto-listing already happened in the past.

- Every application-originated book that's already live gets a Tai
  Bookstore/website listing (bookstore_cut=0, payee_cut=100-my_keep_percent).
- Any (book, bookstore) pair with a historical dispatch_to_bookstore
  transaction but no listing yet gets one too, if the package allows
  external distribution.
"""

from decimal import Decimal

from django.db import migrations


def backfill(apps, schema_editor):
    Bookstore = apps.get_model("inventory", "Bookstore")
    BookstoreListing = apps.get_model("inventory", "BookstoreListing")
    InventoryTransaction = apps.get_model("inventory", "InventoryTransaction")
    AuthorApplicationBook = apps.get_model("catalog_app", "AuthorApplicationBook")

    internal_bookstore = Bookstore.objects.filter(is_internal=True).first()

    app_books = (
        AuthorApplicationBook.objects
        .filter(created_book__isnull=False, created_book__is_listed=True)
        .select_related("application__package", "created_book")
    )
    app_book_by_book_id = {ab.created_book_id: ab for ab in app_books}

    # --- Tai Bookstore / website ---
    if internal_bookstore:
        already = set(
            BookstoreListing.objects
            .filter(bookstore=internal_bookstore)
            .values_list("book_id", flat=True)
        )
        for book_id, app_book in app_book_by_book_id.items():
            if book_id in already:
                continue
            package = app_book.application.package
            if package is None:
                continue
            BookstoreListing.objects.create(
                book_id=book_id,
                bookstore=internal_bookstore,
                agreed_unit_price=app_book.selling_price_kes or Decimal("0"),
                bookstore_cut_percent=Decimal("0"),
                payee_cut_percent=Decimal("100") - package.my_keep_percent,
                notes=f"Backfilled ({package.name} package) — book was already live before "
                      f"this feature shipped.",
            )

    # --- External bookstores already dispatched to, historically ---
    bookstore_by_location_id = {
        b.stock_location_id: b for b in Bookstore.objects.filter(is_internal=False)
        if b.stock_location_id
    }
    dispatch_pairs = (
        InventoryTransaction.objects
        .filter(transaction_type="dispatch_to_bookstore")
        .values_list("book_id", "destination_location_id")
        .distinct()
    )
    for book_id, dest_location_id in dispatch_pairs:
        bookstore = bookstore_by_location_id.get(dest_location_id)
        app_book = app_book_by_book_id.get(book_id)
        if not bookstore or not app_book:
            continue
        package = app_book.application.package
        if package is None or not package.allows_external_bookstores:
            continue
        if package.external_bookstore_author_percent is None:
            continue
        if BookstoreListing.objects.filter(book_id=book_id, bookstore=bookstore).exists():
            continue
        BookstoreListing.objects.create(
            book_id=book_id,
            bookstore=bookstore,
            agreed_unit_price=app_book.selling_price_kes or Decimal("0"),
            bookstore_cut_percent=bookstore.default_bookstore_cut_percent,
            payee_cut_percent=package.external_bookstore_author_percent,
            notes=f"Backfilled ({package.name} package) — stock was already dispatched here "
                  f"before this feature shipped.",
        )


def unbackfill(apps, schema_editor):
    pass  # non-destructive reverse — leaves backfilled listings in place


class Migration(migrations.Migration):
    dependencies = [
        ("inventory", "0011_seed_internal_bookstore"),
        ("catalog_app", "0038_distributionpackage_external_bookstore_author_percent_and_more"),
    ]

    operations = [
        migrations.RunPython(backfill, unbackfill),
    ]
