"""小程序展示配置：轮播图 / 公告（按俱乐部）。"""
import os
import random
import string

from rest_framework.parsers import FormParser, JSONParser, MultiPartParser
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from backend.utils import verify_kefu_permission
from jituan.services.club_context import resolve_effective_club_id
from jituan.services.display_config import (
    forbid_display_write_in_all_scope,
    get_gonggao_content,
    get_lunbo_urls,
    list_response_meta,
    list_tupianpeizhi_by_type,
    LUNBO_PAGE_OPTIONS,
    lunbo_image_type_for_page,
    normalize_page_key,
    TUPIAN_TYPE_LABELS,
    upsert_tupianpeizhi_single,
)
from config.models import Gonggao, Lunbo, Tupianpeizhi
from products.views import delete_from_oss, upload_to_oss, validate_image

POPUP_PERM = '8080a'


class ClubLunboListView(APIView):
    """GET 轮播列表 POST /jituan/houtai/lunbo-list"""
    permission_classes = [IsAuthenticated]
    parser_classes = [JSONParser]

    def post(self, request):
        phone = (request.data.get('phone') or request.data.get('username') or '').strip()
        if not phone:
            return Response({'code': 401, 'msg': '缺少客服账号'})
        kefu, permissions = verify_kefu_permission(request, phone)
        if kefu is None:
            return permissions
        if POPUP_PERM not in permissions:
            return Response({'code': 403, 'msg': '无权限管理轮播图'})

        page_key = normalize_page_key(request.data.get('page_key'), image_type=1)
        image_type = lunbo_image_type_for_page(page_key)
        urls = get_lunbo_urls(request, page_key=page_key, image_type=image_type)
        return Response({
            'code': 0,
            'data': {
                'page_key': page_key,
                'list': urls,
                'page_options': [{'key': k, 'label': v} for k, v in LUNBO_PAGE_OPTIONS],
                **list_response_meta(request),
            },
        })


class ClubLunboManageView(APIView):
    """轮播增删 POST /jituan/houtai/lunbo-manage"""
    permission_classes = [IsAuthenticated]
    parser_classes = [MultiPartParser, FormParser, JSONParser]

    def post(self, request):
        phone = (request.data.get('phone') or request.data.get('username') or '').strip()
        if not phone:
            return Response({'code': 401, 'msg': '缺少客服账号'})
        kefu, permissions = verify_kefu_permission(request, phone)
        if kefu is None:
            return permissions
        if POPUP_PERM not in permissions:
            return Response({'code': 403, 'msg': '无权限管理轮播图'})

        deny = forbid_display_write_in_all_scope(request)
        if deny:
            return deny

        action = (request.data.get('action') or '').strip()
        club_id = resolve_effective_club_id(request, request.user)
        page_key = normalize_page_key(request.data.get('page_key'), image_type=1)
        image_type = lunbo_image_type_for_page(page_key)

        if action == 'delete':
            tupian_url = (request.data.get('tupian_url') or '').strip()
            if not tupian_url:
                return Response({'code': 400, 'msg': '图片URL不能为空'})
            row = Lunbo.query.filter(
                club_id=club_id, ImageURL=tupian_url, ImageType=image_type, page_key=page_key,
            ).first()
            if not row:
                return Response({'code': 404, 'msg': '轮播图不存在'})
            delete_from_oss(tupian_url)
            row.delete()
            return Response({'code': 0, 'msg': '删除成功'})

        if action == 'add':
            file_obj = request.FILES.get('file')
            if not file_obj:
                return Response({'code': 400, 'msg': '请上传图片'})
            ok, msg = validate_image(file_obj)
            if not ok:
                return Response({'code': 400, 'msg': msg})
            ext = os.path.splitext(file_obj.name)[1].lower() or '.jpg'
            random_str = ''.join(random.choices(string.ascii_lowercase + string.digits, k=6))
            oss_file_path = f"a_long/lunbo/{random_str}{ext}"
            if not upload_to_oss(file_obj, oss_file_path):
                return Response({'code': 500, 'msg': '图片上传失败'})
            Lunbo.query.create(
                club_id=club_id,
                page_key=page_key,
                ImageURL=oss_file_path,
                ImageType=image_type,
            )
            return Response({'code': 0, 'msg': '添加成功', 'data': {'tupian_url': oss_file_path}})

        return Response({'code': 400, 'msg': 'action 必须为 add 或 delete'})


class ClubGonggaoView(APIView):
    """公告读写 POST /jituan/houtai/gonggao"""
    permission_classes = [IsAuthenticated]
    parser_classes = [JSONParser]

    def post(self, request):
        phone = (request.data.get('phone') or request.data.get('username') or '').strip()
        if not phone:
            return Response({'code': 401, 'msg': '缺少客服账号'})
        kefu, permissions = verify_kefu_permission(request, phone)
        if kefu is None:
            return permissions
        if POPUP_PERM not in permissions:
            return Response({'code': 403, 'msg': '无权限管理公告'})

        notice_type = int(request.data.get('notice_type', 1) or 1)
        page_key = normalize_page_key(request.data.get('page_key'), image_type=1)
        club_id = resolve_effective_club_id(request, request.user)

        content = request.data.get('content')
        if content is None:
            return Response({
                'code': 0,
                'data': {
                    'content': get_gonggao_content(request, notice_type=notice_type, page_key=page_key),
                    'notice_type': notice_type,
                    'page_key': page_key,
                    **list_response_meta(request),
                },
            })

        deny = forbid_display_write_in_all_scope(request)
        if deny:
            return deny

        row, _ = Gonggao.query.get_or_create(
            club_id=club_id,
            page_key=page_key,
            defaults={'NoticeType': notice_type, 'Content': content},
        )
        row.Content = content
        row.NoticeType = notice_type
        row.save(update_fields=['Content', 'NoticeType', 'UpdateTime'])
        return Response({'code': 0, 'msg': '保存成功', 'data': {'page_key': page_key}})


class ClubTupianListView(APIView):
    """杂项图片配置列表 POST /jituan/houtai/tupian-list"""
    permission_classes = [IsAuthenticated]
    parser_classes = [JSONParser]

    def post(self, request):
        phone = (request.data.get('phone') or request.data.get('username') or '').strip()
        if not phone:
            return Response({'code': 401, 'msg': '缺少客服账号'})
        kefu, permissions = verify_kefu_permission(request, phone)
        if kefu is None:
            return permissions
        if POPUP_PERM not in permissions:
            return Response({'code': 403, 'msg': '无权限管理小程序图片'})

        club_id = resolve_effective_club_id(request, request.user)
        data = {}
        for t, label in TUPIAN_TYPE_LABELS.items():
            data[str(t)] = {
                'label': label,
                'multi': t == 3,
                'list': list_tupianpeizhi_by_type(club_id, t),
            }
        return Response({
            'code': 0,
            'data': {
                'types': data,
                **list_response_meta(request),
            },
        })


class ClubTupianManageView(APIView):
    """杂项图片上传/删除 POST /jituan/houtai/tupian-manage"""
    permission_classes = [IsAuthenticated]
    parser_classes = [MultiPartParser, FormParser, JSONParser]

    def post(self, request):
        phone = (request.data.get('phone') or request.data.get('username') or '').strip()
        if not phone:
            return Response({'code': 401, 'msg': '缺少客服账号'})
        kefu, permissions = verify_kefu_permission(request, phone)
        if kefu is None:
            return permissions
        if POPUP_PERM not in permissions:
            return Response({'code': 403, 'msg': '无权限管理小程序图片'})

        deny = forbid_display_write_in_all_scope(request)
        if deny:
            return deny

        action = (request.data.get('action') or '').strip()
        image_type = int(request.data.get('image_type') or 0)
        if image_type not in TUPIAN_TYPE_LABELS:
            return Response({'code': 400, 'msg': 'image_type 无效'})

        club_id = resolve_effective_club_id(request, request.user)

        if action == 'delete':
            row_id = request.data.get('id')
            image_url = (request.data.get('image_url') or '').strip()
            qs = Tupianpeizhi.query.filter(club_id=club_id, ImageType=image_type)
            if row_id:
                row = qs.filter(id=row_id).first()
            elif image_url:
                row = qs.filter(ImageURL=image_url).first()
            else:
                return Response({'code': 400, 'msg': '缺少 id 或 image_url'})
            if not row:
                return Response({'code': 404, 'msg': '图片不存在'})
            if row.ImageURL:
                delete_from_oss(row.ImageURL)
            row.delete()
            return Response({'code': 0, 'msg': '删除成功'})

        if action == 'add':
            file_obj = request.FILES.get('file')
            if not file_obj:
                return Response({'code': 400, 'msg': '请上传图片'})
            ok, msg = validate_image(file_obj)
            if not ok:
                return Response({'code': 400, 'msg': msg})
            ext = os.path.splitext(file_obj.name)[1].lower() or '.jpg'
            random_str = ''.join(random.choices(string.ascii_lowercase + string.digits, k=6))
            folder = 'guanzhu' if image_type == 3 else 'misc'
            oss_file_path = f"beijing/{folder}/{club_id}_{random_str}{ext}"
            if not upload_to_oss(file_obj, oss_file_path):
                return Response({'code': 500, 'msg': '图片上传失败'})
            if image_type in (1, 2):
                upsert_tupianpeizhi_single(club_id, image_type, oss_file_path)
            else:
                Tupianpeizhi.query.create(
                    club_id=club_id,
                    ImageType=image_type,
                    ImageURL=oss_file_path,
                    AccessCount=0,
                )
            return Response({'code': 0, 'msg': '上传成功', 'data': {'image_url': oss_file_path}})

        return Response({'code': 400, 'msg': 'action 必须为 add 或 delete'})
