package jnpf.store.controller;

import com.alibaba.nacos.common.utils.StringUtils;
import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jnpf.base.ActionResult;
import jnpf.base.vo.PageListVO;
import jnpf.doclibrary.StoreApi;
import jnpf.entity.StoreEntity;
import jnpf.exception.HandleException;
import jnpf.model.attendance.dto.UpdateStoreDto;
import jnpf.model.store.Store;
import jnpf.model.store.StorePositionInfoVo;
import jnpf.model.store.StoreUserNumVo;
import jnpf.model.store.dto.*;
import jnpf.model.store.vo.StoreBaseListVO;
import jnpf.model.store.vo.StoreLocationVO;
import jnpf.model.store.vo.StoreUsersVo;
import jnpf.model.store.vo.UserStoreListVo;
import jnpf.model.vo.StoreExecutionVo;
import jnpf.store.service.StoreService;
import jnpf.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

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


/**
 * 门店管理
 *
 * @版本： V3.1.0
 * @版权： 引迈信息技术有限公司（https://www.jnpfsoft.com）
 * @作者： JNPF开发平台组
 * @日期： 2023-07-11
 */
@Slf4j
@RestController("ftbStoreController")
@Tag(name = "门店管理", description = "Store")
@RequestMapping("/Store")
public class StoreController implements StoreApi {
    @Autowired
    private StoreService storeService;
    @Autowired
    private CustomTenantUtil customTenantUtil;

    /**
     * 查询门店下岗位的成员数量
     *
     * @param storeId      门店id
     * @param positionList 岗位id集合
     * @return java.util.List<jnpf.model.store.StorePositionInfoVo>
     */
    @Override
    @GetMapping(value = "/storePositionInfo/list")
    public List<StorePositionInfoVo> getStorePositionInfoList(@RequestParam(value = "storeId") String storeId, @RequestParam(value = "positionList") List<String> positionList) {

        return storeService.getStorePositionInfoList(storeId, positionList);
    }

    @Override
    @GetMapping(value = "/storePositionInfo/getUserNum")
    public List<StoreUserNumVo> getUserNum(@RequestParam(value = "storeIds") List<String> storeIds) {

        return storeService.getUserNum(storeIds);
    }

    /**
     * 检查哪些用户不能被选择
     *
     * @param currentChoose 当前选中的人
     * @param exceptChoose  需要排除的人
     * @return jnpf.base.ActionResult<java.util.List < java.lang.String>>
     */
    @GetMapping(value = "/userCantChoose")
    public ActionResult<List<String>> checkUserCantChoose(String currentChoose, @RequestParam(required = false) String exceptChoose) {

        List<String> list = storeService.checkUserCantChoose(currentChoose, exceptChoose);
        return ActionResult.success(list);
    }

    /**
     * 列表
     *
     * @return
     */
    @Override
    @Operation(summary = "获取列表")
    @GetMapping("/getList")
    public ActionResult<List<Store>> getList(@RequestParam("selectKey") String selectKey,
                                             @RequestParam(value = "organizeid", required = false) String organizeId,
                                             @RequestParam(value = "longitude", required = false) String longitude,
                                             @RequestParam(value = "latitude", required = false) String latitude) {

        // 根据组织名、门店名、地址、负责人
        // 根据经纬度范围查询
        // 根据组织id查询门店列表

        // 1.根据selectKey判断查询类型,如果为byOrganizeId,执行方法2  如果为byKeyword，执行方法3  如果为byRange，执行方法4
        // 2.判断organizeid是否为空
        //  2.1.为空，报错
        //  2.2.不为空，根据organizeid查询对应的门店列表，并根据修改时间排序
        // 4.判断经度或纬度是否为空
        //  4.1.为空，报错
        //  4.2.不为空，判断organizeid是否为空
        //   4.2.1.为空，直接查出所有门店，并根据经纬度算出距离，根据距离排序
        //   4.2.2.不为空，根据organizeid查出对应门店，并根据经纬度算出距离，根据距离排序

        if ("byOrganizeId".equals(selectKey)) {
            if (StringUtils.isEmpty(organizeId)) {
                return ActionResult.fail("组织id不能为空！");
            }
            return ActionResult.success(storeService.getStoreByOrganizeId(organizeId));
        } else if ("byRange".equals(selectKey)) {
            if (StringUtils.isEmpty(longitude) || StringUtils.isEmpty(latitude)) {
                return ActionResult.fail("经度或纬度不能为空！");
            }
            return ActionResult.success(storeService.getStoreByRange(organizeId, longitude, latitude));
        } else if ("enabled".equals(selectKey)) {
            return ActionResult.success(storeService.getStoreEnabled());
        } else {
            return ActionResult.fail("查询方式不合法！");
        }
    }

    /**
     * 查询组织下的门店
     *
     * @param organizeId 组织id
     * @return java.util.List<jnpf.model.store.Store>
     */
    @Override
    @GetMapping(value = "/list")
    public List<Store> getStoreList(@RequestParam(value = "organizeId", required = false) String organizeId) {

        return storeService.getStoreList(organizeId, null);
    }

    @Override
    @GetMapping(value = "/orgList")
    public List<Store> getOrgStoreList(@RequestParam(value = "organizeId", required = false) String organizeId, @RequestParam(value = "queryStoreIds", required = false) List<String> queryStoreIds) {

        return storeService.getOrgStoreList(organizeId, queryStoreIds);
    }

    /**
     * 查询组织下的门店
     *
     * @param organizeId 组织id
     * @return java.util.List<jnpf.model.store.Store>
     */
//    @Override
    @GetMapping(value = "/list/v2")
    public ActionResult<List<Store>> getStoreListV2(@RequestParam(value = "organizeId", required = false) String organizeId, @RequestParam(value = "storeName", required = false) String storeName) {

        return ActionResult.success(storeService.getStoreList(organizeId, storeName));
    }

    /**
     * 查询组织下的门店
     *
     * @param organizeId 组织id
     * @return java.util.List<jnpf.model.store.Store>
     */
    @GetMapping(value = "/allList")
    public ActionResult<List<Store>> getAllStoreList(@RequestParam(value = "organizeId", required = false) String organizeId) {

        List<Store> storeList = storeService.getStoreList(organizeId, null);
        return ActionResult.success(storeList);
    }


    @Operation(summary = "获取所有列表")
    @GetMapping("/getAllList")
    public ActionResult<PageListVO<Store>> getListByKeyword(@RequestParam("keyword") String keyword, int currentPage, int pageSize, @RequestParam(value = "searchStatus", required = false) String searchStatus) {
        //门店状态( 全部：-1   禁用：1   正常：0/不传入默认0正常)
        Integer searchState = 0;
        if (StringUtil.isNotEmpty(searchStatus)) {
            //字符串转成小写
            searchStatus = searchStatus.toLowerCase();
            if (searchStatus.equals("true")) {
                searchState = 1;
            } else if (searchStatus.equals("false")) {
                searchState = 0;
            } else {
                searchState = Integer.valueOf(searchStatus);
            }
        }
        PageInfo<Store> page = storeService.getStoreByKeyword(keyword, currentPage, pageSize, searchState);
        return ActionResult.page(page.getList(), FtbUtil.getPagination(page));
    }

    @Operation(summary = "获取所有门店下属值班人员")
    @GetMapping("/duty/users")
    public ActionResult<PageListVO<StoreUsersVo>> getUsersByStore(@RequestParam("keyword") String keyword, @RequestParam("currentPage") int currentPage, @RequestParam("pageSize") int pageSize) {
        PageInfo<StoreUsersVo> page = storeService.getUsersByStore(keyword, currentPage, pageSize);
        return ActionResult.page(page.getList(), FtbUtil.getPagination(page));
    }

    /**
     * 设置值班人
     *
     * @param storeUserDto 值班人设置实体
     * @return
     */
    @PostMapping("/updateStoreUsers")
    @Transactional
    @Operation(summary = "设置值班人")
    public ActionResult updateStoreUsers(@RequestBody StoreUserDto storeUserDto) {
        storeService.updateStoreUsers(storeUserDto);
        return ActionResult.success();
    }

    /**
     * 创建
     *
     * @param store
     * @return
     */
    @PostMapping
    @Transactional
    @Operation(summary = "创建")
    @Deprecated
    public ActionResult create(@RequestBody @Valid Store store) throws Exception {
        String b = storeService.checkForm(store, 0);
        if (StringUtil.isNotEmpty(b)) {
            return ActionResult.fail(b + "不能重复");
        }
        try {
            storeService.create(store);
            return ActionResult.success("创建成功");
        } catch (Exception e) {
            e.printStackTrace();
            return ActionResult.fail(e.getMessage());
        }
    }


    /**
     * 信息
     *
     * @param id
     * @return
     */
    @Operation(summary = "信息")
    @GetMapping("/{id}")
    public ActionResult<Store> info(@PathVariable("id") String id) {
        Store store = storeService.getInfo(id);
        return ActionResult.success(store);
    }

    /**
     * 查询门店信息
     *
     * @param id 门店id
     * @return jnpf.model.store.Store
     */
    @Override
    @GetMapping("/info/{id}")
    public Store getStoreInfo(@PathVariable("id") String id) {

        return storeService.getInfo(id);
    }

    /**
     * 查询门店信息值班调用fegin
     *
     * @param id 门店id
     * @return jnpf.model.store.Store
     */
    @Override
    @GetMapping("/getStoreInfoNoData")
    @NoDataSourceBind
    public StoreEntity getStoreInfoNoData(@RequestParam("id") String id, @RequestParam("tenantId") String tenantId) {
        customTenantUtil.checkOutTenant(tenantId);
        return storeService.getStoreInfoDutyQuery(id);
    }

    /**
     * 根据门店 ids 分页查询门店记录（POST，避免大量 id 撑爆 URL）
     */
    @PostMapping(value = "/store/pageByIds")
    @Override
    public PageInfo<StoreExecutionVo> getStorePageByIds(@RequestBody StorePageByIdsQueryDTO query) {
        if (query == null) {
            throw new RuntimeException("请求体不能为空");
        }
        String storeIds = joinStoreIdsForLegacyService(query.getStoreIds());
        return storeService.getStorePageByIds(storeIds, query.getStoreName(), query.getCurrentPage(), query.getPageSize(), query.getSortNum());
    }

    /**
     * 根据门店 ids 分页查询门店记录（切租户、无数据源绑定；POST）
     */
    @PostMapping(value = "/store/pageByIdsNoDataSource")
    @NoDataSourceBind
    @Override
    public PageInfo<StoreExecutionVo> getStorePageByIdsNoDataSource(@RequestBody StorePageByIdsNoDsQueryDTO query) {
        if (query == null) {
            throw new RuntimeException("请求体不能为空");
        }
        if (StringUtils.isEmpty(query.getTenantId())) {
            throw new RuntimeException("租户不能为空");
        }
        customTenantUtil.checkOutTenant(query.getTenantId());
        String storeIds = joinStoreIdsForLegacyService(query.getStoreIds());
        return storeService.getStorePageByIds(storeIds, query.getStoreName(), query.getCurrentPage(), query.getPageSize(), ConstantUtil.NUM_TRUE);
    }

    /**
     * 查询异常的门店（POST）
     */
    @PostMapping(value = "/store/abnormal/record")
    @Override
    public List<String> getAbnormalStoreIds(@RequestBody StoreAbnormalIdsQueryDTO query) {
        if (query == null) {
            return storeService.getAbnormalStoreIds(null);
        }
        return storeService.getAbnormalStoreIds(query.getStoreIds());
    }

    /**
     * 根据组织ids查询门店列表
     *
     * @param organizeIdList 组织ids
     * @return java.util.List<jnpf.model.store.Store>
     */
    @Override
    @PostMapping(value = "/store/list/byOrganizeList")
    public List<Store> getStoreListByOrganizeList(@RequestBody List<String> organizeIdList) {

        return storeService.getStoreListByOrganizeList(organizeIdList);
    }

    @GetMapping(value = "/store/checkStoreUser")
    @Override
    public boolean checkStoreUser(String userId) {

        return storeService.checkStoreUser(userId);
    }

    /**
     * 查询门店信息(未绑定数据库)
     *
     * @param tenantId 租户id
     * @param storeIds 门店ids
     * @return java.util.List<jnpf.model.store.Store>
     */
    @NoDataSourceBind
    @Override
    @GetMapping(value = "/store/list/noDataSource")
    public List<Store> getListByIdsNoDataSource(@RequestParam(value = "tenantId") String tenantId, @RequestParam(value = "storeIds") List<String> storeIds) {

        customTenantUtil.checkOutTenant(tenantId);
        return storeService.getListByIds(storeIds);
    }

    /**
     * 更新
     *
     * @param id
     * @param store
     * @return
     */
    @PutMapping("/{id}")
    @Transactional
    @Operation(summary = "更新")
    public ActionResult update(@PathVariable("id") String id, @RequestBody @Valid Store store) throws Exception {
        try {
            storeService.update(id, store);
            return ActionResult.success();
        } catch (Exception e) {
            e.printStackTrace();
            return ActionResult.fail(e.getMessage());
        }
    }

    /**
     * 获取用户门店列表信息
     *
     * @return 返回值
     */
    @Override
    @GetMapping(value = "/userStoreList")
    public ActionResult<List<Store>> getUserStoreList() {
        return ActionResult.success(storeService.getUserStoreList());
    }

    /**
     * 获取用户门店列表信息(值班)
     *
     * @return 返回值
     */
    @Override
    @GetMapping(value = "/userStoreListDuty")
    public ActionResult<List<Store>> getUserStoreListDuty() {
        return ActionResult.success(storeService.getUserStoreListDuty());
    }

    /**
     * 获取用户门店列表信息
     *
     * @return 返回值
     */
    @Override
    @GetMapping(value = "/listByUserId/{userId}")
    public List<Store> getListByUserId(@PathVariable(value = "userId") String userId) {

        return storeService.getStoreListByUser(userId);
    }

    /**
     * 获取所有用户的门店集合
     *
     * @return java.util.List<jnpf.model.store.vo.UserStoreListVo>
     * @author hlp
     */
    @Override
    @GetMapping(value = "/getAllUserStores")
    public List<UserStoreListVo> getAllUserStores() {
        return storeService.getAllUserStores();
    }

    /**
     * 根据门店ids查询门店信息
     *
     * @param storeIds 门店ids
     * @return java.util.List<jnpf.model.store.Store>
     */
    @Override
    @GetMapping(value = "/listByIds")
    public List<Store> getListByIds(@RequestParam(value = "storeIds") List<String> storeIds) {

        return storeService.getListByIds(storeIds);
    }

    /**
     * 批量新增门店
     *
     * @param batchSaveStoreDto
     * @return ActionResult<Void>
     */
    @PostMapping("/batchSaveStore")
    public ActionResult<Void> batchSaveStore(@RequestBody BatchSaveStoreDto batchSaveStoreDto) throws HandleException {
        storeService.batchSaveStore(batchSaveStoreDto);
        return ActionResult.success();
    }

    /**
     * 根据组织id查询门店
     *
     * @return
     */
    @GetMapping("/queryByOrganizeId/{id}")
    public ActionResult queryByOrganizeId(@PathVariable("id") String id) {
        List<Store> storeList = storeService.getStoreByOrganizeId(id);
        return ActionResult.success(storeList);
    }

    /**
     * 检查门店是否有门店负责人
     *
     * @return ActionResult<Boolean>
     */
    @GetMapping("/checkHeadId/{id}")
    public ActionResult<Boolean> checkHeadId(@PathVariable("id") String id) {
        Boolean isHasHead = storeService.checkStore(id);
        return ActionResult.success(isHasHead);
    }

    /**
     * 改变门店状态 禁用/启用
     *
     * @param id             门店id
     * @param updateStoreDto 是否禁用 1.是 0.否
     * @return ActionResult<Void>
     */
    @PutMapping("/updateStatus/{id}")
    public ActionResult<Void> updateStatus(@PathVariable("id") String id, @RequestBody UpdateStoreDto updateStoreDto) {
        storeService.updateStatus(id, updateStoreDto.getDisabled());
        return ActionResult.success();
    }

    /**
     * 根据组织id获取所有门店（包括禁用门店）
     *
     * @param organizeId 组织id
     * @return ActionResult<List < Store>>
     */
    @GetMapping("/getAllStoreByOrgId/{organizeId}")
    public ActionResult<List<Store>> getAllByOrgId(@PathVariable("organizeId") String organizeId) {
        List<Store> allStoreByOrganizeId = storeService.getAllStoreByOrganizeId(organizeId);
        return ActionResult.success(allStoreByOrganizeId);
    }

    @Override
    @Operation(description = "[列表] 目标组织,及其子组织所有已启用的门店")
    @GetMapping(value = "/store/list/organizeChildren")
    public ActionResult<List<StoreBaseListVO>> getStoreListByOrganizeIdAndChildOrganize(@RequestParam(value = "organizeId") String organizeId, @RequestParam(required = false, value = "disabled") Boolean disabled) {
        if (disabled == null) {
            disabled = false;
        }
        return ActionResult.success(storeService.getStoreListByOrganizeIdAndChildOrganize(organizeId, disabled));
    }

    @Override
    @GetMapping(value = "/storePositionInfo/list/nodata")
    @NoDataSourceBind
    public List<StorePositionInfoVo> getStorePositionInfoListNodata(@RequestParam(value = "storeId") String storeId, @RequestParam(value = "positionList") List<String> positionList, @RequestParam(value = "tenantId") String tenantId) {
        customTenantUtil.checkOutTenant(tenantId);
        return storeService.getStorePositionInfoListNodata(storeId, positionList, tenantId);
    }

    @Override
    @GetMapping(value = "/listByUserId/nodata/{userId}")
    @NoDataSourceBind
    public List<Store> getListByUserIdNodata(@PathVariable(value = "userId") String userId, @RequestParam(value = "tenantId") String tenantId) {
        customTenantUtil.checkOutTenant(tenantId);
        return storeService.getStoreListByUserNodata(userId, tenantId);
    }

    /**
     * 获取门店位置信息
     * @param storeId 门店id
     * @return jnpf.model.store.vo.StoreLocationVO
     */
    @Override
    @GetMapping(value = "/getStoreLocation")
    public StoreLocationVO getStoreLocation(String storeId) {
        return storeService.getStoreLocation(storeId);
    }

    /**
     * 与 {@link StoreService#getStorePageByIds(String, String, Integer, Integer, Integer)} 入参约定一致：空或全空白为「0」表示不按 id 列表过滤。
     */
    private static String joinStoreIdsForLegacyService(List<String> storeIds) {
        if (storeIds == null || storeIds.isEmpty()) {
            return "0";
        }
        if (storeIds.size() == 1 && "0".equals(storeIds.get(0))) {
            return "0";
        }
        StringBuilder sb = new StringBuilder();
        for (String id : storeIds) {
            if (id == null) {
                continue;
            }
            String t = id.trim();
            if (t.isEmpty()) {
                continue;
            }
            if (sb.length() > 0) {
                sb.append(',');
            }
            sb.append(t);
        }
        if (sb.length() == 0) {
            return "0";
        }
        return sb.toString();
    }
}
