package com.crm.ucard.service.impl;

import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.dto.base.BaseResultDto;
import com.crm.rely.backend.core.dto.base.PageDto;
import com.crm.rely.backend.core.dto.base.ResultWithPagerDto;
import com.crm.rely.backend.core.dto.ucard.CardPermissionDto;
import com.crm.rely.backend.core.entity.custom.info.CustomInfoEntity;
import com.crm.rely.backend.core.entity.ucard.CardPermissionAddEntity;
import com.crm.rely.backend.core.entity.ucard.CardPermissionDeleteEntity;
import com.crm.rely.backend.core.entity.ucard.CardPermissionPageEntity;
import com.crm.rely.backend.core.entity.ucard.CardPermissionUpdateEntity;
import com.crm.rely.backend.core.pojo.table.ucard.CardPermissionTable;
import com.crm.rely.backend.exception.ServiceException;
import com.crm.ucard.dao.mapper.CardPermissionMapper;
import com.crm.ucard.dao.repository.CardPermissionRepository;
import com.crm.ucard.service.UcardPermissionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.util.stream.Collectors;

@Slf4j
@Service
public class UcardPermissionServiceImpl implements UcardPermissionService {

    @Autowired
    private CardPermissionRepository permissionRepository;
    @Autowired
    private CardPermissionMapper permissionMapper;

    /**
     * 校验正则表达式格式
     *
     * @param regexp 待校验的正则表达式
     * @return 是否符合要求的格式
     */
    private static boolean isValidRegexpFormat(String regexp) {
        try {
            Pattern.compile(regexp);
            return true;
        } catch (PatternSyntaxException e) {
            return false;
        }
    }

    /**
     * 新增权限规则
     */
    @Override
    public BaseResultDto addPermission(CardPermissionAddEntity entity) throws ServiceException {
        if (StringUtils.isEmpty(entity.getCIdRegexp()) && StringUtils.isEmpty(entity.getEmailRegexp())
                && StringUtils.isEmpty(entity.getPhoneRegexp()) && StringUtils.isEmpty(entity.getCountryCodes())
                && StringUtils.isEmpty(entity.getStateEnNames()) && StringUtils.isEmpty(entity.getCityEnNames())) {
            throw new ServiceException("权限规则不能全部为空");
        }
        // 校验 regexp 字段格式
        if (StringUtils.isNotEmpty(entity.getCIdRegexp()) && !isValidRegexpFormat(entity.getCIdRegexp())) {
            throw new ServiceException("CID正则表达式格式不正确");
        }
        if (StringUtils.isNotEmpty(entity.getEmailRegexp()) && !isValidRegexpFormat(entity.getEmailRegexp())) {
            throw new ServiceException("邮箱正则表达式格式不正确");
        }
        if (StringUtils.isNotEmpty(entity.getPhoneRegexp()) && !isValidRegexpFormat(entity.getPhoneRegexp())) {
            throw new ServiceException("手机号码正则表达式格式不正确");
        }
        CardPermissionTable table = new CardPermissionTable();
        BeanUtils.copyProperties(entity, table);
        permissionRepository.save(table);
        return BaseResultDto.success();
    }

    /**
     * 更新权限规则
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResultDto updatePermission(CardPermissionUpdateEntity entity) throws ServiceException {
        CardPermissionTable table = permissionRepository.getFirstById(entity.getId());
        if (table == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        if (table.getEnableStatus().equals(entity.getEnableStatus())) {
            return BaseResultDto.success();
        }
        BeanUtils.copyProperties(entity, table);
        permissionRepository.save(table);
        return BaseResultDto.success();
    }

    /**
     * 删除权限规则
     */
    @Override
    public BaseResultDto deletePermission(CardPermissionDeleteEntity entity) throws ServiceException {
        permissionRepository.delete(entity.getId());
        return BaseResultDto.success();
    }

    /**
     * 权限分页列表
     */
    @Override
    public ResultWithPagerDto<CardPermissionDto> queryPermissionPageList(CardPermissionPageEntity entity) throws ServiceException {
        try {
            // 获取总数
            Integer count = permissionMapper.countList(entity);
            PageDto pageDto = PageDto.format(entity, count);
            if (count == null || count <= 0) {
                return ResultWithPagerDto.success(pageDto);
            }
            List<CardPermissionDto> dtos = permissionMapper.pageList(entity);

            return ResultWithPagerDto.success(pageDto, dtos);
        } catch (Exception e) {
            log.error("卡权限分页查询失败", e);
            throw new ServiceException("卡权限分页查询失败");
        }
    }

    /**
     * 权限校验
     */
    @Override
    public BaseResultDto permissionVerify(CustomInfoEntity entity) throws ServiceException {
        List<CardPermissionTable> tables = permissionRepository.findByEnableStatus(1);
        if (CollectionUtils.isEmpty(tables)) {
            return BaseResultDto.success(false);
        }
        for (CardPermissionTable table : tables) {
            if (matchData(table, entity)) {
                return BaseResultDto.success(true);
            }
        }
        return BaseResultDto.success(false);
    }


    public boolean matchData(CardPermissionTable table, CustomInfoEntity customInfo) {
        boolean match;
        if (StringUtils.isNotEmpty(table.getCIdRegexp())) {
            match = Pattern.matches(table.getCIdRegexp(), customInfo.getCId().toString());
        } else {
            match = true;
        }
        if (match && StringUtils.isNotEmpty(table.getEmailRegexp())) {
            match = Pattern.matches(table.getEmailRegexp(), customInfo.getEmail());
        }
        if (match && StringUtils.isNotEmpty(table.getPhoneRegexp())) {
            match = Pattern.matches(table.getPhoneRegexp(), customInfo.getPhone());
        }
        if (match && StringUtils.isNotEmpty(table.getCountryCodes())) {
            match = matchListField(customInfo.getCountry().trim(), table.getCountryCodes());
        }
        if (match && StringUtils.isNotEmpty(table.getStateEnNames())) {
            match = matchListField(customInfo.getState().trim(), table.getStateEnNames());
        }
        if (match && StringUtils.isNotEmpty(table.getCityEnNames())) {
            match = matchListField(customInfo.getCity().trim(), table.getCityEnNames());
        }
        return match;
    }

    private boolean matchListField(String value, String listStr) {
        if (value == null || listStr == null) {
            return false;
        }
        List<String> items;
        if (listStr.contains(",")) {
            items = Arrays.stream(listStr.split(","))
                    .map(String::trim)
                    .filter(StringUtils::isNotEmpty).collect(Collectors.toList());
        } else {
            items = Collections.singletonList(listStr.trim());
        }

        return items.contains(value);
    }

}
