
package com.tmerclub.cloud.delivery.controller.multishop;

import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.hutool.core.util.StrUtil;
import com.tmerclub.cloud.api.auth.constant.SysTypeEnum;
import com.tmerclub.cloud.api.auth.dto.AuthAccountDTO;
import com.tmerclub.cloud.api.auth.feign.AccountFeignClient;
import com.tmerclub.cloud.api.auth.vo.AuthAccountVO;
import com.tmerclub.cloud.api.delivery.vo.StationVO;
import com.tmerclub.cloud.api.platform.constant.OfflineHandleEventType;
import com.tmerclub.cloud.api.platform.dto.OfflineHandleEventDTO;
import com.tmerclub.cloud.api.platform.feign.OfflineHandleEventFeignClient;
import com.tmerclub.cloud.api.platform.vo.OfflineHandleEventVO;
import com.tmerclub.cloud.api.product.feign.StockPointFeignClient;
import com.tmerclub.cloud.api.product.feign.TakeStockFeignClient;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.database.dto.PageDTO;
import com.tmerclub.cloud.common.database.vo.PageVO;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.leaf.manager.SegmentManager;
import com.tmerclub.cloud.common.order.constant.StockModeEnum;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.common.security.AuthUserContext;
import com.tmerclub.cloud.common.util.BeanUtil;
import com.tmerclub.cloud.common.util.IpHelper;
import com.tmerclub.cloud.common.util.PrincipalUtil;
import com.tmerclub.cloud.constant.DistributedIdKey;
import com.tmerclub.cloud.delivery.dto.StationDTO;
import com.tmerclub.cloud.delivery.model.Station;
import com.tmerclub.cloud.delivery.service.StationService;
import com.tmerclub.cloud.order.service.AllotOrderService;
import com.tmerclub.cloud.order.service.PurchaseOrderService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;

/**
 * 自提点信息
 *
 * @author tmerclub
 * @date 2020-12-07 15:10:01
 */
@RestController("multishopStationController")
@RequestMapping("/m/station")
@Tag(name = "[商家端]自提点信息")
public class StationController {

    @Value("${tmerclub.expose.permission:}")
    private Boolean permission;
    @DubboReference
    private AccountFeignClient accountFeignClient;
    @DubboReference
    private OfflineHandleEventFeignClient offlineHandleEventFeignClient;
    @Autowired
    private SegmentManager segmentManager;
    @Autowired
    private StationService stationService;
    @Autowired
    private AllotOrderService allotOrderService;
    @Autowired
    private PurchaseOrderService purchaseOrderService;
    @DubboReference
    private StockPointFeignClient stockPointFeignClient;
    @DubboReference
    private TakeStockFeignClient takeStockFeignClient;

    @GetMapping("/page")
    @Operation(summary = "获取自提点信息列表", description = "分页获取自提点信息列表")
    public ServerResponseEntity<PageVO<StationVO>> page(@Valid PageDTO pageDTO, StationDTO stationDTO) {
        Long shopId = AuthUserContext.get().getTenantId();
        stationDTO.setShopId(shopId);
        PageVO<StationVO> stationPage = stationService.pageStation(pageDTO, stationDTO);
        for (StationVO stationVO : stationPage.getList()) {
            if (StrUtil.isNotBlank(stationVO.getMobile()) && PrincipalUtil.isMobile(stationVO.getMobile())) {
                stationVO.setMobile(PhoneUtil.hideBetween(stationVO.getMobile()).toString());
            }
        }
        return ServerResponseEntity.success(stationPage);
    }

    @GetMapping
    @Operation(summary = "获取自提点信息", description = "根据stationId获取自提点信息")
    public ServerResponseEntity<StationVO> getByStationId(@RequestParam Long stationId) {
        StationVO stationVO = stationService.getByStationId(stationId);
        if (stationVO != null && stationVO.getStatus() == -1) {
            stationVO = null;
        }
        if (Objects.nonNull(stationVO) && StrUtil.isNotBlank(stationVO.getMobile()) && PrincipalUtil.isMobile(stationVO.getMobile())) {
            stationVO.setMobile(PhoneUtil.hideBetween(stationVO.getMobile()).toString());
        }
        return ServerResponseEntity.success(stationVO);
    }

    @PostMapping
    @Operation(summary = "保存自提点信息", description = "保存自提点信息")
    public ServerResponseEntity<Void> save(@Valid @RequestBody StationDTO stationDTO) {
        Station station = BeanUtil.map(stationDTO, Station.class);
        station.setShopId(AuthUserContext.get().getTenantId());
        station.setStationId(null);
        station.setAccount(null);
        station.setStockMode(station.getStockMode() == null ? StockModeEnum.ALL_STOCK.value() : station.getStockMode());
        stationService.save(station);
        return ServerResponseEntity.success();
    }

    @PutMapping
    @Operation(summary = "更新自提点信息", description = "更新自提点信息")
    public ServerResponseEntity<Void> update(@Valid @RequestBody StationDTO stationDTO) {
        Station station = BeanUtil.map(stationDTO, Station.class);
        station.setAccount(null);
        stationService.update(station);
        return ServerResponseEntity.success();
    }

    @DeleteMapping
    @Operation(summary = "删除自提点信息", description = "根据自提点信息id删除自提点信息")
    public ServerResponseEntity<Void> delete(@RequestParam Long stationId) {
        StationVO stationVO = stationService.getByStationId(stationId);
        int count = stockPointFeignClient.countStockList(stationId).getData();
        if (count > 0) {
            throw new LuckException("当前门店存在商品库存，不可删除");
        }
        // 检查采购订单
        Long unFinishCount = purchaseOrderService.countUnFinish(stationId);
        if (unFinishCount > 0) {
            throw new LuckException("存在未完成的采购订单，不可删除");
        }
        // 检查调拨订单
        unFinishCount = allotOrderService.countUnFinish(stationId);
        if (unFinishCount > 0) {
            throw new LuckException("存在未完成的调拨订单，不可删除");
        }
        // 检查实物盘点
        unFinishCount = takeStockFeignClient.countUnFinish(stationId);
        if (unFinishCount > 0) {
            throw new LuckException("存在未完成的实物盘点，不可删除");
        }
        if(Objects.nonNull(stationVO.getAccount())) {
            // 删除账号
            accountFeignClient.deleteByTenantIdAndSysType(stationId, SysTypeEnum.STATION.value());
        }
        // 删除门店
        stationService.logicDeleteById(stationId);
        return ServerResponseEntity.success();
    }

    @PostMapping("/createAccount")
    @Operation(summary = "创建自提门店账号", description = "创建自提门店账号")
    public ServerResponseEntity<Void> createAccount(@RequestBody StationDTO stationDTO) {
        // 创建账号
        AuthAccountDTO authAccountDTO = new AuthAccountDTO();
        authAccountDTO.setUsername(stationDTO.getAccount());
        authAccountDTO.setPassword(stationDTO.getPassword());
        authAccountDTO.setStatus(1);
        authAccountDTO.setSysType(SysTypeEnum.STATION.value());
        authAccountDTO.setIsAdmin(1);
        authAccountDTO.setTenantId(stationDTO.getStationId());
        authAccountDTO.setCreateIp(IpHelper.getIpAddr());
        authAccountDTO.setUserId(segmentManager.getSegmentId(DistributedIdKey.tmerclub_STATION_USER));
        ServerResponseEntity<Long> response = accountFeignClient.save(authAccountDTO);
        if (!response.isSuccess()) {
            return ServerResponseEntity.showFailMsg(response.getMsg());
        }
        // 更新门店信息
        Station station = new Station();
        station.setStationId(stationDTO.getStationId());
        station.setAccount(stationDTO.getAccount());
        stationService.update(station);
        return ServerResponseEntity.success();
    }

    @PutMapping("/changeAccountInfo")
    @Operation(summary = "账号密码设置", description = "账号密码设置")
    public ServerResponseEntity<Void> changeAccountInfo(@RequestBody StationDTO stationDTO) {
        // 检查是否有权限
        if (Objects.equals(stationDTO.getStationId(), Constant.ON_LINE_STATION_ID) && BooleanUtil.isFalse(permission)) {
            throw new LuckException("没有权限进行操作");
        }
        // 更新账号密码
        AuthAccountVO accountVO = accountFeignClient.getAccountInfoByTenantId(stationDTO.getStationId(), SysTypeEnum.STATION.value()).getData();
        if (accountVO == null) {
            throw new LuckException("账号不存在");
        }
        AuthAccountDTO authAccountDTO = new AuthAccountDTO();
        BeanUtils.copyProperties(accountVO, authAccountDTO);
        authAccountDTO.setUsername(stationDTO.getAccount());
        authAccountDTO.setPassword(stationDTO.getPassword());
        authAccountDTO.setSysType(SysTypeEnum.STATION.value());
        accountFeignClient.update(authAccountDTO);
        // 更新门店信息
        Station station = new Station();
        station.setStationId(stationDTO.getStationId());
        station.setAccount(stationDTO.getAccount());
        stationService.update(station);
        return ServerResponseEntity.success();
    }

    @GetMapping("/checkStationAccount")
    @Operation(summary = "校验账号")
    @Parameters({
            @Parameter(name = "stationId", description = "自提点id"),
            @Parameter(name = "account", description = "自提点账号")
    })
    public ServerResponseEntity<Boolean> checkStationAccount(@RequestParam("stationId") Long stationId,
                                                             @RequestParam("account") String account) {
        AuthAccountVO accountVO;
        try {
            accountVO = accountFeignClient.getAccountInfoByTenantId(stationId, SysTypeEnum.STATION.value()).getData();
        } catch (Exception e) {
            accountVO = null;
        }
        Integer count = accountFeignClient.countByUserNameAndSysType(account, SysTypeEnum.STATION.value()).getData();
        count = (accountVO != null && accountVO.getUsername().equals(account)) ? count - 1 : count;
        if (count > 0) {
            return ServerResponseEntity.success(false);
        }
        return ServerResponseEntity.success(true);
    }

    @GetMapping("/getOfflineHandleEvent/{stationId}")
    @Operation(summary = "通过自提点id获取下线信息")
    @Parameter(name = "stationId", description = "自提点id", required = true)
    public ServerResponseEntity<OfflineHandleEventVO> getOfflineHandleEventByStationId(@PathVariable("stationId") Long stationId) {
        OfflineHandleEventVO offlineHandleEventVO = offlineHandleEventFeignClient.getProcessingEventByHandleTypeAndHandleId(OfflineHandleEventType.STATION.getValue(), stationId, null).getData();
        return ServerResponseEntity.success(offlineHandleEventVO);
    }

    @PostMapping("/auditApply")
    @Operation(summary = "下线自提点提交审核")
    public ServerResponseEntity<Void> auditApply(@RequestBody OfflineHandleEventDTO eventDTO) {
        StationVO stationVO = stationService.getByStationId(eventDTO.getHandleId());
        if (stationVO == null) {
            // 未找到该自提点信息
            throw new LuckException("未找到相应门店");
        }
        offlineHandleEventFeignClient.updateToApply(eventDTO);
        // 更新门店状态
        Station station = new Station();
        station.setStationId(eventDTO.getHandleId());
        station.setStatus(3);
        stationService.update(station);
        return ServerResponseEntity.success();
    }

    @GetMapping("/stationPage")
    @Operation(summary = "获取自提点列表", description = "获取自提点列表")
    public ServerResponseEntity<List<StationVO>> page() {
        Long shopId = AuthUserContext.get().getTenantId();
        return ServerResponseEntity.success(stationService.listByShopId(shopId));
    }

    @PutMapping("/switchStationStockMode")
    @Operation(summary = "切换门店库存模式", description = "切换门店库存模式")
    @Parameters({
            @Parameter(name = "stationId", description = "门店id"),
            @Parameter(name = "type", description = "更新共享库存模式（1同步到默认仓库 2库存清零）")
    })
    public ServerResponseEntity<Void> switchStationStockMode(@RequestParam("stationId") Long stationId, @RequestParam(value = "type", required = false) Integer type) {
        stationService.switchStationStockMode(stationId, type);
        return ServerResponseEntity.success();
    }
}
