package com.snack.server.module.banner.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.snack.server.exception.BusinessException;
import com.snack.server.module.banner.dto.req.BannerPageReq;
import com.snack.server.module.banner.dto.req.BannerSaveReq;
import com.snack.server.module.banner.entity.Banner;
import com.snack.server.module.banner.mapper.BannerMapper;
import com.snack.server.module.banner.service.BannerService;
import com.snack.server.module.banner.vo.BannerVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 轮播图业务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class BannerServiceImpl implements BannerService {

    private final BannerMapper bannerMapper;

    // ==================== 用户端 ====================

    @Override
    public List<BannerVO> listActive() {
        LocalDateTime now = LocalDateTime.now();
        List<Banner> list = bannerMapper.selectList(
                new LambdaQueryWrapper<Banner>()
                        .eq(Banner::getStatus, 1)
                        .and(w -> w
                                .isNull(Banner::getStartTime)
                                .or().le(Banner::getStartTime, now)
                        )
                        .and(w -> w
                                .isNull(Banner::getEndTime)
                                .or().ge(Banner::getEndTime, now)
                        )
                        .orderByAsc(Banner::getSort)
                        .orderByDesc(Banner::getId)
        );
        return list.stream().map(this::toVO).toList();
    }

    // ==================== 管理端查询 ====================

    @Override
    public Page<BannerVO> pageBanners(BannerPageReq req) {
        Page<Banner> page = new Page<>(req.getCurrent(), req.getSize());
        LambdaQueryWrapper<Banner> wrapper = new LambdaQueryWrapper<Banner>()
                .like(StrUtil.isNotBlank(req.getKeyword()), Banner::getTitle, req.getKeyword())
                .eq(req.getStatus() != null, Banner::getStatus, req.getStatus())
                .orderByAsc(Banner::getSort)
                .orderByDesc(Banner::getId);

        Page<Banner> result = bannerMapper.selectPage(page, wrapper);
        Page<BannerVO> voPage = new Page<>(result.getCurrent(), result.getSize(), result.getTotal());
        voPage.setRecords(result.getRecords().stream().map(this::toVO).toList());
        return voPage;
    }

    @Override
    public BannerVO getById(Long id) {
        Banner banner = bannerMapper.selectById(id);
        if (banner == null) {
            throw new BusinessException(1000, "轮播图不存在");
        }
        return toVO(banner);
    }

    // ==================== 创建 / 更新 / 删除 ====================

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long create(BannerSaveReq req) {
        Banner banner = new Banner();
        BeanUtil.copyProperties(req, banner, "id");
        if (banner.getStatus() == null) {
            banner.setStatus(1);
        }
        if (banner.getSort() == null) {
            banner.setSort(0);
        }
        bannerMapper.insert(banner);
        log.info("创建轮播图 id={} title={}", banner.getId(), banner.getTitle());
        return banner.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(BannerSaveReq req) {
        if (req.getId() == null) {
            throw new BusinessException(1000, "ID 不能为空");
        }
        Banner existing = bannerMapper.selectById(req.getId());
        if (existing == null) {
            throw new BusinessException(1000, "轮播图不存在");
        }
        Banner banner = new Banner();
        BeanUtil.copyProperties(req, banner);
        bannerMapper.updateById(banner);
        log.info("更新轮播图 id={}", banner.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        Banner existing = bannerMapper.selectById(id);
        if (existing == null) {
            throw new BusinessException(1000, "轮播图不存在");
        }
        bannerMapper.deleteById(id);
        log.info("删除轮播图 id={}", id);
    }

    // ==================== 状态 / 排序 ====================

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStatus(Long id, Integer status) {
        if (id == null || status == null) {
            throw new BusinessException(1000, "参数错误");
        }
        Banner existing = bannerMapper.selectById(id);
        if (existing == null) {
            throw new BusinessException(1000, "轮播图不存在");
        }
        if (existing.getStatus() != null && existing.getStatus().equals(status)) {
            return;
        }
        Banner update = new Banner();
        update.setId(id);
        update.setStatus(status);
        bannerMapper.updateById(update);
        log.info("轮播图 id={} 状态更新为 {}", id, status);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSort(Long id, Integer sort) {
        if (id == null) {
            throw new BusinessException(1000, "ID 不能为空");
        }
        Banner existing = bannerMapper.selectById(id);
        if (existing == null) {
            throw new BusinessException(1000, "轮播图不存在");
        }
        Banner update = new Banner();
        update.setId(id);
        update.setSort(sort == null ? 0 : sort);
        bannerMapper.updateById(update);
        log.info("轮播图 id={} 排序更新为 {}", id, sort);
    }

    // ==================== 私有方法 ====================

    private BannerVO toVO(Banner banner) {
        BannerVO vo = new BannerVO();
        BeanUtil.copyProperties(banner, vo);
        return vo;
    }
}
