"""
Retry Digistore full refund with force=true for a single order.

Usage:
  python manage.py retry_force_refund --digistore-order-id MNXVZRXL
  python manage.py retry_force_refund --digistore-order-id MNXVZRXL --dry-run
  python manage.py retry_force_refund --digistore-order-id MNXVZRXL --request-date 2026-05-20
"""
from django.core.management.base import BaseCommand, CommandError

from orders.models import Order
from orders.services import OrderService
from webhooks.models import ShopifyRefundEvent


class Command(BaseCommand):
    help = (
        "Retry a full Digistore refund with force=true for one digistore_order_id "
        "and store the response/error on the latest failed refund webhook event."
    )

    def add_arguments(self, parser):
        parser.add_argument(
            "--digistore-order-id",
            type=str,
            required=True,
            help="Digistore purchase/order id (e.g. MNXVZRXL).",
        )
        parser.add_argument(
            "--reason",
            type=str,
            default="Manual force retry after expired window",
            help="Reason sent to Digistore refundPurchase call.",
        )
        parser.add_argument(
            "--request-date",
            type=str,
            default="",
            help="Optional Digistore request_date to evaluate refund policy against.",
        )
        parser.add_argument(
            "--dry-run",
            action="store_true",
            help="Do not call Digistore API; only print what would be retried.",
        )

    def handle(self, *args, **options):
        oid = str(options.get("digistore_order_id") or "").strip()
        reason = str(options.get("reason") or "").strip()
        request_date = str(options.get("request_date") or "").strip()
        dry_run = bool(options.get("dry_run"))

        if not oid:
            raise CommandError("--digistore-order-id is required")

        order = Order.objects.filter(digistore_order_id=oid).order_by("pk").first()
        if not order:
            raise CommandError(f"Order mapping not found for digistore_order_id={oid}")

        latest_failed_event = (
            ShopifyRefundEvent.objects.filter(
                digistore_order_id=oid,
                processed=False,
            )
            .order_by("-created_at")
            .first()
        )

        self.stdout.write(
            f"Order found: digistore_order_id={oid} shopify_order_id={order.shopify_order_id or '-'} "
            f"status={order.status}"
        )
        if latest_failed_event:
            self.stdout.write(
                f"Latest failed refund event: webhook_id={latest_failed_event.webhook_id}"
            )
        else:
            self.stdout.write("Latest failed refund event: none")

        if dry_run:
            self.stdout.write(
                self.style.WARNING(
                    "DRY RUN - would call OrderService.refund_purchase("
                    f"digistore_order_id={oid}, force=True, request_date={request_date or 'now'})"
                )
            )
            return

        try:
            result = OrderService.refund_purchase(
                oid,
                reason=reason,
                force=True,
                request_date=request_date,
            )
        except Exception as exc:
            msg = f"manual_force_retry_exception: {exc}"
            if latest_failed_event:
                latest_failed_event.error = msg
                latest_failed_event.save(update_fields=["error", "updated_at"])
            raise CommandError(msg) from exc

        if latest_failed_event:
            latest_failed_event.error = f"manual_force_retry_response: {result}"
            latest_failed_event.save(update_fields=["error", "updated_at"])

        self.stdout.write(self.style.SUCCESS("Force retry request sent to Digistore."))
        self.stdout.write(f"Response: {result}")
