"""Fitted section handler — auto-list assembled ships from stockrooms (in-game curated
by a name marker), snapshot each fit, reconcile on recompute. Manual price, per-ship."""

import logging

from django.conf import settings

from ...models import FITTED, FittedListing, Shop, ShopSource
from ...tasks import TASK_PRIORITY
from ..base import SectionHandler, register
from .forms import EditFittedStockroomForm, FittedStockroomForm
from .stock import reconcile_fitted_listings

logger = logging.getLogger(__name__)


class FittedSectionHandler(SectionHandler):
    section = FITTED
    stockroom_form_class = FittedStockroomForm
    edit_stockroom_form_class = EditFittedStockroomForm
    manage_template = "shop/manage_fitted.html"
    featured_model = FittedListing

    def manage_context(self, shop, request):
        from ...sources import source_tree

        return {
            "listings": FittedListing.objects.filter(shop=shop)
            .select_related("eve_type")
            .order_by("eve_type__name", "ship_name"),
            "sources": shop.sources.filter(section=FITTED).select_related(
                "character_audit__character", "corporation_audit__corporation"
            ),
            "add_stockroom_form": FittedStockroomForm(owner=request.user, shop=shop),
            "source_tree": source_tree(request.user, shop),
        }

    def storefront_context(self, shop, request):
        base = FittedListing.objects.filter(shop=shop).select_related(
            "eve_type", "eve_type__eve_group"
        )
        featured = list(
            base.filter(featured=True).order_by(
                "featured_at", "eve_type__name", "ship_name"
            )
        )
        listings = list(
            base.filter(featured=False).order_by("eve_type__name", "ship_name")
        )
        view = request.GET.get("view", "grid")
        if view not in ("grid", "table"):
            view = "grid"
        return {
            "featured_listings": featured,
            "listings": listings,
            "view": view,
        }

    def build_order_line(self, shop, listing_id):
        listing = FittedListing.objects.filter(shop=shop, pk=listing_id).first()
        if listing is None:
            return None
        return {
            "section": FITTED,
            "eve_type": listing.eve_type,  # the hull
            "unit_price": listing.price,
            "listing_id": listing.pk,
            "label": listing.ship_name[:100],  # OrderLine.label is max_length=100
            # present ship -> cap at 1; a persisted gone ship -> build-to-order (no cap)
            "available": listing.stock or None,
            "fit_json": listing.fit_json,  # frozen onto the order line
        }

    def _apply_source_fields(self, source, cd):
        source.name_filter = cd.get("name_filter", "") or ""
        source.strip_marker = bool(cd.get("strip_marker"))
        source.save(update_fields=["name_filter", "strip_marker"])

    def stockroom_added(self, source, cd):
        self._apply_source_fields(source, cd)
        reconcile_fitted_listings(source.shop)

    def stockroom_edited(self, source, cd):
        self._apply_source_fields(source, cd)
        reconcile_fitted_listings(source.shop)

    def stockroom_removed(self, shop):
        reconcile_fitted_listings(shop)

    def shops_to_recompute(self):
        return (
            Shop.objects.filter(sources__section=FITTED)
            .values_list("pk", flat=True)
            .distinct()
        )

    def enqueue_source_refresh(self):
        if not getattr(settings, "SHOP_REFRESH_CORPTOOLS_ASSETS", True):
            return []
        from corptools.tasks.character.assets import update_char_assets
        from corptools.tasks.corporation import update_corp_assets

        srcs = ShopSource.objects.filter(section=FITTED)
        eve_char_ids = list(
            srcs.filter(character_audit__isnull=False)
            .values_list("character_audit__character__character_id", flat=True)
            .distinct()
        )
        for eve_char_id in eve_char_ids:
            update_char_assets.apply_async(
                args=[eve_char_id],
                kwargs={"force_refresh": True},
                priority=TASK_PRIORITY,
            )
        corp_ids = list(
            srcs.filter(corporation_audit__isnull=False)
            .values_list("corporation_audit__corporation__corporation_id", flat=True)
            .distinct()
        )
        for corp_id in corp_ids:
            update_corp_assets.apply_async(
                args=[corp_id],
                kwargs={"force_refresh": True},
                priority=TASK_PRIORITY,
            )
        return eve_char_ids + corp_ids

    def recompute(self, shop):
        reconcile_fitted_listings(shop)


register(FittedSectionHandler())
