"""俱乐部商品类型上架与图标（全局类型由集团定义）。"""
import logging
import os
import uuid

from django.db import transaction

from jituan.constants import CLUB_ID_DEFAULT, DATA_SCOPE_ALL
from jituan.models import ClubShangpinLeixingConfig
from jituan.services.club_context import (
    club_id_for_write,
    resolve_club_id_from_request,
    resolve_club_scope,
)
from products.models import ShangpinLeixing
from utils.oss_utils import delete_from_oss, upload_to_oss, validate_image

logger = logging.getLogger(__name__)

CLUB_WRITE_SCOPE_MSG = '当前为集团汇总视图，请先在顶栏切换到具体俱乐部后再操作'
CLUB_READ_SCOPE_MSG = '请先在顶栏切换到具体小程序/俱乐部后再操作'


def club_read_blocked(request):
    return resolve_club_scope(request) == DATA_SCOPE_ALL


def club_write_blocked(request):
    return resolve_club_scope(request) == DATA_SCOPE_ALL


def _config_map(club_id):
    return {
        r.leixing_id: r
        for r in ClubShangpinLeixingConfig.query.filter(club_id=club_id)
    }


def _resolve_tupian(leixing, cfg):
    if cfg and cfg.tupian_url:
        return cfg.tupian_url
    return leixing.tupian_url or ''


def _is_visible(club_id, leixing_id, cfg):
    if cfg is not None:
        return bool(cfg.is_enabled)
    return club_id == CLUB_ID_DEFAULT


def build_leixing_item(leixing, cfg=None):
    item = {
        'id': leixing.id,
        'jieshao': leixing.jieshao or '',
        'tupian_url': _resolve_tupian(leixing, cfg),
        'global_tupian_url': leixing.tupian_url or '',
        'yaoqiuleixing': leixing.yaoqiuleixing,
        'huiyuan_id': leixing.huiyuan_id,
        'yongjin': float(leixing.yongjin) if leixing.yongjin else None,
        'paixu': (cfg.paixu if cfg and cfg.paixu else leixing.paixu) or 0,
        'shenhezhuangtai': leixing.shenhezhuangtai or 1,
        'bankuai_id': leixing.bankuai_id,
        'club_enabled': True,
        'icon_source': 'club' if cfg and cfg.tupian_url else 'global',
        # 新字段：旧客户端忽略；1/true 时该类型订单强制展示价格
        'show_price': bool(getattr(cfg, 'show_price', False)) if cfg else False,
    }
    return item


def build_club_leixing_list_for_api(club_id):
    """小程序/抢单池：仅返回本俱乐部已上架的类型，图标优先俱乐部配置。"""
    cfg_map = _config_map(club_id)
    rows = []
    for lx in ShangpinLeixing.query.exclude(shenhezhuangtai=2):
        cfg = cfg_map.get(lx.id)
        if not _is_visible(club_id, lx.id, cfg):
            continue
        rows.append(build_leixing_item(lx, cfg))
    rows.sort(key=lambda x: (-int(x['paixu'] or 0), x['id']))
    return rows


def build_club_leixing_admin_list(request):
    if club_read_blocked(request):
        return {
            'club_id': resolve_club_id_from_request(request),
            'list': [],
            'scope': resolve_club_scope(request),
            'scope_error': CLUB_READ_SCOPE_MSG,
        }
    club_id = resolve_club_id_from_request(request)
    cfg_map = _config_map(club_id)
    enabled = []
    for lx in ShangpinLeixing.query.exclude(shenhezhuangtai=2).order_by('-paixu', 'id'):
        cfg = cfg_map.get(lx.id)
        if not _is_visible(club_id, lx.id, cfg):
            continue
        item = build_leixing_item(lx, cfg)
        item['club_enabled'] = True
        enabled.append(item)
    enabled.sort(key=lambda x: (-int(x['paixu'] or 0), x['id']))
    return {
        'club_id': club_id,
        'list': enabled,
        'scope': resolve_club_scope(request),
    }


def build_club_leixing_catalog(request):
    if club_read_blocked(request):
        return {
            'club_id': resolve_club_id_from_request(request),
            'catalog': [],
            'scope_error': CLUB_READ_SCOPE_MSG,
        }
    club_id = resolve_club_id_from_request(request)
    cfg_map = _config_map(club_id)
    catalog = []
    for lx in ShangpinLeixing.query.exclude(shenhezhuangtai=2).order_by('-paixu', 'id'):
        cfg = cfg_map.get(lx.id)
        if _is_visible(club_id, lx.id, cfg):
            continue
        catalog.append({
            'id': lx.id,
            'jieshao': lx.jieshao or '',
            'tupian_url': lx.tupian_url or '',
            'bankuai_id': lx.bankuai_id,
        })
    return {'club_id': club_id, 'catalog': catalog}


def enable_leixing_for_club(request, leixing_id, paixu=0):
    if club_write_blocked(request):
        return None, CLUB_WRITE_SCOPE_MSG
    club_id = club_id_for_write(request)
    try:
        lx = ShangpinLeixing.query.get(id=leixing_id)
    except ShangpinLeixing.DoesNotExist:
        return None, '商品类型不存在'
    if lx.shenhezhuangtai == 2:
        return None, '该类型为审核专用，不可上架'

    row, _ = ClubShangpinLeixingConfig.query.get_or_create(
        club_id=club_id,
        leixing_id=leixing_id,
        defaults={'is_enabled': True, 'paixu': int(paixu or lx.paixu or 0)},
    )
    row.is_enabled = True
    if paixu:
        row.paixu = int(paixu)
    row.save(update_fields=['is_enabled', 'paixu', 'UpdateTime'])
    return {'leixing_id': leixing_id}, None


def disable_leixing_for_club(request, leixing_id):
    if club_write_blocked(request):
        return None, CLUB_WRITE_SCOPE_MSG
    club_id = club_id_for_write(request)
    row, _ = ClubShangpinLeixingConfig.query.get_or_create(
        club_id=club_id,
        leixing_id=leixing_id,
        defaults={'is_enabled': False},
    )
    row.is_enabled = False
    row.save(update_fields=['is_enabled', 'UpdateTime'])
    return {'leixing_id': leixing_id}, None


def set_leixing_show_price(request, leixing_id, show_price):
    """按俱乐部商品类型开关：是否强制展示订单价格。"""
    if club_write_blocked(request):
        return None, CLUB_WRITE_SCOPE_MSG
    club_id = club_id_for_write(request)
    try:
        lx = ShangpinLeixing.query.get(id=leixing_id)
    except ShangpinLeixing.DoesNotExist:
        return None, '商品类型不存在'

    row, _ = ClubShangpinLeixingConfig.query.get_or_create(
        club_id=club_id,
        leixing_id=int(leixing_id),
        defaults={
            'is_enabled': club_id == CLUB_ID_DEFAULT,
            'paixu': int(lx.paixu or 0),
            'show_price': False,
        },
    )
    row.show_price = bool(show_price)
    row.save(update_fields=['show_price', 'UpdateTime'])
    return {
        'leixing_id': int(leixing_id),
        'show_price': bool(row.show_price),
    }, None


def upload_leixing_icon(request, leixing_id, file_obj):
    if club_write_blocked(request):
        return None, CLUB_WRITE_SCOPE_MSG
    club_id = club_id_for_write(request)
    if not ShangpinLeixing.query.filter(id=leixing_id).exists():
        return None, '商品类型不存在'
    ok, msg = validate_image(file_obj)
    if not ok:
        return None, msg

    ext = os.path.splitext(file_obj.name)[1].lower() or '.png'
    if ext not in ('.png', '.jpg', '.jpeg', '.webp'):
        ext = '.png'
    oss_path = f'club/{club_id}/miniapp/shangpinleixing/{leixing_id}_{uuid.uuid4().hex}{ext}'

    row, _ = ClubShangpinLeixingConfig.query.get_or_create(
        club_id=club_id,
        leixing_id=leixing_id,
        defaults={'is_enabled': club_id == CLUB_ID_DEFAULT},
    )
    if row.tupian_url and row.tupian_url != oss_path:
        delete_from_oss(row.tupian_url)
    if not upload_to_oss(file_obj, oss_path):
        return None, '图片上传失败'
    row.tupian_url = oss_path
    row.save(update_fields=['tupian_url', 'UpdateTime'])
    return {'leixing_id': leixing_id, 'tupian_url': oss_path}, None


def copy_club_shangpin_leixing_config(template_club_id, new_club_id):
    for row in ClubShangpinLeixingConfig.query.filter(club_id=template_club_id):
        if ClubShangpinLeixingConfig.query.filter(
            club_id=new_club_id, leixing_id=row.leixing_id,
        ).exists():
            continue
        ClubShangpinLeixingConfig.query.create(
            club_id=new_club_id,
            leixing_id=row.leixing_id,
            is_enabled=row.is_enabled,
            tupian_url='',  # 新俱乐部需自行上传图标，不复制 OSS 路径
            paixu=row.paixu,
            show_price=bool(getattr(row, 'show_price', False)),
        )
