package shop.alien.store.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import shop.alien.entity.store.BathFacilityService;
import shop.alien.entity.store.StoreImg;
import shop.alien.entity.store.vo.BathFacilityServiceCategoryVo;
import shop.alien.entity.store.vo.BathFacilityServiceVo;
import shop.alien.mapper.BathFacilityServiceMapper;
import shop.alien.mapper.StoreImgMapper;
import shop.alien.store.service.BathFacilityServiceService;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 洗浴设施及服务服务实现类
 *
 * @author system
 * @since 2025-01-XX
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class BathFacilityServiceServiceImpl extends ServiceImpl<BathFacilityServiceMapper, BathFacilityService>
        implements BathFacilityServiceService {

    private final BathFacilityServiceMapper facilityServiceMapper;
    private final StoreImgMapper storeImgMapper;

    /**
     * 设施分类名称映射
     */
    private static final String[] FACILITY_CATEGORY_NAMES = {"", "洗浴区", "汗蒸区", "休闲区", "餐饮区"};

    /**
     * 洗浴设施及服务图片类型
     */
    private static final Integer IMG_TYPE_BATH_FACILITY = 29;

    @Override
    public IPage<BathFacilityServiceVo> getPageList(Integer pageNum, Integer pageSize, Integer storeId, Integer facilityCategory) {
        Page<BathFacilityService> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<BathFacilityService> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BathFacilityService::getStoreId, storeId);
        if (facilityCategory != null) {
            queryWrapper.eq(BathFacilityService::getFacilityCategory, facilityCategory);
        }
        queryWrapper.orderByDesc(BathFacilityService::getCreatedTime);
        IPage<BathFacilityService> facilityServicePage = facilityServiceMapper.selectPage(page, queryWrapper);
        return facilityServicePage.convert(this::convertToVo);
    }

    @Override
    public List<BathFacilityServiceVo> getList(Integer storeId, Integer facilityCategory) {
        LambdaQueryWrapper<BathFacilityService> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BathFacilityService::getStoreId, storeId);
        if (facilityCategory != null) {
            queryWrapper.eq(BathFacilityService::getFacilityCategory, facilityCategory);
        }
        queryWrapper.orderByDesc(BathFacilityService::getCreatedTime);
        List<BathFacilityService> facilityServiceList = facilityServiceMapper.selectList(queryWrapper);
        return facilityServiceList.stream().map(this::convertToVo).collect(Collectors.toList());
    }

    @Override
    public BathFacilityServiceVo getDetail(Integer id) {
        BathFacilityService facilityService = facilityServiceMapper.selectById(id);
        if (facilityService == null) {
            return null;
        }
        return convertToVo(facilityService);
    }

    @Override
    public boolean saveFacilityService(BathFacilityService facilityService, List<String> imageList) {
        // 校验使用时间
        validateUsageTime(facilityService);
        // 保存设施服务信息
        boolean result = this.save(facilityService);
        if (result && !CollectionUtils.isEmpty(imageList)) {
            // 保存图片
            saveImages(facilityService.getId(), facilityService.getStoreId(), imageList);
        }
        return result;
    }

    @Override
    public boolean updateFacilityService(BathFacilityService facilityService, List<String> imageList) {
        // 校验使用时间
        validateUsageTime(facilityService);
        // 更新设施服务信息
        boolean result = this.updateById(facilityService);
        if (result && !CollectionUtils.isEmpty(imageList)) {
            // 删除旧图片
            LambdaQueryWrapper<StoreImg> deleteWrapper = new LambdaQueryWrapper<>();
            deleteWrapper.eq(StoreImg::getBusinessId, facilityService.getId())
                    .eq(StoreImg::getImgType, IMG_TYPE_BATH_FACILITY);
            storeImgMapper.delete(deleteWrapper);
            // 保存新图片
            saveImages(facilityService.getId(), facilityService.getStoreId(), imageList);
        }
        return result;
    }

    @Override
    public boolean deleteFacilityService(Integer id) {
        // 删除图片
        LambdaQueryWrapper<StoreImg> deleteWrapper = new LambdaQueryWrapper<>();
        deleteWrapper.eq(StoreImg::getBusinessId, id)
                .eq(StoreImg::getImgType, IMG_TYPE_BATH_FACILITY);
        storeImgMapper.delete(deleteWrapper);
        // 删除设施服务
        return this.removeById(id);
    }

    /**
     * 校验使用时间
     */
    private void validateUsageTime(BathFacilityService facilityService) {
        if (facilityService.getUsageTimeType() == null) {
            throw new RuntimeException("使用时间类型不能为空");
        }
        // 如果选择时间，需要填写开始时间和结束时间
        if (facilityService.getUsageTimeType() == 1) {
            if (!StringUtils.hasText(facilityService.getUsageStartTime())
                    || !StringUtils.hasText(facilityService.getUsageEndTime())) {
                throw new RuntimeException("选择时间时，开始时间和结束时间不能为空");
            }
            // 校验时间格式
            if (!facilityService.getUsageStartTime().matches("^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$")
                    || !facilityService.getUsageEndTime().matches("^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$")) {
                throw new RuntimeException("时间格式错误，请使用HH:mm格式");
            }
        }
    }

    /**
     * 保存图片
     */
    private void saveImages(Integer facilityServiceId, Integer storeId, List<String> imageList) {
        for (int i = 0; i < imageList.size(); i++) {
            StoreImg storeImg = new StoreImg();
            storeImg.setStoreId(storeId);
            storeImg.setImgType(IMG_TYPE_BATH_FACILITY);
            storeImg.setBusinessId(facilityServiceId);
            storeImg.setImgUrl(imageList.get(i));
            storeImg.setImgSort(i + 1);
            storeImg.setImgDescription("洗浴设施及服务图片");
            storeImgMapper.insert(storeImg);
        }
    }

    /**
     * 转换为VO对象
     */
    private BathFacilityServiceVo convertToVo(BathFacilityService facilityService) {
        BathFacilityServiceVo vo = new BathFacilityServiceVo();
        BeanUtils.copyProperties(facilityService, vo);
        // 设置分类名称
        if (facilityService.getFacilityCategory() != null && facilityService.getFacilityCategory() > 0
                && facilityService.getFacilityCategory() < FACILITY_CATEGORY_NAMES.length) {
            vo.setFacilityCategoryName(FACILITY_CATEGORY_NAMES[facilityService.getFacilityCategory()]);
        }
        // 设置使用时间类型文本
        if (facilityService.getUsageTimeType() != null) {
            vo.setUsageTimeTypeText(facilityService.getUsageTimeType() == 0 ? "全天" : "选择时间");
            // 设置使用时间范围
            if (facilityService.getUsageTimeType() == 1
                    && StringUtils.hasText(facilityService.getUsageStartTime())
                    && StringUtils.hasText(facilityService.getUsageEndTime())) {
                vo.setUsageTimeRange(facilityService.getUsageStartTime() + "-" + facilityService.getUsageEndTime());
            }
        }
        // 设置显示状态文本
        if (facilityService.getDisplayInStoreDetail() != null) {
            vo.setDisplayInStoreDetailText(facilityService.getDisplayInStoreDetail() == 1 ? "显示" : "隐藏");
        }
        // 查询图片列表
        LambdaQueryWrapper<StoreImg> imageWrapper = new LambdaQueryWrapper<>();
        imageWrapper.eq(StoreImg::getBusinessId, facilityService.getId())
                .eq(StoreImg::getImgType, IMG_TYPE_BATH_FACILITY);
        imageWrapper.orderByAsc(StoreImg::getImgSort);
        List<StoreImg> imageList = storeImgMapper.selectList(imageWrapper);
        if (!CollectionUtils.isEmpty(imageList)) {
            vo.setImageList(imageList.stream().map(StoreImg::getImgUrl)
                    .collect(Collectors.toList()));
        } else {
            vo.setImageList(new ArrayList<>());
        }
        return vo;
    }

    @Override
    public List<BathFacilityServiceCategoryVo> getCategorySummary(Integer storeId) {
        List<BathFacilityServiceCategoryVo> result = new ArrayList<>();
        
        // 遍历所有分类（1:洗浴区, 2:汗蒸区, 3:休闲区, 4:餐饮区）
        for (int category = 1; category < FACILITY_CATEGORY_NAMES.length; category++) {
            BathFacilityServiceCategoryVo categoryVo = new BathFacilityServiceCategoryVo();
            categoryVo.setFacilityCategory(category);
            categoryVo.setFacilityCategoryName(FACILITY_CATEGORY_NAMES[category]);
            
            // 查询该分类下的设备列表（不分页）
            LambdaQueryWrapper<BathFacilityService> facilityWrapper = new LambdaQueryWrapper<>();
            facilityWrapper.eq(BathFacilityService::getStoreId, storeId)
                    .eq(BathFacilityService::getFacilityCategory, category);
            facilityWrapper.orderByDesc(BathFacilityService::getCreatedTime);
            List<BathFacilityService> facilityServiceList = facilityServiceMapper.selectList(facilityWrapper);
            
            // 设置设备数量
            categoryVo.setFacilityCount(facilityServiceList != null ? facilityServiceList.size() : 0);
            
            // 查询该分类的代表图片（从第一个设备的第一张图片获取）
            if (!CollectionUtils.isEmpty(facilityServiceList)) {
                BathFacilityService firstFacility = facilityServiceList.get(0);
                // 查询该设备的第一张图片
                LambdaQueryWrapper<StoreImg> imageWrapper = new LambdaQueryWrapper<>();
                imageWrapper.eq(StoreImg::getStoreId, storeId)
                        .eq(StoreImg::getBusinessId, firstFacility.getId())
                        .eq(StoreImg::getImgType, IMG_TYPE_BATH_FACILITY);
                imageWrapper.orderByAsc(StoreImg::getImgSort);
                imageWrapper.last("LIMIT 1");
                StoreImg firstImage = storeImgMapper.selectOne(imageWrapper);
                if (firstImage != null) {
                    categoryVo.setCategoryImage(firstImage.getImgUrl());
                }
            }
            
            // 转换为VO列表（包含设备信息和图片）
            List<BathFacilityServiceVo> facilityVoList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(facilityServiceList)) {
                for (BathFacilityService facilityService : facilityServiceList) {
                    // 使用现有的convertToVo方法，它会自动查询图片
                    BathFacilityServiceVo vo = convertToVo(facilityService);
                    facilityVoList.add(vo);
                }
            }
            categoryVo.setFacilityList(facilityVoList);
            
            result.add(categoryVo);
        }
        
        return result;
    }

    @Override
    public IPage<BathFacilityServiceVo> getStorePageList(Integer pageNum, Integer pageSize, Integer storeId, Integer facilityCategory) {
        Page<BathFacilityService> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<BathFacilityService> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BathFacilityService::getStoreId, storeId);
        if (facilityCategory != null) {
            queryWrapper.eq(BathFacilityService::getFacilityCategory, facilityCategory);
        }
        queryWrapper.orderByDesc(BathFacilityService::getCreatedTime);
        IPage<BathFacilityService> facilityServicePage = facilityServiceMapper.selectPage(page, queryWrapper);
        return facilityServicePage.convert(this::convertToVo);
    }

    @Override
    public BathFacilityServiceVo getStoreDetail(Integer id) {
        BathFacilityService facilityService = facilityServiceMapper.selectById(id);
        if (facilityService == null) {
            return null;
        }
        return convertToVo(facilityService);
    }

    @Override
    public List<BathFacilityServiceCategoryVo> getStoreCategorySummary(Integer storeId) {
        List<BathFacilityServiceCategoryVo> result = new ArrayList<>();

        // 遍历所有分类（1:洗浴区, 2:汗蒸区, 3:休闲区, 4:餐饮区）
        for (int category = 1; category < FACILITY_CATEGORY_NAMES.length; category++) {
            BathFacilityServiceCategoryVo categoryVo = new BathFacilityServiceCategoryVo();
            categoryVo.setFacilityCategory(category);
            categoryVo.setFacilityCategoryName(FACILITY_CATEGORY_NAMES[category]);

            // 查询该分类下的设备列表（不分页）
            LambdaQueryWrapper<BathFacilityService> facilityWrapper = new LambdaQueryWrapper<>();
            facilityWrapper.eq(BathFacilityService::getStoreId, storeId)
                    .eq(BathFacilityService::getFacilityCategory, category);
            facilityWrapper.orderByDesc(BathFacilityService::getCreatedTime);
            List<BathFacilityService> facilityServiceList = facilityServiceMapper.selectList(facilityWrapper);

            // 设置设备数量
            categoryVo.setFacilityCount(facilityServiceList != null ? facilityServiceList.size() : 0);

            // 查询该分类的代表图片（从第一个设备的第一张图片获取）
            if (!CollectionUtils.isEmpty(facilityServiceList)) {
                BathFacilityService firstFacility = facilityServiceList.get(0);
                // 查询该设备的第一张图片
                LambdaQueryWrapper<StoreImg> imageWrapper = new LambdaQueryWrapper<>();
                imageWrapper.eq(StoreImg::getStoreId, storeId)
                        .eq(StoreImg::getBusinessId, firstFacility.getId())
                        .eq(StoreImg::getImgType, IMG_TYPE_BATH_FACILITY);
                imageWrapper.orderByAsc(StoreImg::getImgSort);
                imageWrapper.last("LIMIT 1");
                StoreImg firstImage = storeImgMapper.selectOne(imageWrapper);
                if (firstImage != null) {
                    categoryVo.setCategoryImage(firstImage.getImgUrl());
                }
            }

            // 转换为VO列表（包含设备信息和图片）
            List<BathFacilityServiceVo> facilityVoList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(facilityServiceList)) {
                for (BathFacilityService facilityService : facilityServiceList) {
                    // 使用现有的convertToVo方法，它会自动查询图片
                    BathFacilityServiceVo vo = convertToVo(facilityService);
                    facilityVoList.add(vo);
                }
            }
            categoryVo.setFacilityList(facilityVoList);

            result.add(categoryVo);
        }

        return result;
    }
}

