package shop.alien.store.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
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 org.springframework.util.CollectionUtils;
import shop.alien.entity.store.SportsEquipmentFacility;
import shop.alien.entity.store.SportsFacilityArea;
import shop.alien.entity.store.StoreImg;
import shop.alien.mapper.SportsEquipmentFacilityMapper;
import shop.alien.mapper.SportsFacilityAreaMapper;
import shop.alien.mapper.StoreImgMapper;
import shop.alien.store.service.SportsFacilityAreaService;

import java.util.List;

/**
 * 运动设施区域服务实现类
 *
 * @author assistant
 * @since 2025-12-19
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class SportsFacilityAreaServiceImpl extends ServiceImpl<SportsFacilityAreaMapper, SportsFacilityArea>
        implements SportsFacilityAreaService {

    private final SportsFacilityAreaMapper areaMapper;
    private final SportsEquipmentFacilityMapper facilityMapper;
    private final StoreImgMapper storeImgMapper;

    /**
     * 运动器材设施图片类型
     */
    private static final Integer IMG_TYPE_SPORTS_EQUIPMENT = 28;

    /**
     * 删除标志：未删除
     */
    private static final int DELETE_FLAG_NOT_DELETED = 0;

    /**
     * 删除标志：已删除
     */
    private static final int DELETE_FLAG_DELETED = 1;

    /**
     * 默认排序号
     */
    private static final int DEFAULT_SORT_ORDER = 0;

    @Override
    public Integer createArea(Integer storeId, String areaName) {
        log.info("新建区域，storeId={}，areaName={}", storeId, areaName);

        // 1. 参数验证
        if (storeId == null || storeId <= 0) {
            log.warn("新建区域失败，门店ID无效：{}", storeId);
            throw new IllegalArgumentException("门店ID不能为空且必须大于0");
        }

        if (StringUtils.isBlank(areaName)) {
            log.warn("新建区域失败，区域名称为空");
            throw new IllegalArgumentException("区域名称不能为空");
        }

        // 2. 区域名称长度验证（限10字）
        String trimmedAreaName = areaName.trim();
        if (trimmedAreaName.length() > 10) {
            log.warn("新建区域失败，区域名称长度超过10字：{}，长度：{}", trimmedAreaName, trimmedAreaName.length());
            throw new IllegalArgumentException("区域名称长度不能超过10个字符");
        }

        // 3. 创建区域记录（区域名称允许重复，无需检查）
        SportsFacilityArea area = new SportsFacilityArea();
        area.setStoreId(storeId);
        area.setAreaName(trimmedAreaName);
        area.setSortOrder(DEFAULT_SORT_ORDER);
        area.setDeleteFlag(DELETE_FLAG_NOT_DELETED);

        // 5. 保存到数据库
        boolean saveResult = this.save(area);
        if (!saveResult) {
            log.error("新建区域失败，保存数据库失败：storeId={}，areaName={}", storeId, trimmedAreaName);
            throw new RuntimeException("新建区域失败，保存数据库失败");
        }

        log.info("新建区域成功，storeId={}，areaName={}，区域ID={}", storeId, trimmedAreaName, area.getId());
        return area.getId();
    }

    @Override
    public List<SportsFacilityArea> listAreas(Integer storeId) {
        log.info("查询区域列表，storeId={}", storeId);

        // 参数验证
        if (storeId == null || storeId <= 0) {
            log.warn("查询区域列表失败，门店ID无效：{}", storeId);
            throw new IllegalArgumentException("门店ID不能为空且必须大于0");
        }

        // 查询该门店下的所有未删除区域，按排序号升序，相同排序号按创建时间降序
        // 查询结果包含所有字段：id、storeId、areaName、sortOrder、deleteFlag、createdTime、updatedTime、
        // createdUserId、updatedUserId、areaLogoImg、areaHeadUrl
        // 注意：MyBatis-Plus的list()方法默认会查询所有字段，包括areaLogoImg和areaHeadUrl
        LambdaQueryWrapper<SportsFacilityArea> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SportsFacilityArea::getStoreId, storeId)
                .eq(SportsFacilityArea::getDeleteFlag, DELETE_FLAG_NOT_DELETED)
                .orderByAsc(SportsFacilityArea::getSortOrder)
                .orderByDesc(SportsFacilityArea::getCreatedTime);
        
        // 明确指定要查询的字段，确保包含图片字段
        queryWrapper.select(SportsFacilityArea::getId,
                SportsFacilityArea::getStoreId,
                SportsFacilityArea::getAreaName,
                SportsFacilityArea::getSortOrder,
                SportsFacilityArea::getDeleteFlag,
                SportsFacilityArea::getCreatedTime,
                SportsFacilityArea::getCreatedUserId,
                SportsFacilityArea::getUpdatedTime,
                SportsFacilityArea::getUpdatedUserId,
                SportsFacilityArea::getAreaLogoImg,
                SportsFacilityArea::getAreaHeadUrl);

        List<SportsFacilityArea> areaList = this.list(queryWrapper);
        
        // 记录查询结果详情（包括区域头图URL和logo图信息，用于调试）
        // 使用INFO级别记录，方便排查图片不显示的问题
        areaList.forEach(area -> {
            log.info("查询区域详情，areaId={}，areaName={}，areaHeadUrl={}，areaLogoImg={}", 
                    area.getId(), 
                    area.getAreaName(),
                    area.getAreaHeadUrl() != null ? (area.getAreaHeadUrl().length() > 100 ? 
                            area.getAreaHeadUrl().substring(0, 100) + "..." : area.getAreaHeadUrl()) : "null",
                    area.getAreaLogoImg());
        });
        
        log.info("查询区域列表成功，storeId={}，区域数量：{}", storeId, areaList.size());
        return areaList;
    }

    @Override
    public boolean updateArea(Integer areaId, String areaName, Integer sortOrder) {
        log.info("更新区域，areaId={}，areaName={}，sortOrder={}", areaId, areaName, sortOrder);

        // 参数验证
        if (areaId == null || areaId <= 0) {
            log.warn("更新区域失败，区域ID无效：{}", areaId);
            throw new IllegalArgumentException("区域ID不能为空且必须大于0");
        }

        // 查询区域是否存在
        SportsFacilityArea existingArea = this.getById(areaId);
        if (existingArea == null || existingArea.getDeleteFlag() == DELETE_FLAG_DELETED) {
            log.warn("更新区域失败，区域不存在或已删除：areaId={}", areaId);
            throw new IllegalArgumentException("区域不存在或已删除");
        }

        // 构建更新条件
        LambdaUpdateWrapper<SportsFacilityArea> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SportsFacilityArea::getId, areaId);

        // 更新区域名称
        if (StringUtils.isNotBlank(areaName)) {
            String trimmedAreaName = areaName.trim();
            // 验证长度
            if (trimmedAreaName.length() > 10) {
                log.warn("更新区域失败，区域名称长度超过10字：{}，长度：{}", trimmedAreaName, trimmedAreaName.length());
                throw new IllegalArgumentException("区域名称长度不能超过10个字符");
            }
            // 区域名称允许重复，无需检查
            updateWrapper.set(SportsFacilityArea::getAreaName, trimmedAreaName);
        }

        // 更新排序号
        if (sortOrder != null) {
            updateWrapper.set(SportsFacilityArea::getSortOrder, sortOrder);
        }

        // 执行更新
        boolean updateResult = this.update(updateWrapper);
        log.info("更新区域{}，areaId={}", updateResult ? "成功" : "失败", areaId);
        return updateResult;
    }

    @Override
    public boolean updateAreaHeadUrl(Integer areaId, String areaHeadUrl) {
        log.info("更新区域头图，areaId={}，areaHeadUrl长度={}", areaId, areaHeadUrl != null ? areaHeadUrl.length() : 0);

        // 参数验证
        if (areaId == null || areaId <= 0) {
            log.warn("更新区域头图失败，区域ID无效：{}", areaId);
            throw new IllegalArgumentException("区域ID不能为空且必须大于0");
        }

        if (areaHeadUrl == null) {
            log.warn("更新区域头图失败，区域头图URL为空");
            throw new IllegalArgumentException("区域头图URL不能为空");
        }

        // 查询区域是否存在
        SportsFacilityArea existingArea = this.getById(areaId);
        if (existingArea == null || existingArea.getDeleteFlag() == DELETE_FLAG_DELETED) {
            log.warn("更新区域头图失败，区域不存在或已删除：areaId={}", areaId);
            throw new IllegalArgumentException("区域不存在或已删除");
        }

        // 构建更新条件，直接覆盖原有的area_head_url字段
        LambdaUpdateWrapper<SportsFacilityArea> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SportsFacilityArea::getId, areaId)
                .set(SportsFacilityArea::getAreaHeadUrl, areaHeadUrl);

        // 执行更新
        boolean updateResult = this.update(updateWrapper);
        log.info("更新区域头图{}，areaId={}", updateResult ? "成功" : "失败", areaId);
        return updateResult;
    }

    @Override
    public boolean deleteArea(Integer areaId) {
        log.info("删除区域，areaId={}", areaId);

        // 参数验证
        if (areaId == null || areaId <= 0) {
            log.warn("删除区域失败，区域ID无效：{}", areaId);
            throw new IllegalArgumentException("区域ID不能为空且必须大于0");
        }

        // 查询区域是否存在
        SportsFacilityArea area = this.getById(areaId);
        if (area == null || area.getDeleteFlag() == DELETE_FLAG_DELETED) {
            log.warn("删除区域失败，区域不存在或已删除：areaId={}", areaId);
            throw new IllegalArgumentException("区域不存在或已删除");
        }

        // 1. 逻辑删除区域（区域名称允许重复，无需处理唯一索引冲突）
        LambdaUpdateWrapper<SportsFacilityArea> areaUpdateWrapper = new LambdaUpdateWrapper<>();
        areaUpdateWrapper.eq(SportsFacilityArea::getId, areaId)
                .set(SportsFacilityArea::getDeleteFlag, DELETE_FLAG_DELETED);
        boolean deleteAreaResult = this.update(areaUpdateWrapper);

        // 2. 逻辑删除该区域下的所有设施
        LambdaUpdateWrapper<SportsEquipmentFacility> facilityUpdateWrapper = new LambdaUpdateWrapper<>();
        facilityUpdateWrapper.eq(SportsEquipmentFacility::getAreaId, areaId)
                .set(SportsEquipmentFacility::getDeleteFlag, DELETE_FLAG_DELETED);
        int deletedFacilityCount = facilityMapper.update(null, facilityUpdateWrapper);

        // 3. 物理删除该区域下的所有实景图片
        LambdaQueryWrapper<StoreImg> deleteImageWrapper = new LambdaQueryWrapper<>();
        deleteImageWrapper.eq(StoreImg::getStoreId, area.getStoreId())
                .eq(StoreImg::getBusinessId, areaId)
                .eq(StoreImg::getImgType, IMG_TYPE_SPORTS_EQUIPMENT);
        int deletedImageCount = storeImgMapper.delete(deleteImageWrapper);

        log.info("删除区域{}，areaId={}，同时删除了{}个设施和{}张图片", 
                deleteAreaResult ? "成功" : "失败", areaId, deletedFacilityCount, deletedImageCount);
        return deleteAreaResult;
    }

    @Override
    public boolean batchDeleteAreas(Integer storeId, List<Integer> areaIds) {
        log.info("批量删除区域，storeId={}，areaIds={}", storeId, areaIds);

        // 参数验证
        if (storeId == null || storeId <= 0) {
            log.warn("批量删除区域失败，门店ID无效：{}", storeId);
            throw new IllegalArgumentException("门店ID不能为空且必须大于0");
        }

        if (CollectionUtils.isEmpty(areaIds)) {
            log.warn("批量删除区域失败，区域ID列表为空");
            throw new IllegalArgumentException("区域ID列表不能为空");
        }

        // 验证所有区域都属于该门店
        LambdaQueryWrapper<SportsFacilityArea> checkWrapper = new LambdaQueryWrapper<>();
        checkWrapper.eq(SportsFacilityArea::getStoreId, storeId)
                .in(SportsFacilityArea::getId, areaIds)
                .eq(SportsFacilityArea::getDeleteFlag, DELETE_FLAG_NOT_DELETED);
        long validCount = this.count(checkWrapper);
        if (validCount != areaIds.size()) {
            log.warn("批量删除区域失败，部分区域不存在或不属于该门店：storeId={}，areaIds={}，有效数量={}", storeId, areaIds, validCount);
            throw new IllegalArgumentException("部分区域不存在或不属于该门店");
        }

        // 1. 批量逻辑删除区域（区域名称允许重复，无需处理唯一索引冲突）
        LambdaUpdateWrapper<SportsFacilityArea> areaUpdateWrapper = new LambdaUpdateWrapper<>();
        areaUpdateWrapper.eq(SportsFacilityArea::getStoreId, storeId)
                .in(SportsFacilityArea::getId, areaIds)
                .set(SportsFacilityArea::getDeleteFlag, DELETE_FLAG_DELETED);
        boolean deleteAreaResult = this.update(areaUpdateWrapper);

        // 2. 批量逻辑删除这些区域下的所有设施
        LambdaUpdateWrapper<SportsEquipmentFacility> facilityUpdateWrapper = new LambdaUpdateWrapper<>();
        facilityUpdateWrapper.eq(SportsEquipmentFacility::getStoreId, storeId)
                .in(SportsEquipmentFacility::getAreaId, areaIds)
                .set(SportsEquipmentFacility::getDeleteFlag, DELETE_FLAG_DELETED);
        int deletedFacilityCount = facilityMapper.update(null, facilityUpdateWrapper);

        // 3. 批量物理删除这些区域下的所有实景图片
        LambdaQueryWrapper<StoreImg> deleteImageWrapper = new LambdaQueryWrapper<>();
        deleteImageWrapper.eq(StoreImg::getStoreId, storeId)
                .in(StoreImg::getBusinessId, areaIds)
                .eq(StoreImg::getImgType, IMG_TYPE_SPORTS_EQUIPMENT);
        int deletedImageCount = storeImgMapper.delete(deleteImageWrapper);

        log.info("批量删除区域{}，storeId={}，区域数量={}，同时删除了{}个设施和{}张图片", 
                deleteAreaResult ? "成功" : "失败", storeId, areaIds.size(), deletedFacilityCount, deletedImageCount);
        return deleteAreaResult;
    }
}

