package com.jeesharp.business.modules.mall.application;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.jeesharp.business.modules.mall.convert.MallBrowseFootprintConvert;
import com.jeesharp.business.modules.mall.dto.MallBrowseFootprintSaveDTO;
import com.jeesharp.business.modules.mall.entity.MallBrowseFootprint;
import com.jeesharp.business.modules.mall.service.MallBrowseFootprintService;
import com.jeesharp.business.modules.mall.service.MallSpuService;
import com.jeesharp.business.modules.mall.vo.MallBrowseFootprintInfoVO;
import com.jeesharp.business.modules.mall.vo.MallBrowseFootprintListVO;
import com.jeesharp.business.modules.mall.vo.MallBrowseFootprintQueryVO;
import com.jeesharp.business.modules.member.service.MemberService;
import com.jeesharp.framework.pojo.Page;
import com.jeesharp.framework.pojo.query.PageRespVO;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * 浏览足迹应用服务：管理端分页查询、会员/商品名称筛选与列表展示补全。
 *
 * @author jeesharp
 * @since 2026-06-05
 */
@Service
@AllArgsConstructor
@Transactional(readOnly = true)
public class MallBrowseFootprintApplicationService {

    private final MallBrowseFootprintService mallBrowseFootprintService;
    private final MemberService memberService;
    private final MallSpuService mallSpuService;

    public MallBrowseFootprintInfoVO get(String id) {
        MallBrowseFootprintInfoVO vo = MallBrowseFootprintConvert.INSTANCE.toInfoVO(mallBrowseFootprintService.get(id));
        enrichInfoDisplay(vo);
        return vo;
    }

    public PageRespVO<MallBrowseFootprintListVO> findPage(Page<MallBrowseFootprint> page, MallBrowseFootprintQueryVO query) {
        MallBrowseFootprintQueryVO prepared = prepareQuery(query);
        if (prepared == null) {
            return emptyPage(page);
        }
        Page<MallBrowseFootprint> result = mallBrowseFootprintService.findPage(page, prepared);
        PageRespVO<MallBrowseFootprintListVO> pageVo = MallBrowseFootprintConvert.INSTANCE.toPageRespVO(result);
        enrichListDisplay(pageVo.getRecords());
        return pageVo;
    }

    @Transactional(readOnly = false)
    public void save(MallBrowseFootprintSaveDTO dto) {
        MallBrowseFootprint entity = MallBrowseFootprintConvert.INSTANCE.toEntity(dto);
        if (StrUtil.isBlank(dto.getId())) {
            mallBrowseFootprintService.createFootprint(entity);
            return;
        }
        mallBrowseFootprintService.updateFootprint(entity);
    }

    @Transactional(readOnly = false)
    public void delete(String ids) {
        mallBrowseFootprintService.batchDelete(StrUtil.splitTrim(ids, ','));
    }

    /**
     * 记录用户浏览足迹
     */
    @Transactional(readOnly = false)
    public void recordBrowseFootprint(String memberId, String spuId) {
        mallBrowseFootprintService.recordBrowseFootprint(memberId, spuId);
    }

    /**
     * 获取用户浏览足迹（最近200条，按时间倒序）
     */
    public PageRespVO<MallBrowseFootprintListVO> getUserBrowseFootprints(String memberId, Page<MallBrowseFootprint> page) {
        PageRespVO<MallBrowseFootprint> result = mallBrowseFootprintService.getUserBrowseFootprints(memberId, page);
        PageRespVO<MallBrowseFootprintListVO> resp = new PageRespVO<>();
        List<MallBrowseFootprintListVO> rows = MallBrowseFootprintConvert.INSTANCE.toListVO(result.getRecords());
        enrichListDisplay(rows);
        resp.setRecords(rows);
        resp.setTotal(result.getTotal());
        resp.setPageNo(result.getPageNo());
        resp.setPageSize(result.getPageSize());
        return resp;
    }

    /**
     * 删除用户的浏览足迹
     */
    @Transactional(readOnly = false)
    public void clearUserBrowseFootprints(String memberId) {
        mallBrowseFootprintService.clearUserBrowseFootprints(memberId);
    }

    /**
     * 删除单条浏览足迹
     */
    @Transactional(readOnly = false)
    public void deleteFootprint(String memberId, String spuId) {
        mallBrowseFootprintService.deleteFootprint(memberId, spuId);
    }

    private MallBrowseFootprintQueryVO prepareQuery(MallBrowseFootprintQueryVO query) {
        MallBrowseFootprintQueryVO q = query != null ? query : new MallBrowseFootprintQueryVO();
        if (StrUtil.isNotBlank(q.getMemberKeyword())) {
            List<String> memberIds = memberService.findIdsByKeyword(q.getMemberKeyword().trim());
            q.setMemberKeyword(null);
            if (CollUtil.isEmpty(memberIds)) {
                return null;
            }
            q.setMemberIdIn(memberIds);
        }
        if (StrUtil.isNotBlank(q.getSpuName())) {
            List<String> spuIds = mallSpuService.findIdsBySpuNameLike(q.getSpuName().trim());
            q.setSpuName(null);
            if (CollUtil.isEmpty(spuIds)) {
                return null;
            }
            q.setSpuIdIn(spuIds);
        }
        return q;
    }

    private void enrichInfoDisplay(MallBrowseFootprintInfoVO vo) {
        if (vo == null) {
            return;
        }
        memberService.enrichMemberDisplay(vo);
        if (StrUtil.isNotBlank(vo.getSpuId())) {
            vo.setSpuName(mallSpuService.mapSpuNameByIds(List.of(vo.getSpuId())).get(vo.getSpuId()));
        }
    }

    private void enrichListDisplay(List<MallBrowseFootprintListVO> rows) {
        if (CollUtil.isEmpty(rows)) {
            return;
        }
        memberService.enrichMemberDisplay(rows);
        List<String> spuIds = rows.stream().map(MallBrowseFootprintListVO::getSpuId).filter(StrUtil::isNotBlank).distinct().toList();
        if (CollUtil.isEmpty(spuIds)) {
            return;
        }
        Map<String, String> spuNameMap = mallSpuService.mapSpuNameByIds(spuIds);
        for (MallBrowseFootprintListVO row : rows) {
            if (StrUtil.isNotBlank(row.getSpuId())) {
                row.setSpuName(spuNameMap.get(row.getSpuId()));
            }
        }
    }

    private PageRespVO<MallBrowseFootprintListVO> emptyPage(Page<MallBrowseFootprint> page) {
        PageRespVO<MallBrowseFootprintListVO> empty = new PageRespVO<>();
        empty.setRecords(Collections.emptyList());
        empty.setTotal(0L);
        empty.setPageNo(page.getPageNo());
        empty.setPageSize(page.getPageSize());
        empty.setPages(0L);
        return empty;
    }
}
