package shop.alien.store.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import shop.alien.entity.result.R;
import shop.alien.entity.store.LifeUserPersonalizationSetting;
import shop.alien.mapper.LifeUserPersonalizationSettingMapper;
import shop.alien.store.config.BaseRedisService;
import shop.alien.store.service.LifeUserPersonalizationSettingService;

@Service
@Slf4j
public class LifeUserPersonalizationSettingServiceImpl
        extends ServiceImpl<LifeUserPersonalizationSettingMapper, LifeUserPersonalizationSetting>
        implements LifeUserPersonalizationSettingService {

    /** v2：含 personalHomepageSetting，与 v1 区分以淘汰旧缓存结构 */
    private static final String CACHE_KEY_PREFIX = "alien:store:life:user:personalization:v2:";
    private static final long CACHE_TTL_SECONDS = 7 * 24 * 3600L;

    @Autowired
    private BaseRedisService baseRedisService;

    @Override
    public R<String> add(LifeUserPersonalizationSetting setting) {
        log.info("LifeUserPersonalizationSettingServiceImpl.add, param={}", setting);
        R<String> validated = validateAndApplyFontRule(setting, null);
        if (validated != null) {
            return validated;
        }

        // 设定个人主页设置
        R<String> homepageValidated = validatePersonalHomepageSetting(setting);
        if (homepageValidated != null) {
            return homepageValidated;
        }
        boolean result = this.save(setting);
        if (result) {
            invalidatePersonalizationCache(setting.getUserId());
            return R.success("新增成功");
        }
        return R.fail("新增失败");
    }

    @Override
    public R<String> deleteById(Integer id) {
        log.info("LifeUserPersonalizationSettingServiceImpl.deleteById, id={}", id);
        LifeUserPersonalizationSetting old = id == null ? null : this.getById(id);
        boolean result = this.removeById(id);
        if (result) {
            if (old != null) {
                invalidatePersonalizationCache(old.getUserId());
            }
            return R.success("删除成功");
        }
        return R.fail("删除失败");
    }

    @Override
    public R<String> update(LifeUserPersonalizationSetting setting) {
        log.info("LifeUserPersonalizationSettingServiceImpl.update, param={}", setting);
        LifeUserPersonalizationSetting existing;

        if (setting.getId() != null) {
            existing = this.getById(setting.getId());
            if (existing == null) {
                return R.fail("记录不存在");
            }
            if (setting.getUserId() != null && !setting.getUserId().equals(existing.getUserId())) {
                return R.fail("userId与记录不一致");
            }
        } else if (setting.getUserId() != null) {
            LambdaQueryWrapper<LifeUserPersonalizationSetting> w = new LambdaQueryWrapper<>();
            w.eq(LifeUserPersonalizationSetting::getUserId, setting.getUserId());
            existing = this.getOne(w);
            if (existing == null) {
                LifeUserPersonalizationSetting created = buildDefaultForUser(setting.getUserId());
                R<String> validatedInit = validateAndApplyFontRule(created, null);
                if (validatedInit != null) {
                    return validatedInit;
                }
                try {
                    this.save(created);
                    existing = created;
                } catch (DataIntegrityViolationException e) {
                    log.warn("LifeUserPersonalizationSetting update 并发初始化 userId={}", setting.getUserId(), e);
                    existing = this.getOne(w);
                    if (existing == null) {
                        return R.fail("记录不存在");
                    }
                }
            }
            setting.setId(existing.getId());
        } else {
            return R.fail("id与userId至少填写一个");
        }

        R<String> validated = validateAndApplyFontRule(setting, existing);
        if (validated != null) {
            return validated;
        }
        R<String> homepageValidated = validatePersonalHomepageSetting(setting);
        if (homepageValidated != null) {
            return homepageValidated;
        }
        boolean result = this.updateById(setting);
        if (result) {
            Integer uid = setting.getUserId() != null ? setting.getUserId() : existing.getUserId();
            invalidatePersonalizationCache(uid);
            return R.success("更新成功");
        }
        return R.fail("更新失败");
    }

    /**
     * followSystemFont=1 跟随系统：不采纳请求中的 chatFontLevel，沿用库中已有值（新增时为 0）。
     * followSystemFont=0：chatFontLevel 必须在 0～4（缺省按 0）。
     */
    private R<String> validateAndApplyFontRule(LifeUserPersonalizationSetting incoming, LifeUserPersonalizationSetting existing) {
        int followSys = incoming.getFollowSystemFont() != null
                ? incoming.getFollowSystemFont()
                : (existing != null && existing.getFollowSystemFont() != null ? existing.getFollowSystemFont() : 1);
        if (followSys != 0 && followSys != 1) {
            return R.fail("followSystemFont 只能为 0 或 1");
        }
        if (followSys == 1) {
            Integer keep = existing != null ? existing.getChatFontLevel() : null;
            incoming.setChatFontLevel(keep != null ? keep : 0);
            return null;
        }
        int level = incoming.getChatFontLevel() != null
                ? incoming.getChatFontLevel()
                : (existing != null && existing.getChatFontLevel() != null ? existing.getChatFontLevel() : 0);
        if (level < 0 || level > 4) {
            return R.fail("chatFontLevel 取值 0～4");
        }
        incoming.setChatFontLevel(level);
        return null;
    }

    /** 非空时须为 0 或 1 */
    private static R<String> validatePersonalHomepageSetting(LifeUserPersonalizationSetting incoming) {
        Integer v = incoming.getPersonalHomepageSetting();
        if (v == null) {
            return null;
        }
        if (v != 0 && v != 1) {
            return R.fail("personalHomepageSetting 只能为 0 或 1");
        }
        return null;
    }

    @Override
    public R<LifeUserPersonalizationSetting> getInfoById(Integer id) {
        log.info("LifeUserPersonalizationSettingServiceImpl.getInfoById, id={}", id);
        return R.data(this.getById(id));
    }

    @Override
    public R<LifeUserPersonalizationSetting> getByUserId(Integer userId) {
        log.info("LifeUserPersonalizationSettingServiceImpl.getByUserId, userId={}", userId);
        if (userId == null) {
            return R.fail("userId不能为空");
        }
        LambdaQueryWrapper<LifeUserPersonalizationSetting> w = new LambdaQueryWrapper<>();
        w.eq(LifeUserPersonalizationSetting::getUserId, userId);
        LifeUserPersonalizationSetting one = this.getOne(w);
        if (one != null) {
            return R.data(one);
        }
        LifeUserPersonalizationSetting created = buildDefaultForUser(userId);
        R<String> validated = validateAndApplyFontRule(created, null);
        if (validated != null) {
            return R.fail(validated.getMsg());
        }
        try {
            this.save(created);
            return R.data(created);
        } catch (DataIntegrityViolationException e) {
            log.warn("LifeUserPersonalizationSetting getByUserId 并发插入 userId={}", userId, e);
            LifeUserPersonalizationSetting again = this.getOne(w);
            if (again != null) {
                return R.data(again);
            }
            return R.fail("初始化个性化设置失败");
        }
    }

    @Override
    public LifeUserPersonalizationSetting getByUserIdCacheAside(Integer userId) {
        if (userId == null) {
            return null;
        }
        String key = cacheKey(userId);
        String cached = baseRedisService.getString(key);
        if (StringUtils.isNotEmpty(cached)) {
            try {
                LifeUserPersonalizationSetting parsed = JSON.parseObject(cached, LifeUserPersonalizationSetting.class);
                if (parsed != null) {
                    return parsed;
                }
            } catch (Exception e) {
                log.warn("LifeUserPersonalizationSetting 缓存反序列化失败，删除 key，userId={}", userId, e);
                baseRedisService.delete(key);
            }
        }
        R<LifeUserPersonalizationSetting> r = getByUserId(userId);
        if (!R.isSuccess(r) || r.getData() == null) {
            return null;
        }
        LifeUserPersonalizationSetting data = r.getData();
        try {
            baseRedisService.setString(key, JSON.toJSONString(data), CACHE_TTL_SECONDS);
        } catch (Exception e) {
            log.warn("LifeUserPersonalizationSetting 写入缓存失败，userId={}", userId, e);
        }
        return data;
    }

    @Override
    public boolean shouldSuppressLikeRelatedNotice(Integer userId) {
        if (userId == null) {
            return false;
        }
        LifeUserPersonalizationSetting s = getByUserIdCacheAside(userId);
        if (s == null) {
            return false;
        }
        Integer nrm = s.getNotifyReceiveMessage();
        Integer nl = s.getNotifyLike();
        if (nrm != null && nrm == 0) {
            return true;
        }
        return nrm != null && nrm == 1 && nl != null && nl == 0;
    }

    @Override
    public boolean shouldSuppressFollowRelatedNotice(Integer userId) {
        if (userId == null) {
            return false;
        }
        LifeUserPersonalizationSetting s = getByUserIdCacheAside(userId);
        if (s == null) {
            return false;
        }
        Integer nrm = s.getNotifyReceiveMessage();
        Integer nf = s.getNotifyFollow();
        if (nrm != null && nrm == 0) {
            return true;
        }
        return nrm != null && nrm == 1 && nf != null && nf == 0;
    }

    private static String cacheKey(Integer userId) {
        return CACHE_KEY_PREFIX + userId;
    }

    private void invalidatePersonalizationCache(Integer userId) {
        if (userId == null) {
            return;
        }
        baseRedisService.delete(cacheKey(userId));
    }

    /** 与表默认值一致，便于无记录时落库 */
    private static LifeUserPersonalizationSetting buildDefaultForUser(Integer userId) {
        LifeUserPersonalizationSetting s = new LifeUserPersonalizationSetting();
        s.setUserId(userId);
        s.setPersonalizedRecommendation(1);
        s.setOnlyFollowersComment(1);
        s.setHideFansList(1);
        s.setHideFollowList(1);
        s.setNotifyReceiveMessage(1);
        s.setNotifyLike(1);
        s.setNotifyFollow(1);
        s.setNotifyComment(1);
        s.setFollowSystemFont(1);
        s.setChatFontLevel(0);
        s.setAutoRefresh(1);
        s.setPersonalHomepageSetting(1);
        return s;
    }

    @Override
    public R<IPage<LifeUserPersonalizationSetting>> list(Integer pageNum, Integer pageSize, Integer userId) {
        log.info("LifeUserPersonalizationSettingServiceImpl.list, pageNum={}, pageSize={}, userId={}", pageNum, pageSize, userId);
        Page<LifeUserPersonalizationSetting> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<LifeUserPersonalizationSetting> w = new LambdaQueryWrapper<>();
        if (userId != null) {
            w.eq(LifeUserPersonalizationSetting::getUserId, userId);
        }
        w.orderByDesc(LifeUserPersonalizationSetting::getUpdatedTime);
        return R.data(this.page(page, w));
    }
}
