package shop.alien.store.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import shop.alien.entity.result.R;
import shop.alien.entity.store.FitnessEquipmentInfo;
import shop.alien.entity.store.SportsEquipmentFacility;
import shop.alien.entity.store.vo.DeleteFacilityRequestVo;
import shop.alien.entity.store.vo.FitnessEquipmentCategoryDetailVo;
import shop.alien.entity.store.vo.SportsEquipmentFacilityCategorySummaryVo;
import shop.alien.entity.store.vo.SportsEquipmentFacilityCategoryVo;
import shop.alien.entity.store.vo.SportsEquipmentFacilityVo;
import shop.alien.store.service.SportsEquipmentFacilityService;

import java.util.List;

/**
 * 运动器材设施Controller
 *
 * @author system
 * @since 2025-01-XX
 */
@Slf4j
@Api(tags = {"运动器材设施管理"})
@ApiSort(1)
@CrossOrigin
@RestController
@RequestMapping("/sports/equipment/facility")
@RequiredArgsConstructor
public class SportsEquipmentFacilityController {

    private final SportsEquipmentFacilityService facilityService;

    @ApiOperation("分页查询运动器材设施列表")
    @ApiOperationSupport(order = 1)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "页码", dataType = "int", paramType = "query", required = true, defaultValue = "1"),
            @ApiImplicitParam(name = "pageSize", value = "页大小", dataType = "int", paramType = "query", required = true, defaultValue = "10"),
            @ApiImplicitParam(name = "storeId", value = "门店ID", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "facilityCategory", value = "设施分类(1:有氧区, 2:力量区, 3:单功能机械区)", dataType = "int", paramType = "query")
    })
    @GetMapping("/page")
    public R<IPage<SportsEquipmentFacilityVo>> getPageList(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam Integer storeId,
            @RequestParam(required = false) Integer facilityCategory) {
        log.info("SportsEquipmentFacilityController.getPageList?pageNum={},pageSize={},storeId={},facilityCategory={}",
                pageNum, pageSize, storeId, facilityCategory);
        return R.data(facilityService.getPageList(pageNum, pageSize, storeId, facilityCategory));
    }

    @ApiOperation("查询运动器材设施列表")
    @ApiOperationSupport(order = 2)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeId", value = "门店ID", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "facilityCategory", value = "设施分类(1:有氧区, 2:力量区, 3:单功能机械区)", dataType = "int", paramType = "query")
    })
    @GetMapping("/list")
    public R<List<SportsEquipmentFacilityVo>> getList(
            @RequestParam Integer storeId,
            @RequestParam(required = false) Integer facilityCategory) {
        log.info("SportsEquipmentFacilityController.getList?storeId={},facilityCategory={}", storeId, facilityCategory);
        return R.data(facilityService.getList(storeId, facilityCategory));
    }

    @ApiOperation("根据区域ID查询设备列表")
    @ApiOperationSupport(order = 3)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeId", value = "门店ID", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "areaId", value = "区域ID", dataType = "int", paramType = "query", required = true)
    })
    @GetMapping("/listByArea")
    public R<List<FitnessEquipmentInfo>> getListByArea(
            @RequestParam Integer storeId,
            @RequestParam Integer areaId) {
        log.info("SportsEquipmentFacilityController.getListByArea?storeId={},areaId={}", storeId, areaId);
        try {
            if (storeId == null || storeId <= 0) {
                log.warn("根据区域ID查询设备列表失败，门店ID无效：{}", storeId);
                return R.fail("门店ID不能为空且必须大于0");
            }
            if (areaId == null || areaId <= 0) {
                log.warn("根据区域ID查询设备列表失败，区域ID无效：{}", areaId);
                return R.fail("区域ID不能为空且必须大于0");
            }
            List<FitnessEquipmentInfo> result = facilityService.getListByAreaId(storeId, areaId);
            log.info("根据区域ID查询设备列表成功，storeId={}，areaId={}，设备数量：{}", storeId, areaId, result.size());
            return R.data(result);
        } catch (IllegalArgumentException e) {
            log.warn("根据区域ID查询设备列表失败，参数验证失败：{}", e.getMessage());
            return R.fail(e.getMessage());
        } catch (Exception e) {
            log.error("根据区域ID查询设备列表异常，storeId={}，areaId={}，异常信息：{}", 
                    storeId, areaId, e.getMessage(), e);
            return R.fail("查询失败：" + e.getMessage());
        }
    }

    @ApiOperation("根据ID查询运动器材设施详情（用户端）")
    @ApiOperationSupport(order = 4)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "主键ID", dataType = "int", paramType = "query", required = true)
    })
    @GetMapping("/detail")
    public R<SportsEquipmentFacilityVo> getDetail(@RequestParam Integer id) {
        log.info("SportsEquipmentFacilityController.getDetail?id={}", id);
        SportsEquipmentFacilityVo vo = facilityService.getDetail(id);
        if (vo == null) {
            return R.fail("数据不存在");
        }
        return R.data(vo);
    }

    @ApiOperation("新增运动器材设施")
    @ApiOperationSupport(order = 5)
    @PostMapping("/save")
    public R<Boolean> saveFacility(@RequestBody SportsEquipmentFacilityVo vo) {
        log.info("SportsEquipmentFacilityController.saveFacility?vo={}", vo);
        try {
            // 参数验证
            if (vo == null) {
                return R.fail("请求参数不能为空");
            }
            if (vo.getStoreId() == null || vo.getStoreId() <= 0) {
                return R.fail("门店ID不能为空且必须大于0");
            }
            if (vo.getAreaId() == null || vo.getAreaId() <= 0) {
                return R.fail("区域ID不能为空且必须大于0");
            }
            if (StringUtils.isBlank(vo.getEquipmentName())) {
                return R.fail("设备名称不能为空");
            }
            
            SportsEquipmentFacility facility = new SportsEquipmentFacility();
            facility.setStoreId(vo.getStoreId());
            facility.setAreaId(vo.getAreaId()); // 设置区域ID
            facility.setFacilityCategory(vo.getFacilityCategory());
            facility.setFacilityName(vo.getFacilityName());
            facility.setQuantity(vo.getQuantity());
            facility.setBrand(vo.getBrand());
            facility.setDescription(vo.getDescription());
            facility.setDisplayInStoreDetail(vo.getDisplayInStoreDetail());
            
            // 传递vo参数，包含设备信息（equipmentName、equipmentNums、equipmentImage）
            boolean result = facilityService.saveFacility(facility, vo.getImageList(), vo);
            if (result) {
                return R.success("新增成功");
            }
            return R.fail("新增失败");
        } catch (IllegalArgumentException e) {
            log.warn("新增运动器材设施失败，参数验证失败：{}", e.getMessage());
            return R.fail(e.getMessage());
        } catch (Exception e) {
            log.error("SportsEquipmentFacilityController.saveFacility异常", e);
            return R.fail(e.getMessage());
        }
    }

    @ApiOperation("修改运动器材设施")
    @ApiOperationSupport(order = 6)
    @PostMapping("/update")
    public R<Boolean> updateFacility(@RequestBody SportsEquipmentFacilityVo vo) {
        log.info("SportsEquipmentFacilityController.updateFacility?vo={}", vo);
        try {
            // 参数验证：必须提供id（设施ID）或equipmentId（设备ID）之一
            if (vo.getId() == null && (vo.getEquipmentId() == null || vo.getEquipmentId() <= 0)) {  
                return R.fail("主键ID或设备ID不能为空");
            }
            
            SportsEquipmentFacility facility = new SportsEquipmentFacility();
            // 如果提供了设施ID，使用设施ID；否则会在Service层根据equipmentId查询
            if (vo.getId() != null) {
                facility.setId(vo.getId());
            }
            facility.setStoreId(vo.getStoreId());
            facility.setFacilityCategory(vo.getFacilityCategory());
            facility.setFacilityName(vo.getFacilityName());
            facility.setQuantity(vo.getQuantity());
            facility.setBrand(vo.getBrand()); 
            facility.setDescription(vo.getDescription());
            facility.setDisplayInStoreDetail(vo.getDisplayInStoreDetail());
            facility.setAreaId(vo.getAreaId()); // 设置区域ID
            
            // 传递vo参数，包含设备信息（equipmentName、equipmentNums、equipmentImage、equipmentId）
            boolean result = facilityService.updateFacility(facility, vo.getImageList(), vo);
            if (result) {
                return R.success("修改成功");
            }
            return R.fail("修改失败");
        } catch (IllegalArgumentException e) {
            log.warn("修改运动器材设施失败，参数验证失败：{}", e.getMessage());
            return R.fail(e.getMessage());
        } catch (Exception e) {
            log.error("SportsEquipmentFacilityController.updateFacility异常", e);
            return R.fail(e.getMessage());
        }
    }

    @ApiOperation("删除运动器材设施")
    @ApiOperationSupport(order = 7)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "request", value = "删除设备请求参数", dataType = "DeleteFacilityRequestVo", paramType = "body", required = true)
    })
    @PostMapping("/delete")
    public R<Boolean> deleteFacility(@RequestBody DeleteFacilityRequestVo request) {
        log.info("SportsEquipmentFacilityController.deleteFacility?request={}", request);
        try {
            // 参数验证
            if (request == null) {
                log.warn("删除运动器材设施失败，请求参数为空");
                return R.fail("请求参数不能为空");
            }
            
            // 优先使用equipmentId，如果没有则使用id
            Integer equipmentId = request.getEquipmentId();
            if (equipmentId == null || equipmentId <= 0) {
                equipmentId = request.getId();
            }
            if (equipmentId == null || equipmentId <= 0) {
                log.warn("删除运动器材设施失败，设备ID无效：id={}，equipmentId={}", request.getId(), request.getEquipmentId());
                return R.fail("设备ID不能为空且必须大于0");
            }
            
            boolean result = facilityService.deleteFacility(equipmentId);
            if (result) {
                return R.success("删除成功");
            }
            return R.fail("删除失败");
        } catch (IllegalArgumentException e) {
            log.warn("删除运动器材设施失败，参数验证失败：{}", e.getMessage());
            return R.fail(e.getMessage());
        } catch (Exception e) {
            log.error("SportsEquipmentFacilityController.deleteFacility异常", e);
            return R.fail(e.getMessage());
        }
    }

    @ApiOperation("查询指定店铺按分类汇总的设备信息（包含设备数量、图片列表和设备列表）（用户端）")
    @ApiOperationSupport(order = 8)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeId", value = "门店ID", dataType = "int", paramType = "query", required = true)
    })
    @GetMapping("/categorySummary")
    public R<List<SportsEquipmentFacilityCategorySummaryVo>> getCategorySummary(@RequestParam Integer storeId) {
        log.info("SportsEquipmentFacilityController.getCategorySummary，storeId={}", storeId);
        try {
            if (storeId == null || storeId <= 0) {
                log.warn("查询分类汇总失败，门店ID无效：{}", storeId);
                return R.fail("门店ID不能为空且必须大于0");
            }
            List<SportsEquipmentFacilityCategorySummaryVo> result = facilityService.getCategorySummary(storeId);
            log.info("查询分类汇总成功，storeId={}，返回分类数量：{}", storeId, result.size());
            return R.data(result);
        } catch (Exception e) {
            log.error("查询分类汇总异常，storeId={}，异常信息：{}", storeId, e.getMessage(), e);
            return R.fail("查询失败：" + e.getMessage());
        }
    }



    @ApiOperation("根据ID查询运动器材设施详情（商户端）")
    @ApiOperationSupport(order = 9)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "主键ID", dataType = "int", paramType = "query", required = true)
    })
    @GetMapping("/storeDetail")
    public R<SportsEquipmentFacilityVo> getStoreDetail(@RequestParam Integer id) {
        log.info("SportsEquipmentFacilityController.getStoreDetail?id={}", id);
        SportsEquipmentFacilityVo vo = facilityService.getStoreDetail(id);
        if (vo == null) {
            return R.fail("数据不存在");
        }
        return R.data(vo);
    }

    @ApiOperation("查询指定店铺按分类汇总的设备信息（包含设备数量、图片列表和设备列表）（商户端）")
    @ApiOperationSupport(order = 10)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeId", value = "门店ID", dataType = "int", paramType = "query", required = true)
    })
    @GetMapping("/storeCategorySummary")
    public R<List<SportsEquipmentFacilityCategoryVo>> getStoreCategorySummary(@RequestParam Integer storeId) {
        log.info("SportsEquipmentFacilityController.getStoreCategorySummary?storeId={}", storeId);
        return R.data(facilityService.getstoreCategorySummary(storeId));
    }

    @ApiOperation("保存分类下的实景图片（商户端）- 设施列表通过添加接口已保存，此接口仅保存图片")
    @ApiOperationSupport(order = 11)
    @PostMapping("/saveCategoryImages")
    public R<Boolean> saveCategoryImages(@RequestBody SportsEquipmentFacilityCategoryVo vo) {
        log.info("SportsEquipmentFacilityController.saveCategoryImages?storeId={},facilityCategory={},imageList={}", 
                vo.getStoreId(), vo.getFacilityCategory(), vo.getImageList());
        try {
            boolean result = facilityService.saveCategoryImages(vo.getStoreId(), vo.getFacilityCategory(), vo.getImageList());
            if (result) {
                return R.success("保存成功");
            }
            return R.fail("保存失败");
        } catch (Exception e) {
            log.error("SportsEquipmentFacilityController.saveCategoryImages异常", e);
            return R.fail(e.getMessage());
        }
    }

    /**
     * 查询失败消息
     */
    private static final String QUERY_FAIL_MSG = "查询失败";
    
    /**
     * 门店ID无效消息
     */
    private static final String INVALID_STORE_ID_MSG = "门店ID不能为空且必须大于0";
    
    /**
     * 最小有效值
     */
    private static final int MIN_VALID_VALUE = 1;
    
    @ApiOperation("查询分类的设备详情（用户端）- 包含图片列表、各子分类的设备数量汇总、设备列表。facilityCategoryName为空时返回所有分类，equipmentType为空时返回所有类型")
    @ApiOperationSupport(order = 12)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeId", value = "门店ID", dataType = "Integer", paramType = "query", required = true),
            @ApiImplicitParam(name = "facilityCategoryName", value = "设施分类名称（商户自定义），可选，为空时返回所有分类", dataType = "String", paramType = "query", required = false),
            @ApiImplicitParam(name = "equipmentType", value = "设备类型(1:心肺训练, 2:核心训练, 3:臀腿训练, 4:上肢训练, 5:全身训练, 6:其他)，可选，为空时返回所有类型", dataType = "Integer", paramType = "query", required = false)
    })
    @GetMapping("/categoryDetail")
    public R<List<FitnessEquipmentCategoryDetailVo>> getCategoryDetail(
            @RequestParam("storeId") Integer storeId,
            @RequestParam(required = false) String facilityCategoryName,
            @RequestParam(required = false) Integer equipmentType) {
        log.info("查询分类的设备详情（用户端），storeId={}，facilityCategoryName={}，equipmentType={}", 
                storeId, facilityCategoryName, equipmentType);
        try {
            // 参数验证
            if (storeId == null || storeId < MIN_VALID_VALUE) {
                log.warn("查询分类详情失败，门店ID无效：{}", storeId);
                return R.fail(INVALID_STORE_ID_MSG);
            }
            
            List<FitnessEquipmentCategoryDetailVo> resultList = facilityService.getCategoryDetail(storeId, facilityCategoryName, equipmentType);
            
            // 统计总设备数量（从equipmentTypeList中统计）
            int totalEquipmentCount = 0;
            if (resultList != null) {
                for (FitnessEquipmentCategoryDetailVo vo : resultList) {
                    if (vo.getEquipmentTypeList() != null) {
                        totalEquipmentCount += vo.getEquipmentTypeList().stream()
                                .mapToInt(typeVo -> typeVo.getEquipmentList() != null ? typeVo.getEquipmentList().size() : 0)
                                .sum();
                    }
                }
            }
            log.info("查询分类详情成功，storeId={}，facilityCategoryName={}，equipmentType={}，返回分类数量：{}，总设备数量：{}", 
                    storeId, facilityCategoryName, equipmentType, resultList != null ? resultList.size() : 0, totalEquipmentCount);
            return R.data(resultList);
        } catch (Exception e) {
            log.error("查询分类详情异常，storeId={}，facilityCategoryName={}，equipmentType={}，异常信息：{}", 
                    storeId, facilityCategoryName, equipmentType, e.getMessage(), e);
            return R.fail(QUERY_FAIL_MSG + "：" + e.getMessage());
        }
    }
}

