from django.core.management.base import BaseCommand
from django.utils import timezone
from django.db import transaction

from billing.models import Invoice
from core.models import SystemSettings, OperationLog
from core.goedge_client import GoEdgeClient


class Command(BaseCommand):
    help = '对逾期未支付账单执行未支付策略（停服或限速）。支持 dry-run 与用户/时间过滤。'

    def add_arguments(self, parser):
        parser.add_argument('--days-overdue', type=int, default=0, help='逾期天数阈值（默认0，表示只要未支付即处理）')
        parser.add_argument('--user-id', type=int, default=0, help='仅处理指定用户（可选）')
        parser.add_argument('--dry-run', action='store_true', default=False, help='试运行，不落库与不调用接口')

    @transaction.atomic
    def handle(self, *args, **options):
        days_overdue = int(options.get('days_overdue') or 0)
        user_id = int(options.get('user_id') or 0)
        dry = bool(options.get('dry_run'))

        today = timezone.now().date()
        qs = Invoice.objects.filter(status=Invoice.STATUS_UNPAID)
        if user_id:
            qs = qs.filter(user_id=user_id)
        if days_overdue > 0:
            # 以账单周期结束日为逾期基准
            cutoff = today - timezone.timedelta(days=days_overdue)
            qs = qs.filter(period_end__lte=cutoff)

        invoices = list(qs)
        if not invoices:
            self.stdout.write(self.style.NOTICE('无符合条件的未支付账单'))
            return

        sys = SystemSettings.objects.order_by('id').first()
        policy = getattr(sys, 'default_overage_policy', {}) or {}
        action_type = (policy.get('action') or '').lower()
        limit_bps = int(policy.get('limit_bps') or 0)

        client = None
        if not dry:
            client = GoEdgeClient()

        total_domains = 0
        for inv in invoices:
            applied = []
            items = inv.items.select_related('domain').all()
            for it in items:
                d = it.domain
                if not d or not d.edge_server_id:
                    continue
                total_domains += 1
                if dry:
                    applied.append({'domain': d.name, 'action': action_type or 'shutdown', 'limit_bps': limit_bps})
                    continue
                web_id = client.find_server_web_id(int(d.edge_server_id))
                if not web_id:
                    continue
                if action_type == 'limit' and limit_bps > 0:
                    client.update_http_web_request_limit(web_id, {'isOn': True, 'rateBytes': int(limit_bps)})
                    applied.append({'domain': d.name, 'action': 'limit', 'rateBytes': limit_bps})
                else:
                    client.update_http_web_shutdown(web_id, {'isOn': True})
                    if d.status != 'suspended':
                        d.status = 'suspended'
                        d.save(update_fields=['status', 'updated_at'])
                    applied.append({'domain': d.name, 'action': 'shutdown'})
            if applied:
                try:
                    OperationLog.objects.create(
                        actor=None,
                        action='apply_overage_policy_cron',
                        target=f"Invoice#{inv.id}",
                        detail=str(applied)
                    )
                except Exception:
                    pass
            self.stdout.write(self.style.SUCCESS(f"Invoice#{inv.id} 应用策略：{len(applied)} 个域名"))

        self.stdout.write(self.style.SUCCESS(f'完成：处理账单 {len(invoices)} 个，涉及域名 {total_domains} 个'))