"""业务用户模型——继承 SDK 抽象基类，添加本服务业务字段和方法

本文件位于 users app（业务层），不属于 gvsdsdk SDK 包。
User 类继承自 gvsdsdk.models.User（抽象基类），添加业务字段和方法。

业务字段：
    - UserUID：用户业务ID（7位）
    - OpenID / UnionID：微信认证字段
    - Avatar：头像路径
    - Phone / PhoneVerified：手机号及认证状态
    - IP：来访用户IP
    - IsStaff / IsSuperuser：Django auth 框架必需

业务方法：
    - UserType：通过 UserRole 推断用户类型（admin/kefu/guanshi/...）
    - PaymentQRCode / PaymentAccount：收款信息（存于 UserSensitiveData）
    - HasRole：检查用户是否拥有指定角色
"""

import datetime as _datetime
from django.db import models
from gvsdsdk.models import User as _UserBase, UserManager
from gvsdsdk.models import UserRole, Role


class User(_UserBase):
    """业务用户表——继承 SDK 抽象 User，添加本服务业务字段和方法

    映射与 SDK 相同的 User 表（db_table='User'），但额外包含：
    - 微信认证字段（OpenID, UnionID）
    - 业务标识字段（UserUID, Avatar, Phone, IP）
    - Django auth 扩展字段（IsStaff, IsSuperuser）
    - 业务方法（UserType, PaymentQRCode, PaymentAccount, HasRole）
    """

    # === 本地业务字段 ===
    UserUID = models.CharField(max_length=7, unique=True, db_column='UserUID', verbose_name='用户业务ID', null=True, blank=True)
    OpenID = models.CharField(max_length=64, unique=True, db_column='OpenID', verbose_name='微信OpenID', null=True, blank=True)
    UnionID = models.CharField(max_length=64, db_column='UnionID', verbose_name='微信UnionID', null=True, blank=True)
    Avatar = models.CharField(max_length=500, default='a_long/morentouxiang.jpg', db_column='Avatar', verbose_name='头像')
    Phone = models.CharField(max_length=11, db_column='Phone', verbose_name='手机号', null=True, blank=True)
    PhoneVerified = models.BooleanField(default=False, db_column='PhoneVerified', verbose_name='手机号是否已认证')
    IP = models.CharField(max_length=50, db_column='IP', verbose_name='来访用户IP', null=True, blank=True)
    IsStaff = models.BooleanField(default=False, db_column='IsStaff', verbose_name='是否员工')
    IsSuperuser = models.BooleanField(default=False, db_column='IsSuperuser', verbose_name='是否超级用户')
    ClubID = models.CharField(
        max_length=16, default='', db_column='ClubID', verbose_name='所属俱乐部',
        null=True, blank=True,
    )

    objects = UserManager()

    # Django auth 框架必需
    USERNAME_FIELD = 'UserName'
    REQUIRED_FIELDS = ['UserUID']

    class Meta:
        managed = True
        app_label = 'users'
        db_table = 'User'
        verbose_name = '用户'
        verbose_name_plural = '用户'
        indexes = [
            models.Index(fields=['UserUID']),
            models.Index(fields=['OpenID']),
        ]

    # ── 用户类型推断（通过 UserRole → Role 推断，带实例缓存）──

    @property
    def UserType(self):
        """用户类型 — 通过 UserRole 推断（带实例缓存）"""
        if hasattr(self, '_cached_user_type'):
            return self._cached_user_type
        try:
            role_uuids = UserRole.objects.filter(
                UserUUID=self.UserUUID
            ).values_list('RoleUUID', flat=True)
            role_names = set(
                Role.objects.filter(RoleUUID__in=role_uuids)
                .values_list('RoleName', flat=True)
            )
            # 优先级：管理员 > 客服 > 负责人 > 组长 > 审核官 > 商家 > 打手
            for rn in role_names:
                if '管理员' in rn or 'admin' in rn.lower():
                    self._cached_user_type = 'admin'
                    return 'admin'
            for rn in role_names:
                if '客服' in rn or 'kefu' in rn.lower():
                    self._cached_user_type = 'kefu'
                    return 'kefu'
            for rn in role_names:
                if '负责人' in rn or '管事' in rn or 'guanshi' in rn.lower():
                    self._cached_user_type = 'guanshi'
                    return 'guanshi'
            for rn in role_names:
                if '组长' in rn or 'zuzhang' in rn.lower():
                    self._cached_user_type = 'zuzhang'
                    return 'zuzhang'
            for rn in role_names:
                if '审核' in rn or 'shenheguan' in rn.lower():
                    self._cached_user_type = 'shenheguan'
                    return 'shenheguan'
            for rn in role_names:
                if '商家' in rn or 'shangjia' in rn.lower():
                    self._cached_user_type = 'shop'
                    return 'shop'
            for rn in role_names:
                if '打手' in rn or 'dashou' in rn.lower():
                    self._cached_user_type = 'dashou'
                    return 'dashou'
            self._cached_user_type = 'normal'
            return 'normal'
        except Exception:
            self._cached_user_type = 'normal'
            return 'normal'

    # ── 收款信息（存于 UserSensitiveData）──

    @property
    def PaymentQRCode(self):
        """收款码图片（存于 UserSensitiveData.zhifu）"""
        try:
            return self.sensitive_data.zhifu
        except Exception:
            return ''

    @PaymentQRCode.setter
    def PaymentQRCode(self, value):
        try:
            sd = self.sensitive_data
            sd.zhifu = value
            sd.save(update_fields=['zhifu'])
        except Exception:
            pass

    @property
    def PaymentAccount(self):
        """收款账号（存于 UserSensitiveData.skzhanghao）"""
        try:
            return self.sensitive_data.skzhanghao
        except Exception:
            return ''

    @PaymentAccount.setter
    def PaymentAccount(self, value):
        try:
            sd = self.sensitive_data
            sd.skzhanghao = value
            sd.save(update_fields=['skzhanghao'])
        except Exception:
            pass

    # ── 关联扩展表快捷访问 ──
    # DashouProfile / ShopProfile / GuanshiProfile / BossProfile /
    # AdminProfile / KefuProfile / ZuzhangProfile / ShenheguanProfile
    # 均由 OneToOneField related_name 直接提供反向关联访问

    def HasRole(self, role_code):
        """检查用户是否拥有指定角色（支持角色名或 UserType 值）"""
        ROLE_CODE_MAP = {
            'admin': '管理员', 'kefu': '客服', 'guanshi': '负责人',
            'zuzhang': '组长', 'shenheguan': '审核官', 'shop': '商家',
            'dashou': '打手', 'normal': '消费者',
        }
        target = ROLE_CODE_MAP.get(role_code, role_code)
        try:
            role_uuids = UserRole.objects.filter(
                UserUUID=self.UserUUID
            ).values_list('RoleUUID', flat=True)
            return Role.objects.filter(
                RoleUUID__in=role_uuids, RoleName=target
            ).exists()
        except Exception:
            return False
