package shop.alien.store.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import shop.alien.entity.result.R;
import shop.alien.entity.store.LawyerUser;
import shop.alien.entity.store.LifeUser;
import shop.alien.entity.store.LifeUserPushDevice;
import shop.alien.entity.store.PushDeviceOwnerType;
import shop.alien.entity.store.StoreUser;
import shop.alien.entity.store.UserLoginInfo;
import shop.alien.mapper.LawyerUserMapper;
import shop.alien.mapper.LifeUserMapper;
import shop.alien.mapper.LifeUserPushDeviceMapper;
import shop.alien.mapper.StoreUserMapper;
import shop.alien.store.dto.LifeUserPushBindDto;
import shop.alien.store.service.LifeUserPushDeviceService;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class LifeUserPushDeviceServiceImpl implements LifeUserPushDeviceService {

    private final LifeUserPushDeviceMapper lifeUserPushDeviceMapper;
    private final LifeUserMapper lifeUserMapper;
    private final StoreUserMapper storeUserMapper;
    private final LawyerUserMapper lawyerUserMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<String> bind(UserLoginInfo login, LifeUserPushBindDto dto) {
        if (login == null || login.getUserId() <= 0) {
            return R.fail("请先登录");
        }
        PushDeviceOwnerType ownerType = PushDeviceOwnerType.fromJwtUserType(login.getType());
        if (ownerType == null) {
            return R.fail("当前登录类型不支持绑定推送设备");
        }
        if (dto == null || StringUtils.isBlank(dto.getPushClientId())) {
            return R.fail("pushClientId 不能为空");
        }
        String cid = StringUtils.trim(dto.getPushClientId());
        if (cid.length() > 128) {
            return R.fail("pushClientId 过长");
        }

        R<String> valid = validateOwnerExists(ownerType, login.getUserId());
        if (valid != null) {
            return valid;
        }

        LifeUserPushDevice existing = lifeUserPushDeviceMapper.selectOne(
                new LambdaQueryWrapper<LifeUserPushDevice>()
                        .eq(LifeUserPushDevice::getPushClientId, cid)
                        .last("LIMIT 1"));

        Date now = new Date();
        String platform = StringUtils.trimToNull(dto.getPlatform());
        String appId = StringUtils.trimToNull(dto.getDcloudAppId());
        if (platform != null && platform.length() > 32) {
            platform = platform.substring(0, 32);
        }
        if (appId != null && appId.length() > 64) {
            appId = appId.substring(0, 64);
        }

        String typeCode = ownerType.getCode();
        if (existing != null) {
            existing.setUserId(login.getUserId());
            existing.setOwnerType(typeCode);
            existing.setPlatform(platform);
            existing.setDcloudAppId(appId);
            existing.setUpdatedTime(now);
            lifeUserPushDeviceMapper.updateById(existing);
            log.info("更新推送设备绑定, ownerType={}, userId={}, cid={}", typeCode, login.getUserId(), cid);
        } else {
            LifeUserPushDevice row = new LifeUserPushDevice();
            row.setUserId(login.getUserId());
            row.setOwnerType(typeCode);
            row.setPushClientId(cid);
            row.setPlatform(platform);
            row.setDcloudAppId(appId);
            row.setCreatedTime(now);
            row.setUpdatedTime(now);
            lifeUserPushDeviceMapper.insert(row);
            log.info("新增推送设备绑定, ownerType={}, userId={}, cid={}", typeCode, login.getUserId(), cid);
        }
        return R.success("绑定成功");
    }

    /**
     * @return null 表示校验通过
     */
    private R<String> validateOwnerExists(PushDeviceOwnerType ownerType, int businessUserId) {
        switch (ownerType) {
            case USER:
                LifeUser user = lifeUserMapper.selectById(businessUserId);
                if (user == null) {
                    return R.fail("用户不存在");
                }
                break;
            case STORE:
                StoreUser su = storeUserMapper.selectById(businessUserId);
                if (su == null || (su.getDeleteFlag() != null && su.getDeleteFlag() != 0)) {
                    return R.fail("门店用户不存在或已删除");
                }
                break;
            case LAWYER:
                LawyerUser lu = lawyerUserMapper.selectById(businessUserId);
                if (lu == null || (lu.getDeleteFlag() != null && lu.getDeleteFlag() != 0)) {
                    return R.fail("律师用户不存在或已删除");
                }
                break;
            default:
                return R.fail("不支持的归属类型");
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<String> unbindByCid(UserLoginInfo login, String pushClientId) {
        if (login == null || login.getUserId() <= 0) {
            return R.fail("请先登录");
        }
        PushDeviceOwnerType ownerType = PushDeviceOwnerType.fromJwtUserType(login.getType());
        if (ownerType == null) {
            return R.fail("当前登录类型不支持解绑推送设备");
        }
        if (StringUtils.isBlank(pushClientId)) {
            return R.fail("pushClientId 不能为空");
        }
        String cid = StringUtils.trim(pushClientId);
        int n = lifeUserPushDeviceMapper.delete(
                new LambdaQueryWrapper<LifeUserPushDevice>()
                        .eq(LifeUserPushDevice::getOwnerType, ownerType.getCode())
                        .eq(LifeUserPushDevice::getUserId, login.getUserId())
                        .eq(LifeUserPushDevice::getPushClientId, cid));
        if (n <= 0) {
            return R.fail("未找到绑定记录");
        }
        return R.success("解绑成功");
    }

    @Override
    public R<List<LifeUserPushDevice>> listMine(UserLoginInfo login) {
        if (login == null || login.getUserId() <= 0) {
            return R.fail("请先登录");
        }
        PushDeviceOwnerType ownerType = PushDeviceOwnerType.fromJwtUserType(login.getType());
        if (ownerType == null) {
            return R.fail("当前登录类型不支持查询推送设备");
        }
        List<LifeUserPushDevice> list = lifeUserPushDeviceMapper.selectList(
                new LambdaQueryWrapper<LifeUserPushDevice>()
                        .eq(LifeUserPushDevice::getOwnerType, ownerType.getCode())
                        .eq(LifeUserPushDevice::getUserId, login.getUserId())
                        .orderByDesc(LifeUserPushDevice::getUpdatedTime));
        return R.data(list);
    }

    @Override
    public List<String> listPushClientIdsByUserId(int userId, String ownerType) {
        if (userId <= 0) {
            return Collections.emptyList();
        }
        PushDeviceOwnerType ot = PushDeviceOwnerType.fromCode(ownerType);
        if (ot == null) {
            return Collections.emptyList();
        }
        List<LifeUserPushDevice> list = lifeUserPushDeviceMapper.selectList(
                new LambdaQueryWrapper<LifeUserPushDevice>()
                        .eq(LifeUserPushDevice::getOwnerType, ot.getCode())
                        .eq(LifeUserPushDevice::getUserId, userId)
                        .select(LifeUserPushDevice::getPushClientId));
        if (list == null || list.isEmpty()) {
            return Collections.emptyList();
        }
        return list.stream()
                .map(LifeUserPushDevice::getPushClientId)
                .filter(StringUtils::isNotBlank)
                .distinct()
                .collect(Collectors.toList());
    }
}
