package org.springblade.modules.api.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import org.springblade.common.base.BaseEntity;
import org.springblade.common.constant.CommonConstant;
import org.springblade.common.utils.DistanceUtils;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.business.entity.Facility;
import org.springblade.modules.business.entity.Shop;
import org.springblade.modules.business.service.IFacilityService;
import org.springblade.modules.business.service.IShopService;
import org.springblade.modules.business.vo.ShopVO;
import org.springblade.modules.business.wrapper.ShopWrapper;
import org.springblade.modules.system.service.IUserMerchantService;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;

@RestController
@AllArgsConstructor
@RequestMapping(CommonConstant.API_URL + "/shop")
@Api(value = "门店管理接口", tags = "门店管理接口")
public class ApiShopController extends BaseController {

    private final IShopService iShopService;
    private final IFacilityService iFacilityService;
    private final IUserMerchantService iUserMerchantService;

    @PostMapping("/add")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "添加门店", notes = "传入shop")
    public R<Void> save(@Valid @RequestBody Shop shop) {
        shop.setMerchantId(AuthUtil.getUserId());

        //添加设备门店关联
        List<Facility> facilityList = iFacilityService.lambdaQuery()
                .in(Facility::getId, Func.toLongList(shop.getFacilityIds()))
                .list();
        facilityList.forEach((item)->item.setShopId(shop.getId()));
        iFacilityService.updateBatchById(facilityList);

        return R.status(iShopService.save(shop));
    }

    @PostMapping("/update")
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "修改门店", notes = "传入shop")
    public R<Void> update(@Valid @RequestBody Shop shop) {

        //删除门店关联设备
        iFacilityService.lambdaUpdate()
                .set(Facility::getShopId, null)
                .eq(Facility::getShopId, shop.getId())
                .update();

        //添加设备门店关联
        List<Facility> facilityList = iFacilityService.lambdaQuery()
                .in(Facility::getId, Func.toLongList(shop.getFacilityIds()))
                .list();
        facilityList.forEach((item)->item.setShopId(shop.getId()));
        iFacilityService.updateBatchById(facilityList);

        return R.status(iShopService.updateById(shop));
    }

    /**
     * 自定义分页 门店表
     */
    @GetMapping("/page")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "分页查询门店列表", notes = "传入shop")
    public R<IPage<ShopVO>> page(ShopVO shop, Query query) {
        LambdaQueryWrapper<Shop> wrapper = Wrappers.lambdaQuery(Shop.class);
        wrapper.eq(Shop::getMerchantId, AuthUtil.getUserId());
        shop.setMerchantId(AuthUtil.getUserId());
        if (!isMerchant()) {
            wrapper.in(BaseEntity::getId, iUserMerchantService.getByUserId(AuthUtil.getUserId()));
        }
        IPage<Shop> pages = iShopService.page(Condition.getPage(query), wrapper);
        return R.data(ShopWrapper.build().pageVO(pages));
    }

    @GetMapping("/detail")
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "门店详情", notes = "传入shop")
    public R<ShopVO> detail(@ApiParam(value = "门店id", required = true) @RequestParam Long id) {
        Shop detail = iShopService.getById(id);
        return R.data(ShopWrapper.build().entityVO(detail));
    }

    /**
     * 删除 门店表
     */
    @PostMapping("/remove")
    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "删除", notes = "传入ids")
    public R<Void> remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
        return R.status(iShopService.removeByIds(Func.toLongList(ids)));
    }

    /**
     * 小程序查询所有门店，并返回距离
     */
    @GetMapping("/all")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "查询门店列表", notes = "经度纬度")
    public R<List<ShopVO>> all(@ApiParam(value = "经度", required = true) @RequestParam Double longitude,
                               @ApiParam(value = "纬度", required = true) @RequestParam Double latitude) {
        List<Shop> pages = iShopService.list(Wrappers.lambdaQuery(Shop.class).eq(Shop::getBusinessStatus, 1));
        List<ShopVO> shopVOS = ShopWrapper.build().listVO(pages);
        for (ShopVO shopVO : shopVOS) {
            shopVO.setDistance(DistanceUtils.getDistance(longitude, latitude, shopVO.getLongitude(), shopVO.getLatitude()));
        }
        return R.data(shopVOS);
    }

    @GetMapping("/getByDeviceId")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "根据设备id查询门店信息", notes = "经度纬度")
    public R<ShopVO> getByDeviceId(@ApiParam(value = "经度", required = true) @RequestParam Long deviceId) {
        Facility facility = iFacilityService.getById(deviceId);
        Assert.notNull(facility, "未找到设备信息");
        Shop shop = iShopService.getById(facility.getShopId());
        return R.data(ShopWrapper.build().entityVO(shop));
    }


    @GetMapping("/getAllShop")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "获取商家所有门店", notes = "获取商家所有门店")
    public R<List<ShopVO>> getAllShop() {
        LambdaQueryWrapper<Shop> wrapper = Wrappers.lambdaQuery(Shop.class);
        if (isMerchant()) {
            List<Long> merchantShopIds = iShopService.getMerchantShopIds(AuthUtil.getUserId());
            if (CollUtil.isEmpty(merchantShopIds)) {
                return R.data(new ArrayList<>());
            }
            wrapper.in(Shop::getId, merchantShopIds);
        } else {
            List<Long> authShopId = iUserMerchantService.getAuthShopId(AuthUtil.getUserId());
            if (CollUtil.isEmpty(authShopId)) {
                return R.data(new ArrayList<>());
            }
            wrapper.in(Shop::getId, authShopId);
        }
        return R.data(ShopWrapper.build().listVO(iShopService.list(wrapper)));
    }

}
