package com.czg.service.account.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.czg.account.dto.pagepath.PagePathPermissionAddDTO;
import com.czg.account.dto.staff.ShopStaffAddDTO;
import com.czg.account.dto.staff.ShopStaffEditDTO;
import com.czg.account.dto.staff.ShopStaffRemoveDTO;
import com.czg.account.entity.*;
import com.czg.account.service.*;
import com.czg.exception.CzgException;
import com.czg.sa.StpKit;
import com.czg.service.account.mapper.ShopStaffMapper;
import com.czg.utils.PageUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

/**
 * 店铺员工 服务层实现。
 *
 * @author Administrator
 * @since 2025-02-10
 */
@DubboService
public class ShopStaffServiceImpl extends ServiceImpl<ShopStaffMapper, ShopStaff> implements ShopStaffService {
    @Resource
    private SysUserService sysUserService;
    @Resource
    private SysUsersRolesService sysUsersRolesService;
    @Resource
    private SysRoleService sysRoleService;
    @Resource
    private ShopPermissionService shopPermissionService;
    @Resource
    private ShopStaffPermissionService shopStaffPermissionService;
    @Resource
    private ShopStaffPagePermissionService pagePermissionService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(ShopStaffAddDTO shopStaffAddDTO) {
        SysUser sysUser = sysUserService.addUser(shopStaffAddDTO.getName(), StpKit.USER.getLoginIdAsString() + "@" + shopStaffAddDTO.getAccountName(),
                shopStaffAddDTO.getAccountPwd(), shopStaffAddDTO.getPhone(), shopStaffAddDTO.getRoleId());
        ShopStaff shopStaff = BeanUtil.copyProperties(shopStaffAddDTO, ShopStaff.class);
        shopStaff.setShopId(StpKit.USER.getLoginIdAsLong());
        shopStaff.setId(sysUser.getId());
        save(shopStaff);

        // 权限添加
        if (shopStaffAddDTO.getShopPermissionIds() != null && !shopStaffAddDTO.getShopPermissionIds().isEmpty()) {
            addPermission(shopStaff, shopStaffAddDTO.getShopPermissionIds());
        }

        if (shopStaffAddDTO.getPagePathIdList() != null && !shopStaffAddDTO.getPagePathIdList().isEmpty()) {
            PagePathPermissionAddDTO pagePathPermissionAddDTO = new PagePathPermissionAddDTO();
            pagePathPermissionAddDTO.setPagePathIdList(shopStaffAddDTO.getPagePathIdList());
            pagePathPermissionAddDTO.setStaffId(shopStaff.getId());
            pagePermissionService.add(StpKit.USER.getShopId(), pagePathPermissionAddDTO);
        }
        return true;
    }

    @Override
    public Boolean edit(ShopStaffEditDTO shopStaffEditDTO) {
        long sysUserId = StpKit.USER.getLoginIdAsLong();
        ShopStaff shopStaff = queryChain().eq(ShopStaff::getShopId, sysUserId).eq(ShopStaff::getId, shopStaffEditDTO.getId()).one();
        if (shopStaff == null) {
            throw new CzgException("员工账户不存在");
        }
        if (shopStaffEditDTO.getRoleId() != null) {
            sysUsersRolesService.updateRole(shopStaff.getId(), shopStaffEditDTO.getRoleId());
        }

        if (StrUtil.isNotBlank(shopStaffEditDTO.getAccountPwd()) && !"*******".equals(shopStaffEditDTO.getAccountPwd())) {
            sysUserService.updateSysUserPwd(shopStaff.getId(), shopStaffEditDTO.getAccountPwd());
        }

        SysUser sysUser = sysUserService.getById(shopStaff.getId());
        if (StrUtil.isNotBlank(shopStaffEditDTO.getPhone()) && !shopStaffEditDTO.getPhone().equals(sysUser.getPhone())) {
            sysUser.setPhone(shopStaffEditDTO.getPhone());
        }

        String accountName = StpKit.USER.getLoginIdAsString() + "@" + shopStaffEditDTO.getAccountName();
        if (StrUtil.isNotBlank(shopStaffEditDTO.getAccountName()) && !accountName.equals(sysUser.getAccount())) {
            long count = sysUserService.count(new QueryWrapper().eq(SysUser::getAccount, accountName).ne(SysUser::getId, sysUser.getId()));
            if (count > 0) {
                throw new CzgException("此账户名已存在");
            }
            sysUser.setAccount(accountName);
        }
        sysUserService.updateById(sysUser);


        shopStaffEditDTO.setCode(StrUtil.isBlank(shopStaffEditDTO.getCode()) ? null : shopStaffEditDTO.getCode());
        BeanUtil.copyProperties(shopStaffEditDTO, shopStaff);
        updateById(shopStaff);

        if (shopStaffEditDTO.getShopPermissionIds() != null) {
            shopStaffPermissionService.updateChain().eq(ShopStaffPermission::getStaffId, shopStaff.getId())
                    .eq(ShopStaffPermission::getShopId, StpKit.USER.getShopId()).eq(ShopStaffPermission::getUserId, shopStaff.getId()).remove();
            // 权限添加
            if (!shopStaffEditDTO.getShopPermissionIds().isEmpty()) {
                addPermission(shopStaff, shopStaffEditDTO.getShopPermissionIds());
            }
        }

        if (shopStaffEditDTO.getPagePathIdList() != null) {
            PagePathPermissionAddDTO pagePathPermissionAddDTO = new PagePathPermissionAddDTO();
            pagePathPermissionAddDTO.setPagePathIdList(shopStaffEditDTO.getPagePathIdList());
            pagePathPermissionAddDTO.setStaffId(shopStaff.getId());
            pagePermissionService.add(StpKit.USER.getShopId(), pagePathPermissionAddDTO);
        }
        return true;
    }

    private void addPermission(ShopStaff shopStaff, List<Long> shopPermissionIds) {
        long count = shopPermissionService.queryChain().in(ShopPermission::getId, new HashSet<>(shopPermissionIds)).count();
        if (count != shopPermissionIds.size()) {
            throw new CzgException("存在不存在的权限");
        }

        ArrayList<ShopStaffPermission> staffPermissions = new ArrayList<>();
        shopPermissionIds.forEach(item -> {
            ShopStaffPermission shopStaffPermission = new ShopStaffPermission();
            shopStaffPermission.setStaffId(shopStaff.getId());
            shopStaffPermission.setShopId(StpKit.USER.getShopId());
            shopStaffPermission.setUserId(shopStaff.getId());
            shopStaffPermission.setPermissionId(item);
            staffPermissions.add(shopStaffPermission);
        });
        shopStaffPermissionService.saveBatch(staffPermissions);
    }

    @Override
    public Page<ShopStaff> get(String name, String code) {
        QueryWrapper queryWrapper = new QueryWrapper();
        if (StrUtil.isNotBlank(name)) {
            queryWrapper.like(ShopStaff::getName, name);
        }

        if (StrUtil.isNotBlank(code)) {
            queryWrapper.like(ShopStaff::getCode, code);
        }

        queryWrapper.eq(ShopStaff::getShopId, StpKit.USER.getLoginIdAsLong());
        Page<ShopStaff> page = page(PageUtil.buildPage(), queryWrapper);
        for (ShopStaff record : page.getRecords()) {
            SysUsersRoles sysUsersRoles = sysUsersRolesService.getOne(new QueryWrapper().eq(SysUsersRoles::getUserId, record.getId()));
            if (sysUsersRoles != null) {
                record.setRoleId(sysUsersRoles.getRoleId());
                SysRole role = sysRoleService.getById(sysUsersRoles.getRoleId());
                record.setRoleName(role == null ? "" : role.getName());
            }
        }
        return page;
    }

    @Override
    public Boolean delete(ShopStaffRemoveDTO shopStaffRemoveDTO) {
        long sysUserId = StpKit.USER.getLoginIdAsLong();
        ShopStaff shopStaff = queryChain().eq(ShopStaff::getShopId, sysUserId).eq(ShopStaff::getId, shopStaffRemoveDTO.getId()).one();
        if (shopStaff == null) {
            throw new CzgException("员工账号不存在");
        }

        sysUserService.removeUserAndRole(shopStaff.getId());
        return removeById(shopStaff.getId());
    }

    @Override
    public List<Long> permission(Long id) {
        return shopStaffPermissionService.getPermissionByStaffId(StpKit.USER.getShopId(), id, id).stream().map(ShopPermission::getId).toList();
    }

    @Override
    public ShopStaff detail(Long shopId, Long id) {
        ShopStaff shopStaff = queryChain().eq(ShopStaff::getId, id).eq(ShopStaff::getShopId, shopId).one();
        if (shopStaff == null) {
            throw new CzgException("员工不存在");
        }

        SysUsersRoles sysUsersRoles = sysUsersRolesService.getOne(new QueryWrapper().eq(SysUsersRoles::getUserId, shopStaff.getId()));
        shopStaff.setRoleId(sysUsersRoles == null ? null : sysUsersRoles.getRoleId());
        SysUser sysUser = sysUserService.getById(shopStaff.getId());
        shopStaff.setAccountName(StrUtil.subAfter(sysUser.getAccount(), "@", true));
        shopStaff.setAccountPwd("*******");
        shopStaff.setPhone(sysUser.getPhone());
        return shopStaff;
    }
}
