"""
1080P API 集成测试 — 验证 video_generate_view 的入口校验。
"""
import os
import sys
import django

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
django.setup()

import unittest
from django.test import TestCase
from django.contrib.auth import get_user_model
from rest_framework.test import APIClient
from apps.accounts.models import Team
from apps.generation.models import QuotaConfig

User = get_user_model()


class TestVideoGenerateResolution(TestCase):
    """video_generate_view 的分辨率+模型组合校验。"""

    def setUp(self):
        # 初始化 QuotaConfig
        QuotaConfig.objects.get_or_create(pk=1)

        # 建测试 team + user
        self.team = Team.objects.create(
            name='test-1080p',
            is_active=True,
            monthly_spending_limit=1000,
            markup_percentage=0,
            balance=1000,
            frozen_amount=0,
        )
        self.user = User.objects.create_user(
            username='test_1080p_user',
            email='test1080p@example.com',
            password='testpass123',
            team=self.team,
            spending_limit=-1,
            daily_generation_limit=-1,
            monthly_generation_limit=-1,
        )
        self.client = APIClient()
        self.client.force_authenticate(user=self.user)

    def test_reject_fast_plus_1080p(self):
        """原则 1：Fast + 1080P 组合必须 400 拒绝，不能静默降级。"""
        resp = self.client.post('/api/v1/video/generate', {
            'prompt': '测试',
            'mode': 'universal',
            'model': 'seedance_2.0_fast',
            'aspect_ratio': '16:9',
            'duration': 5,
            'resolution': '1080p',
            'references': [],
        }, format='json')
        self.assertEqual(resp.status_code, 400)
        body = resp.json()
        self.assertEqual(body.get('error'), 'invalid_resolution')
        # 提示信息要明确告知用户原因
        self.assertIn('1080P', body.get('message', ''))
        self.assertIn('Fast', body.get('message', ''))

    def test_reject_adaptive_ratio(self):
        """原则 1：adaptive 不在 6 选 1 白名单，拒绝。"""
        resp = self.client.post('/api/v1/video/generate', {
            'prompt': '测试',
            'mode': 'universal',
            'model': 'seedance_2.0',
            'aspect_ratio': 'adaptive',
            'duration': 5,
            'resolution': '720p',
            'references': [],
        }, format='json')
        self.assertEqual(resp.status_code, 400)
        # serializer 错误：aspect_ratio 不在 choices
        self.assertIn('aspect_ratio', str(resp.content))

    def test_reject_invalid_resolution(self):
        """resolution 不在 480p/720p/1080p 白名单，拒绝。"""
        resp = self.client.post('/api/v1/video/generate', {
            'prompt': '测试',
            'mode': 'universal',
            'model': 'seedance_2.0',
            'aspect_ratio': '16:9',
            'duration': 5,
            'resolution': '4K',
            'references': [],
        }, format='json')
        self.assertEqual(resp.status_code, 400)

    def test_resolution_default_720p_when_missing(self):
        """旧客户端不传 resolution 字段时，serializer default='720p' 生效。"""
        # 不传 resolution（兼容旧客户端）
        resp = self.client.post('/api/v1/video/generate', {
            'prompt': '测试',
            'mode': 'universal',
            'model': 'seedance_2.0',
            'aspect_ratio': '16:9',
            'duration': 5,
            'references': [],
        }, format='json')
        # serializer 应该接受（default='720p'）；可能因火山 API 未开通等其他原因失败，
        # 但不该是 resolution 相关的 400 错误
        if resp.status_code == 400:
            body = resp.json()
            self.assertNotEqual(body.get('error'), 'invalid_resolution')

    def test_accept_valid_1080p_airdrama(self):
        """原则：AirDrama + 1080P 组合合法，不被 400 拒绝。"""
        resp = self.client.post('/api/v1/video/generate', {
            'prompt': '测试',
            'mode': 'universal',
            'model': 'seedance_2.0',
            'aspect_ratio': '16:9',
            'duration': 5,
            'resolution': '1080p',
            'references': [],
        }, format='json')
        # 不应该因为分辨率被 400（可能因余额/API 未开通等其他原因失败）
        if resp.status_code == 400:
            body = resp.json()
            self.assertNotEqual(body.get('error'), 'invalid_resolution')


class TestAdminSettingsResponse(TestCase):
    """GET /api/v1/admin/settings 必须返回所有 token_price 字段，
    以防 v0.19.0 那种"字段在 serializer 里加了、但 _settings_dict 漏了"的回归。"""

    def setUp(self):
        QuotaConfig.objects.get_or_create(pk=1)
        self.admin = User.objects.create_user(
            username='test_admin_settings',
            email='test_admin_settings@example.com',
            password='testpass123',
            is_staff=True,
            is_superuser=True,
        )
        self.client = APIClient()
        self.client.force_authenticate(user=self.admin)

    def test_get_returns_all_token_price_fields(self):
        """GET 返回 4 档单价（全部分辨率 + 是否含视频），缺一不可 — 缺字段会导致前端输入框显示空。"""
        resp = self.client.get('/api/v1/admin/settings')
        self.assertEqual(resp.status_code, 200)
        body = resp.json()
        for field in (
            'base_token_price',
            'base_token_price_video',
            'base_token_price_fast',
            'base_token_price_fast_video',
            'base_token_price_1080p',
            'base_token_price_1080p_video',
        ):
            self.assertIn(field, body, f'GET /admin/settings response missing {field!r} — 前端这个输入框会显示空')
            self.assertIsInstance(body[field], (int, float), f'{field} 应该是数字类型')


if __name__ == '__main__':
    unittest.main(verbosity=2)
