package com.ruoyi.web.sales.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.web.base.domain.BaseLine;
import com.ruoyi.web.base.domain.BaseMarket;
import com.ruoyi.web.base.service.IBaseLineService;
import com.ruoyi.web.base.service.IBaseMarketService;
import com.ruoyi.web.sales.domain.BaseCustomer;
import com.ruoyi.web.sales.domain.RelCustomerMarket;
import com.ruoyi.web.sales.service.IBaseCustomerService;
import com.ruoyi.web.sales.service.IRelCustomerMarketService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

import static com.ruoyi.common.core.domain.AjaxResult.success;
import static com.ruoyi.common.utils.SecurityUtils.getUsername;

@RestController
@Api(tags = "客户市场维护")
@RequestMapping("/rel-customer-market")
public class RelCustomerMarketController {
    @Autowired
    private IRelCustomerMarketService relCustomerMarketService;
    @Autowired
    private IBaseCustomerService customerService;
    @Autowired
    private IBaseLineService lineService;
    @Autowired
    private IBaseMarketService marketService;
    @Autowired
    private TokenService tokenService;

    @ApiOperation("客户市场维护分页")
    @GetMapping("/page")
    public AjaxResult page(@RequestParam("pageNum") Integer pageNum,
                           @RequestParam("pageSize") Integer pageSize,
                           RelCustomerMarket query, HttpServletRequest request) {
        String orgId = tokenService.getLoginOrgId(request);
        int pn = normalizePageNum(pageNum);
        int ps = normalizePageSize(pageSize);
        String lineNum = query != null ? query.getLineNum() : null;
        String marketNum = query != null ? query.getMarketNum() : null;
        IPage<RelCustomerMarket> page = relCustomerMarketService.pageWithDetail(
                new Page<RelCustomerMarket>(pn, ps),
                orgId,
                StringUtils.isNotBlank(lineNum) ? lineNum : null,
                StringUtils.isNotBlank(marketNum) ? marketNum : null);
        return success(page);
    }

    /** 防止超大 pageSize 拖垮数据库 */
    private static int normalizePageSize(Integer pageSize) {
        if (pageSize == null || pageSize < 1) {
            return 10;
        }
        return Math.min(pageSize, 200);
    }

    private static int normalizePageNum(Integer pageNum) {
        if (pageNum == null || pageNum < 1) {
            return 1;
        }
        return pageNum;
    }

    @ApiOperation("客户市场维护新增(支持批量客户)")
    @PostMapping("/add")
    public AjaxResult add(@RequestBody Map<String, Object> params, HttpServletRequest request) throws Exception {
        String orgId = tokenService.getLoginOrgId(request);
        String marketNum = stringVal(params.get("marketNum"));
        String customerNums = stringVal(params.get("customerNums"));
        if (StringUtils.isBlank(marketNum) || StringUtils.isBlank(customerNums)) {
            throw new Exception("市场、客户不能为空");
        }
        BaseMarket market = marketService.getOne(new QueryWrapper<BaseMarket>()
                .eq("org_id", orgId)
                .eq("market_num", marketNum)
                .eq("del_flag", "0")
                .last("limit 1"));
        if (market == null) {
            throw new Exception("市场不存在");
        }
        String lineNum = market.getLineNum();
        if (StringUtils.isBlank(lineNum)) {
            throw new Exception("该市场未绑定物流线");
        }
        List<String> customerNumList = Arrays.stream(customerNums.split(","))
                .map(String::trim)
                .filter(StringUtils::isNotBlank)
                .distinct()
                .collect(Collectors.toList());
        if (customerNumList.isEmpty()) {
            throw new Exception("客户不能为空");
        }

        List<BaseCustomer> existCustomers = customerService.list(new QueryWrapper<BaseCustomer>()
                .eq("org_id", orgId)
                .eq("del_flag", "0")
                .in("customer_num", customerNumList));
        Set<String> existCustomerNums = existCustomers.stream().map(BaseCustomer::getCustomerNum).collect(Collectors.toSet());
        List<String> missingCustomerNums = customerNumList.stream().filter(num -> !existCustomerNums.contains(num)).collect(Collectors.toList());
        if (!missingCustomerNums.isEmpty()) {
            throw new Exception("以下客户编号在客户管理中不存在：" + String.join(",", missingCustomerNums));
        }

        String username = getUsername();
        Date now = new Date();
        for (String customerNum : customerNumList) {
            List<RelCustomerMarket> existRelCustomerMarkets = relCustomerMarketService.list(new QueryWrapper<RelCustomerMarket>()
                    .eq("customer_num", customerNum)
                    .eq("del_flag", "0"));
            if (StringUtils.isNotEmpty(existRelCustomerMarkets)) {
                BaseMarket dbMarket = marketService.getOne(new QueryWrapper<BaseMarket>()
                        .eq("org_id", orgId)
                        .eq("market_num", existRelCustomerMarkets.get(0).getMarketNum())
                        .eq("del_flag", "0")
                        .last("limit 1"));

                throw new Exception("市场["+ dbMarket.getMarketName() +"]下已存在编号为[" + customerNum + "]的客户");
            }
            RelCustomerMarket item = new RelCustomerMarket();
            item.setOrgId(orgId);
            item.setLineNum(lineNum);
            item.setMarketNum(marketNum);
            item.setCustomerNum(customerNum);
            item.setDelFlag("0");
            item.setCreateBy(username);
            item.setCreateTime(now);
            relCustomerMarketService.save(item);
        }
        return success();
    }

    @ApiOperation("客户市场维护删除")
    @PostMapping("/delete")
    public AjaxResult delete(@RequestBody Map<String, String> params) {
        String ids = params.get("ids");
        String username = getUsername();
        Date now = new Date();
        for (String id : ids.split(",")) {
            RelCustomerMarket item = new RelCustomerMarket();
            item.setId(Integer.valueOf(id));
            item.setDelFlag("2");
            item.setUpdateBy(username);
            item.setUpdateTime(now);
            relCustomerMarketService.updateById(item);
        }
        return success();
    }

    @ApiOperation("客户调市场")
    @PostMapping("/move")
    public AjaxResult move(@RequestBody Map<String, Object> params) throws Exception {
        String id = stringVal(params.get("id"));
        String newMarketNum = StringUtils.trimToNull(stringVal(params.get("newMarketNum")));
        if (StringUtils.isBlank(id) || newMarketNum == null) {
            throw new Exception("请传入 id、newMarketNum");
        }
        RelCustomerMarket item = relCustomerMarketService.getById(id);
        if (item == null || !"0".equals(item.getDelFlag())) {
            throw new Exception("记录不存在");
        }
        BaseMarket newMarket = marketService.getOne(new QueryWrapper<BaseMarket>()
                .eq("org_id", item.getOrgId())
                .eq("market_num", newMarketNum)
                .eq("del_flag", "0")
                .last("limit 1"));
        if (newMarket == null) {
            throw new Exception("新市场不存在");
        }
        if (StringUtils.isBlank(newMarket.getLineNum())) {
            throw new Exception("新市场未绑定物流线");
        }
        long exists = relCustomerMarketService.count(new QueryWrapper<RelCustomerMarket>()
                .ne("id", item.getId())
                .eq("org_id", item.getOrgId())
                .eq("customer_num", item.getCustomerNum())
                .eq("market_num", newMarketNum)
                .eq("del_flag", "0"));
        if (exists > 0) {
            throw new Exception("目标市场已存在该客户");
        }
        item.setLineNum(newMarket.getLineNum());
        item.setMarketNum(newMarketNum);
        item.setUpdateBy(getUsername());
        item.setUpdateTime(new Date());
        return success(relCustomerMarketService.updateById(item));
    }

    @ApiOperation("客户市场维护导出")
    @PostMapping("/export")
    public void export(HttpServletResponse response, RelCustomerMarket query, HttpServletRequest request) {
        String orgId = tokenService.getLoginOrgId(request);
        QueryWrapper<RelCustomerMarket> wrapper = new QueryWrapper<RelCustomerMarket>()
                .eq("org_id", orgId)
                .eq("del_flag", "0");
        if (StringUtils.isNotBlank(query.getLineNum())) {
            wrapper.eq("line_num", query.getLineNum());
        }
        if (StringUtils.isNotBlank(query.getMarketNum())) {
            wrapper.eq("market_num", query.getMarketNum());
        }
        List<RelCustomerMarket> list = relCustomerMarketService.list(wrapper);
        fillDisplayFields(list, orgId);
        ExcelUtil<RelCustomerMarket> util = new ExcelUtil<RelCustomerMarket>(RelCustomerMarket.class);
        util.exportExcel(response, list, "客户市场维护数据");
    }

    private void fillDisplayFields(List<RelCustomerMarket> records, String orgId) {
        if (records == null || records.isEmpty()) {
            return;
        }
        Set<String> customerNums = records.stream().map(RelCustomerMarket::getCustomerNum).collect(Collectors.toSet());
        Set<String> lineNums = records.stream().map(RelCustomerMarket::getLineNum).collect(Collectors.toSet());
        Set<String> marketNums = records.stream().map(RelCustomerMarket::getMarketNum).collect(Collectors.toSet());

        Map<String, BaseCustomer> customerMap = customerService.list(new QueryWrapper<BaseCustomer>()
                        .eq("org_id", orgId).eq("del_flag", "0").in("customer_num", customerNums))
                .stream().collect(Collectors.toMap(BaseCustomer::getCustomerNum, e -> e, (a, b) -> a));
        Map<String, BaseLine> lineMap = lineService.list(new QueryWrapper<BaseLine>()
                        .eq("org_id", orgId).eq("del_flag", "0").in("line_num", lineNums))
                .stream().collect(Collectors.toMap(BaseLine::getLineNum, e -> e, (a, b) -> a));
        Map<String, BaseMarket> marketMap = marketService.list(new QueryWrapper<BaseMarket>()
                        .eq("org_id", orgId).eq("del_flag", "0").in("market_num", marketNums))
                .stream().collect(Collectors.toMap(BaseMarket::getMarketNum, e -> e, (a, b) -> a));

        for (RelCustomerMarket item : records) {
            BaseCustomer customer = customerMap.get(item.getCustomerNum());
            if (customer != null) {
                item.setCustomerName(customer.getCustomerName());
                item.setCustomerLevel(customer.getCustomerLevel());
                item.setReceivableCustomer(customer.getReceivableCustomer());
                item.setPayeeCustomer(customer.getPayeeCustomer());
                item.setCreditControl(customer.getCreditControl());
                item.setCustomerChannel(customer.getCustomerChannel());
                item.setRemark(customer.getRemark());
            }
            BaseLine line = lineMap.get(item.getLineNum());
            if (line != null) {
                item.setLineName(line.getLineName());
            }
            BaseMarket market = marketMap.get(item.getMarketNum());
            if (market != null) {
                item.setMarketName(market.getMarketName());
            }
        }
    }

    private String stringVal(Object obj) {
        return obj == null ? null : String.valueOf(obj);
    }
}
