package com.haha.admin.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.haha.admin.annotation.RequirePermission;
import com.haha.entity.dto.BindReplenisherDTO;
import com.haha.entity.dto.ShopQueryDTO;
import com.haha.entity.dto.StatusDTO;
import com.haha.entity.dto.LinkDeviceDTO;
import com.haha.entity.dto.BatchIdsDTO;
import com.haha.common.annotation.Log;
import com.haha.common.constant.ResponseEnum;
import com.haha.common.enums.OperationType;
import com.haha.common.vo.BatchResultVO;
import com.haha.common.vo.PageResult;
import com.haha.common.vo.Result;
import com.haha.common.vo.ShopDeviceVO;
import com.haha.common.vo.ShopSelectVO;
import com.haha.common.vo.ShopStatisticsVO;
import com.haha.entity.Shop;
import com.haha.entity.Device;
import com.haha.entity.Replenisher;
import com.haha.service.ShopService;
import com.haha.service.DeviceService;
import com.haha.service.ReplenisherService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 门店管理控制器
 */
@Slf4j
@RestController
@RequestMapping("/shops")
@RequiredArgsConstructor
public class ShopController {

    private final ShopService shopService;
    private final DeviceService deviceService;
    private final ReplenisherService replenisherService;

    /**
     * 分页查询门店列表
     * @param queryDTO 查询参数
     * @return 门店列表
     */
    @RequirePermission("shop:read")
    @GetMapping("/list")
    public Result<PageResult<Shop>> list(ShopQueryDTO queryDTO) {
        queryDTO.validate();
        
        Map<String, Object> params = new HashMap<>();
        params.put("name", queryDTO.getName());
        params.put("city", queryDTO.getCity());
        params.put("status", queryDTO.getStatus());
        
        IPage<Shop> shopPage = shopService.getPage(queryDTO.getPage(), queryDTO.getPageSize(), params);

        return Result.success("查询成功", PageResult.of(shopPage));
    }

    /**
     * 获取门店详情
     * @param id 门店ID
     * @return 门店详情
     */
    @RequirePermission("shop:read")
    @GetMapping("/{id}")
    public Result<Shop> getById(@PathVariable Long id) {
        Shop shop = shopService.getShopWithStats(id);
        if (shop == null) {
            return ResponseEnum.SHOP_NOT_FOUND.toResult();
        }
        return Result.success("查询成功", shop);
    }

    /**
     * 获取门店统计数据
     * @return 统计数据
     */
    @RequirePermission("shop:read")
    @GetMapping("/statistics")
    public Result<ShopStatisticsVO> getStatistics() {
        ShopStatisticsVO statistics = shopService.getStatistics();
        return Result.success("查询成功", statistics);
    }

    /**
     * 获取所有启用的门店（下拉选择用）
     * @return 门店列表
     */
    @RequirePermission("shop:read")
    @GetMapping("/enabled")
    public Result<List<ShopSelectVO>> getEnabledShops() {
        List<ShopSelectVO> shops = shopService.getAllEnabledShops();
        return Result.success("查询成功", shops);
    }

    /**
     * 新增门店
     * @param shop 门店信息
     * @return 新增后的门店
     */
    @RequirePermission("shop:create")
    @Log(module = "门店管理", operation = OperationType.INSERT, summary = "新增门店")
    @PostMapping
    public Result<Shop> create(@RequestBody Shop shop) {
        Shop created = shopService.createShop(shop);
        return Result.success("创建成功", created);
    }

    /**
     * 编辑门店
     * @param id 门店ID
     * @param shop 门店信息
     * @return 编辑后的门店
     */
    @RequirePermission("shop:update")
    @Log(module = "门店管理", operation = OperationType.UPDATE, summary = "编辑门店")
    @PutMapping("/{id}")
    public Result<Shop> update(@PathVariable Long id, @RequestBody Shop shop) {
        shop.setId(id);
        Shop updated = shopService.updateShop(shop);
        return Result.success("更新成功", updated);
    }

    /**
     * 删除门店
     * @param id 门店ID
     * @return 操作结果
     */
    @RequirePermission("shop:delete")
    @Log(module = "门店管理", operation = OperationType.DELETE, summary = "删除门店")
    @DeleteMapping("/{id}")
    public Result<String> delete(@PathVariable Long id) {
        // 检查门店是否有设备
        Shop shop = shopService.getShopWithStats(id);
        if (shop == null) {
            return ResponseEnum.SHOP_NOT_FOUND.toResult();
        }
        
        if (shop.getDeviceCount() != null && shop.getDeviceCount() > 0) {
            return ResponseEnum.STATUS_NOT_ALLOWED.toResult("该门店下存在设备，无法删除");
        }
        
        shopService.removeById(id);
        return Result.success("删除成功");
    }

    /**
     * 切换门店状态
     * @param id 门店ID
     * @param dto 状态参数
     * @return 操作结果
     */
    @RequirePermission("shop:update")
    @Log(module = "门店管理", operation = OperationType.UPDATE, summary = "切换门店状态")
    @PutMapping("/{id}/status")
    public Result<String> toggleStatus(@PathVariable Long id, @RequestBody StatusDTO dto) {
        boolean result = shopService.toggleStatus(id, dto.getStatus());
        
        if (result) {
            return Result.success("状态更新成功");
        } else {
            return Result.error(500, "状态更新失败");
        }
    }

    /**
     * 获取门店下的设备列表
     * @param id 门店ID
     * @return 设备列表
     */
    @RequirePermission("shop:read")
    @GetMapping("/{id}/devices")
    public Result<List<ShopDeviceVO>> getDevices(@PathVariable Long id) {
        List<ShopDeviceVO> devices = shopService.getDevicesByShopId(id);
        return Result.success("查询成功", devices);
    }

    /**
     * 将设备关联到门店
     * @param id 门店ID
     * @param dto 设备ID参数
     * @return 操作结果
     */
    @RequirePermission("shop:update")
    @Log(module = "门店管理", operation = OperationType.UPDATE, summary = "关联设备到门店")
    @PostMapping("/{id}/devices")
    public Result<String> linkDevice(@PathVariable Long id, @RequestBody LinkDeviceDTO dto) {
        boolean result = shopService.linkDevice(id, dto.getDeviceId());
        if (result) {
            return Result.success("关联成功");
        } else {
            return Result.error(500, "关联失败");
        }
    }

    /**
     * 批量将设备关联到门店
     * @param id 门店ID
     * @param dto 设备ID列表参数
     * @return 操作结果
     */
    @RequirePermission("shop:update")
    @Log(module = "门店管理", operation = OperationType.UPDATE, summary = "批量关联设备到门店")
    @PostMapping("/{id}/devices/batch")
    public Result<BatchResultVO> batchLinkDevices(@PathVariable Long id, @RequestBody BatchIdsDTO dto) {
        int count = shopService.batchLinkDevices(id, dto.getIds());
        
        BatchResultVO result = BatchResultVO.builder()
                .success(count)
                .total(dto.getIds().size())
                .build();
        
        return Result.success("批量关联完成", result);
    }

    /**
     * 从门店移除设备关联
     * @param id 门店ID
     * @param deviceId 设备ID
     * @return 操作结果
     */
    @RequirePermission("shop:update")
    @Log(module = "门店管理", operation = OperationType.UPDATE, summary = "移除门店设备关联")
    @DeleteMapping("/{id}/devices/{deviceId}")
    public Result<String> unlinkDevice(@PathVariable Long id, @PathVariable Long deviceId) {
        boolean result = shopService.unlinkDevice(id, deviceId);
        if (result) {
            return Result.success("移除成功");
        } else {
            return Result.error(500, "移除失败");
        }
    }

    /**
     * 批量移除设备关联
     * @param id 门店ID
     * @param dto 设备ID列表参数
     * @return 操作结果
     */
    @RequirePermission("shop:update")
    @Log(module = "门店管理", operation = OperationType.UPDATE, summary = "批量移除设备关联")
    @DeleteMapping("/{id}/devices/batch")
    public Result<BatchResultVO> batchUnlinkDevices(@PathVariable Long id, @RequestBody BatchIdsDTO dto) {
        int count = shopService.batchUnlinkDevices(id, dto.getIds());
        
        BatchResultVO result = BatchResultVO.builder()
                .success(count)
                .total(dto.getIds().size())
                .build();
        
        return Result.success("批量移除完成", result);
    }

    /**
     * 获取未关联门店的设备列表
     * @return 设备列表
     */
    @RequirePermission("shop:read")
    @GetMapping("/unlinked-devices")
    public Result<List<Device>> getUnlinkedDevices() {
        List<Device> devices = deviceService.getUnlinkedDevices();
        return Result.success("查询成功", devices);
    }

    // ==================== 补货员管理（V2 独立补货员体系） ====================

    /**
     * 获取门店关联的补货员列表（通过设备绑定反向推导）
     *
     * @param id 门店ID
     * @return 补货员列表（来自独立补货员表）
     */
    @RequirePermission("shop:read")
    @GetMapping("/{id}/replenishers")
    public Result<List<Replenisher>> getReplenishers(@PathVariable Long id) {
        List<Replenisher> replenishers = replenisherService.getReplenishersByShopId(id);
        return Result.success("查询成功", replenishers);
    }

    /**
     * 将独立补货员绑定到门店下的所有设备
     *
     * @param id  门店ID
     * @param dto 补货员ID
     * @return 操作结果
     */
    @RequirePermission("shop:update")
    @Log(module = "门店管理", operation = OperationType.INSERT, summary = "绑定补货员到门店")
    @PostMapping("/{id}/replenishers")
    public Result<Void> addReplenisherToShop(@PathVariable Long id, @RequestBody BindReplenisherDTO dto) {
        // 查询门店下的所有设备
        List<Device> devices = deviceService.lambdaQuery().eq(Device::getShopId, id).list();
        if (devices.isEmpty()) {
            return Result.error(400, "该门店下没有设备，无法绑定补货员");
        }
        List<String> deviceIds = devices.stream().map(Device::getDeviceId).collect(Collectors.toList());
        replenisherService.bindDevices(dto.getReplenisherId(), deviceIds);
        log.info("将补货员绑定到门店所有设备: replenisherId={}, shopId={}, deviceCount={}",
                dto.getReplenisherId(), id, deviceIds.size());
        return Result.success("绑定成功");
    }
}
