
from app.core.crud import CRUDBase
from app.schemas.weixin import (
    WeixinUserCreate,
    WeixinUserUpdate,
)

from app.models.weixin import WeixinUser
from app.schemas.weixin import WeixinUserBindInfo

from some_sdk.services.binder import feishu_client, xy_client
from some_sdk.feishu_sdk.biz.doc import search_file_record
from some_sdk.xingyun_sdk.apis.channel import list_channel_group, list_channel_group_user_list, set_online_staff

import logging
logger = logging.getLogger(__name__)

from datetime import datetime

def split_generator(iterable, chunk_size=50):
    """
    将可迭代对象拆分为多个子列表
    """
    chunk = []
    for item in iterable:
        chunk.append(item)
        if len(chunk) == chunk_size:
            yield chunk
            chunk = []
    if chunk:
        yield chunk

class WeixinUserController(CRUDBase[WeixinUser, WeixinUserCreate, WeixinUserUpdate]):
    def __init__(self):
        super().__init__(model=WeixinUser)

    async def update_from_group(self, internal_members: list[dict]):
        # 同步更新数据库
        member_dict = {}
        for member in internal_members:
            member = member.copy()
            userid = member.get('userid', None)
            member['alias'] = member.pop('name', None)
            member_dict[userid] = member
        
        member_list = await self.model.filter(userid__in=member_dict.keys())

        update_list = []
        update_fileds = ['alias', 'role', 'erp_id', 'erp_name']

        history = {}
        for member in member_list:
            member_info = member_dict.pop(member.userid, history.get(member.userid, {}))
            if member.role in ['owner', 'admin', 'follower']:
                continue
            if not member_info: continue
            history[member.userid] = member_info

            updated = {}
            for field in update_fileds:
                old_value = getattr(member, field)
                if field not in member_info:
                    continue
                value = member_info.get(field)
                if old_value != value:
                    setattr(member, field, value)
                    updated[f'{field}:{str(old_value)}'] = value
            if updated:
                logger.info(f'用户 {member.userid} 更新关系为 {updated}')
                update_list.append(member)
        if update_list:
            await self.model.bulk_update(update_list, fields=update_fileds)

        # 新增用户
        create_list = []
        for userid, member_info in member_dict.items():
            create_list.append(WeixinUser(
                **member_info,
                name=member_info.get('alias'),
            ))
        if create_list:
            await self.model.bulk_create(create_list)
        
        return {
            'update_count': len(update_list),
            'create_count': len(create_list),
        }
    
    
    async def bind_user(self, user_in: WeixinUserBindInfo):
        if not user_in.userid:
            raise ValueError("用户ID不能为空")
        if user_in.erp_id == 0:
            del user_in.erp_id

        user = await self.model.filter(userid=user_in.userid).first()
        if not user:
            await self.create({**user_in.model_dump(exclude_unset=True), 'name': user_in.username})
            return {}
        await self.model.filter(userid=user_in.userid).update(**user_in.model_dump(exclude_unset=True))

    async def set_user_online(self, class_type: str, date: datetime):
        daysTimestamp = lambda nowStamp, days: nowStamp + days * 24 * 60 * 60 * 1000
        formatDate = lambda ts: datetime.fromtimestamp(ts / 1000).strftime('%Y-%m-%d')
        
        today = int(date.timestamp() * 1000)
        logger.info(f'设置 {formatDate(today)} 班次为 {class_type} 的员工为在线状态')
        yestoday = daysTimestamp(today, -1)
        tomorrow = daysTimestamp(today, 1)

        # 查询日期为 yestoday 到 后天 之间的所有记录
        resp = search_file_record(
            feishu_client,
            app_token="V4qebMG2kamCWMslJmdcQMbtngW",
            table_id="tblKgjc3F2jZ2inC",
            filter={
                "conjunction": "and",
                "conditions": [{
                    "field_name": "日期",
                    "operator": "isGreater",
                    "value": ["ExactDate", yestoday]
                },{
                    "field_name": "日期",
                    "operator": "isLess",
                    "value": ["ExactDate", daysTimestamp(today, 2)]
                }]
            },
        )
        
        set_result = {}
        current_class = (class_type, today)
        next_class = ('早班', tomorrow) if class_type == '晚班' else ('晚班', today)

        current_class_mapping = {}
        next_class_mapping = {}
        async for data in resp:
            user = data.get('data', {})
            user_online = ((user.get('班次') or '')[:2], user.get('日期', ''))
            # logger.info(f'用户{user.get("接量成员", "")} 在线时间为{user_online} 当前班次为{current_class} 下一班次为{next_class}')
            class_group = user.get('组别', '')
            class_mapping = None
            # 当前班次
            if user_online == current_class:
                class_mapping = current_class_mapping
                set_result[class_group] = {"接量成员": user.get('接量成员', '')}
            # 下一班次
            elif user_online == next_class:
                class_mapping = next_class_mapping
            if class_mapping is None:
                continue
            
            if user.get('id', ''): 
                class_mapping.setdefault(class_group, [])
                class_mapping[class_group].append(user.get('id', ''))

        assert current_class_mapping, f"根据日期{current_class[1]} {formatDate(current_class[1])}没有找到班次为{class_type}的员工"
        logger.info(f'根据日期{current_class[1]} {formatDate(current_class[1])} 找到班次为{class_type}的员工: {current_class_mapping} {set_result}')
        if next_class_mapping:
            logger.info(f'根据日期{next_class[1]} {formatDate(next_class[1])} 找到班次为{next_class[0]}的员工: {next_class_mapping}')
        
        group_list = list_channel_group(xy_client)
        async for group in group_list:
            title = group.get("title", "")
            if title not in current_class_mapping:
                continue

            set_result[title] = set_result.get(title) or {}
            try:
                user_list = list_channel_group_user_list(xy_client, groupId=group.get("id", ""))

                huomaList = []
                async for user in user_list:
                    huomaList.append(user.get('id'))
                
                if not huomaList:
                    logger.error(f'组 {title} {group.get("id", "")} 中没有员工')
                    continue

                is_faild, is_success = [], []
                # 按照50个一组设置在线状态
                for i in range(0, len(huomaList), 50):
                    result = await set_online_staff(xy_client, allDayUserIds=','.join(current_class_mapping[title]), huomaList=huomaList[i:i+50])

                    is_faild += list(filter(lambda x: x.get('errorMsg', ''), result.get('data', [])))
                    is_success += list(filter(lambda x: x.get('success', True), result.get('data', [])))

                is_faild = set(is_faild)
                if is_faild: logger.error(f'设置失败的员工: {is_faild}')
                else: logger.info(f'全部员工设置成功')

                set_result[title] = {
                    'success': len(is_success),
                    'fail': len(is_faild),
                    **set_result[title]
                }
            except Exception as e:
                logger.exception(f'设置群 {group.get("id", "")} 中员工 {huomaList} 为在线状态失败: {e}')
            
        return set_result, next_class_mapping
    
weixin_user_controller = WeixinUserController()
