package com.ruoyi.web.sales.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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.sales.domain.BaseCustomer;
import com.ruoyi.web.sales.service.IBaseCustomerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;

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

/**
 * 客户管理。权限标识与菜单 sys_menu.perms、前端 v-hasPermi 一致：base:customer:list/query/add/edit/remove/export。
 * {@link #getByCustomerNum} 供销售等模块按编号引用客户，不单独校验客户菜单权限，仅需登录。
 */
@RestController
@Api(tags = "客户管理")
@RequestMapping("/base-customer")
public class BaseCustomerController {

    @Autowired
    private IBaseCustomerService baseCustomerService;
    @Autowired
    private TokenService tokenService;

    @ApiOperation("客户管理添加")
    @PreAuthorize("@ss.hasPermi('base:customer:add')")
    @PostMapping("/add")
    public AjaxResult add(@RequestBody BaseCustomer baseCustomer, HttpServletRequest request) throws Exception {
        validateCustomerLevel(baseCustomer.getCustomerLevel());
        validateQuarantineStatType(baseCustomer.getQuarantineStatType());
        validateInvoiceType(baseCustomer.getInvoiceType());
        validateSwitchValue(baseCustomer.getCreditControl(), "信用控制");
        if (baseCustomerService.count(new QueryWrapper<BaseCustomer>()
                .eq("customer_num", baseCustomer.getCustomerNum())
                .eq("del_flag", "0")) > 0) {
            throw new Exception("该编号已存在");
        }
        String loginOrgId = tokenService.getLoginOrgId(request);
        baseCustomer.setOrgId(loginOrgId);
        baseCustomer.setDelFlag("0");
        baseCustomer.setCreateBy(getUsername());
        return success(baseCustomerService.save(baseCustomer));
    }

    @ApiOperation("客户管理修改")
    @PreAuthorize("@ss.hasPermi('base:customer:edit')")
    @PostMapping("/edit")
    public AjaxResult edit(@RequestBody BaseCustomer baseCustomer, HttpServletRequest request) throws Exception {
        validateCustomerLevel(baseCustomer.getCustomerLevel());
        validateQuarantineStatType(baseCustomer.getQuarantineStatType());
        validateInvoiceType(baseCustomer.getInvoiceType());
        validateSwitchValue(baseCustomer.getCreditControl(), "信用控制");
        if (baseCustomerService.count(new QueryWrapper<BaseCustomer>()
                .ne("id", baseCustomer.getId())
                .eq("customer_num", baseCustomer.getCustomerNum())
                .eq("del_flag", "0")) > 0) {
            throw new Exception("该编号已存在");
        }
        baseCustomer.setUpdateBy(getUsername());
        return success(baseCustomerService.updateById(baseCustomer));
    }

    @ApiOperation("客户管理删除")
    @PreAuthorize("@ss.hasPermi('base:customer:remove')")
    @PostMapping("/delete")
    public AjaxResult delete(@ApiParam("删除参数: ids(逗号分隔)") @RequestBody Map<String, String> paramsMap) {
        String ids = paramsMap.get("ids");
        for (String id : ids.split(",")) {
            BaseCustomer customer = new BaseCustomer();
            customer.setId(Integer.valueOf(id));
            customer.setDelFlag("2");
            baseCustomerService.updateById(customer);
        }
        return success();
    }

    @ApiOperation("客户管理列表")
    @PreAuthorize("@ss.hasPermi('base:customer:list')")
    @PostMapping("/list")
    public AjaxResult listAll(HttpServletRequest request) {
        return success(baseCustomerService.list(new QueryWrapper<BaseCustomer>()
                .eq("org_id", tokenService.getLoginOrgId(request))
                .eq("del_flag", "0")));
    }

    @ApiOperation("客户管理分页")
    @PreAuthorize("@ss.hasPermi('base:customer:list')")
    @GetMapping("/page")
    public AjaxResult page(@ApiParam("页码") @RequestParam("pageNum") Integer pageNum,
                           @ApiParam("每页大小") @RequestParam("pageSize") Integer pageSize,
                           BaseCustomer query, HttpServletRequest request) {
        QueryWrapper<BaseCustomer> wrapper = buildWrapper(query, tokenService.getLoginOrgId(request));
        return success(baseCustomerService.page(new Page<BaseCustomer>(pageNum, pageSize), wrapper));
    }

    @ApiOperation("客户管理详情")
    @PreAuthorize("@ss.hasPermi('base:customer:query')")
    @PostMapping("/listById")
    public AjaxResult listById(@ApiParam("详情参数: id") @RequestBody Map<String, String> paramsMap) {
        String id = paramsMap.get("id");
        return success(baseCustomerService.getById(id));
    }

    /**
     * 按客户编号查询（销售订单等模块引用）。不校验 base:customer:*，避免无「客户管理」菜单权限的用户无法录单。
     */
    @ApiOperation("按客户编号查询客户")
    @PostMapping("/getByCustomerNum")
    public AjaxResult getByCustomerNum(@RequestBody Map<String, String> params, HttpServletRequest request) {
        String customerNum = params.get("customerNum");
        if (StringUtils.isBlank(customerNum)) {
            return success(null);
        }
        BaseCustomer c = baseCustomerService.getOne(new QueryWrapper<BaseCustomer>()
                .eq("org_id", tokenService.getLoginOrgId(request))
                .eq("customer_num", customerNum.trim())
                .eq("del_flag", "0")
                .last("limit 1"));
        return success(c);
    }

    @ApiOperation("客户管理导出")
    @PreAuthorize("@ss.hasPermi('base:customer:export')")
    @PostMapping("/export")
    public void export(HttpServletResponse response, BaseCustomer query, HttpServletRequest request) {
        QueryWrapper<BaseCustomer> wrapper = buildWrapper(query, tokenService.getLoginOrgId(request));
        List<BaseCustomer> list = baseCustomerService.list(wrapper);
        ExcelUtil<BaseCustomer> util = new ExcelUtil<BaseCustomer>(BaseCustomer.class);
        util.exportExcel(response, list, "客户数据");
    }

    private QueryWrapper<BaseCustomer> buildWrapper(BaseCustomer query, String orgId) {
        QueryWrapper<BaseCustomer> wrapper = new QueryWrapper<BaseCustomer>()
                .eq("org_id", orgId)
                .eq("del_flag", "0");
        if (query == null) {
            return wrapper;
        }
        if (StringUtils.isNotBlank(query.getCustomerNum())) {
            wrapper.like("customer_num", query.getCustomerNum());
        }
        if (StringUtils.isNotBlank(query.getCustomerName())) {
            wrapper.like("customer_name", query.getCustomerName());
        }
        if (StringUtils.isNotBlank(query.getCustomerAddress())) {
            wrapper.like("customer_address", query.getCustomerAddress());
        }
        if (query.getCustomerLevel() != null) {
            wrapper.eq("customer_level", query.getCustomerLevel());
        }
        if (StringUtils.isNotBlank(query.getContactPerson())) {
            wrapper.like("contact_person", query.getContactPerson());
        }
        if (StringUtils.isNotBlank(query.getContactPhone())) {
            wrapper.like("contact_phone", query.getContactPhone());
        }
        if (StringUtils.isNotBlank(query.getReceivableCustomer())) {
            wrapper.like("receivable_customer", query.getReceivableCustomer());
        }
        if (StringUtils.isNotBlank(query.getPayeeCustomer())) {
            wrapper.like("payee_customer", query.getPayeeCustomer());
        }
        if (StringUtils.isNotBlank(query.getDeliveryCustomer())) {
            wrapper.like("delivery_customer", query.getDeliveryCustomer());
        }
        if (query.getCreditControl() != null) {
            wrapper.eq("credit_control", query.getCreditControl());
        }
        return wrapper;
    }

    private void validateCustomerLevel(Integer customerLevel) throws Exception {
        if (customerLevel != null && (customerLevel < 1 || customerLevel > 5)) {
            throw new Exception("客户等级仅支持：1(1级)、2(2级)、3(3级)、4(4级)、5(5级)");
        }
    }

    private void validateSwitchValue(Integer value, String label) throws Exception {
        if (value != null && value != 0 && value != 1 && value != 2) {
            throw new Exception(label + "仅支持：0(' ')、1(启用)、2(不启用)");
        }
    }

    private void validateQuarantineStatType(Integer quarantineStatType) throws Exception {
        if (quarantineStatType != null && quarantineStatType != 0 && quarantineStatType != 1 && quarantineStatType != 2) {
            throw new Exception("检疫统计类型仅支持：0(无)、1(按客户)、2(按市场)");
        }
    }

    private void validateInvoiceType(Integer invoiceType) throws Exception {
        if (invoiceType != null && invoiceType != 0 && invoiceType != 1 && invoiceType != 2) {
            throw new Exception("开票类型仅支持：0(' ')、1(普票)、2(增票)");
        }
    }
}
