package com.ghy.web.controller.customer;

import com.ghy.common.adapay.model.AnalyseItemEnum;
import com.ghy.common.core.controller.BaseController;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.core.page.TableDataInfo;
import com.ghy.common.enums.FinancialDetailType;
import com.ghy.common.enums.PlaceStatus;
import com.ghy.common.enums.UserStatus;
import com.ghy.common.utils.ExceptionUtil;
import com.ghy.customer.domain.Customer;
import com.ghy.customer.service.CustomerService;
import com.ghy.goods.domain.InsuranceManager;
import com.ghy.order.domain.OrderMaster;
import com.ghy.order.service.OrderMasterService;
import com.ghy.payment.domain.FinancialDetail;
import com.ghy.payment.domain.FinancialMaster;
import com.ghy.payment.service.FinancialMasterService;
import com.ghy.web.pojo.vo.AnalyseItem;
import com.ghy.web.pojo.vo.CustomerPlaceMember;
import org.apache.commons.collections.CollectionUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author clunt
 * 消费者Controller
 */
@Controller
@RequestMapping("/customer")
public class CustomerController extends BaseController {

    private String prefix = "customer";

    @Autowired
    private CustomerService customerService;

    @Autowired
    private FinancialMasterService financialMasterService;

    @Autowired
    private OrderMasterService orderMasterService;

    @RequiresPermissions("customer:customer:view")
    @GetMapping()
    public String customer()
    {
        return prefix + "/customer";
    }

    @RequiresPermissions("customer:customer:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(Customer customer)
    {
        startPage();
        List<Customer> list = customerService.getCustomerList(customer);
        return getDataTable(list);
    }

    @PostMapping("/app/list")
    @ResponseBody
    public TableDataInfo appList(@RequestBody Customer customer)
    {
        List<CustomerPlaceMember> response = new ArrayList<CustomerPlaceMember>();
        startPage();
        List<Customer> list = customerService.getCustomerList(customer);
        for (Customer curCustomer: list) {
            Long teamNum = 0L;
            List<Long> customerIds = new ArrayList<Long>(){{
               add(curCustomer.getCustomerId());
            }};
            List<Long> nextLevelCustomerIds = new ArrayList<>();
            if (customer.getIsDistributor()) {
                // 分销商需要查询所有下一级分销用户作为统计条件
                Customer customerQry = new Customer();
                customerQry.setCustomerPlace(curCustomer.getCustomerId());
                customerQry.setStatus(Integer.valueOf(UserStatus.OK.getCode()));
                List<Customer> nextLevelCustomers = customerService.getCustomerList(customerQry);
                teamNum = teamNum + nextLevelCustomers.stream().filter(x->PlaceStatus.CAN_PLACE.getCode().equals(x.getPlaceStatus())).count();
                nextLevelCustomerIds = nextLevelCustomers.stream().map(Customer::getCustomerId).collect(Collectors.toList());
            }

            // 本月第一天
            LocalDate firstDayCurMonth = LocalDate.now().withDayOfMonth(1);
            // 今天
            LocalDate curDay = LocalDate.now();
            // 往前推第7天
            LocalDate firstDayCurWeek = LocalDate.now().minusDays(6);

            List<AnalyseItem> analyseItems = new ArrayList<AnalyseItem>();
            // 客户数
            Customer customerParams = new Customer();
            customerParams.setCustomerPlaces(customerIds);
            AnalyseItem aItem1 = new AnalyseItem()
                .setType(AnalyseItemEnum.CUSTOMER_NUM.getType())
                .setTitle(AnalyseItemEnum.CUSTOMER_NUM.getTitle())
                .setUnit(AnalyseItemEnum.CUSTOMER_NUM.getUnit())
                .setValue(customerService.countCustomer(customerParams));
            analyseItems.add(aItem1);
            // 本月绑定客户数
            customerParams.setPlaceStatus(null);
            customerParams.setUpdateTimeStart(firstDayCurMonth.atStartOfDay());
            AnalyseItem aItem2 = new AnalyseItem()
                    .setType(AnalyseItemEnum.CUSTOMER_NUM_ADDED_CUR_MONTH.getType())
                    .setTitle(AnalyseItemEnum.CUSTOMER_NUM_ADDED_CUR_MONTH.getTitle())
                    .setUnit(AnalyseItemEnum.CUSTOMER_NUM_ADDED_CUR_MONTH.getUnit())
                    .setValue(customerService.countCustomer(customerParams));
            analyseItems.add(aItem2);
            // 团队
            customerParams.setUpdateTimeStart(null);
            customerParams.setPlaceStatus(PlaceStatus.CAN_PLACE.getCode());
            AnalyseItem aItem11 = new AnalyseItem()
                    .setType(AnalyseItemEnum.TEAM_MEMBER_NUM.getType())
                    .setTitle(AnalyseItemEnum.TEAM_MEMBER_NUM.getTitle())
                    .setUnit(AnalyseItemEnum.TEAM_MEMBER_NUM.getUnit())
                    .setValue(customerService.countCustomer(customerParams));
            analyseItems.add(aItem11);
            // 本月绑定客户数
            customerParams.setUpdateTimeStart(firstDayCurMonth.atStartOfDay());
            customerParams.setPlaceStatus(PlaceStatus.CAN_PLACE.getCode());
            AnalyseItem aItem12 = new AnalyseItem()
                .setType(AnalyseItemEnum.TEAM_MEMBER_ADDED_CUR_MONTH.getType())
                .setTitle(AnalyseItemEnum.TEAM_MEMBER_ADDED_CUR_MONTH.getTitle())
                .setUnit(AnalyseItemEnum.TEAM_MEMBER_ADDED_CUR_MONTH.getUnit())
                .setValue(customerService.countCustomer(customerParams));
            analyseItems.add(aItem12);

            // 本月订单数及本月订单额
            OrderMaster orderParams1 = new OrderMaster();
            customerIds.addAll(nextLevelCustomerIds);
            orderParams1.setCustomerIds(customerIds);
            orderParams1.setCreateTimeStart(firstDayCurMonth.atStartOfDay());
            List<OrderMaster> ordersCurMonth1 = orderMasterService.selectOrderMasterList(orderParams1);
            List<Long> orderIdsCurMonth1 = ordersCurMonth1.stream().map(OrderMaster::getId).collect(Collectors.toList());
            BigDecimal totalMoneyCurMonth1 = new BigDecimal(0);
            if (CollectionUtils.isNotEmpty(orderIdsCurMonth1)) {
                FinancialMaster financialParams1 = new FinancialMaster();
                financialParams1.setOrderMasterIds(orderIdsCurMonth1);
                List<FinancialMaster> financialsCurMonth1 = financialMasterService.selectFinancialMasterList(financialParams1);
                totalMoneyCurMonth1 = financialsCurMonth1.stream().map(FinancialMaster::getTotalMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
            }
            AnalyseItem aItem3 = new AnalyseItem()
                .setType(AnalyseItemEnum.ORDER_NUM_CUR_MONTH.getType())
                .setTitle(AnalyseItemEnum.ORDER_NUM_CUR_MONTH.getTitle())
                .setUnit(AnalyseItemEnum.ORDER_NUM_CUR_MONTH.getUnit())
                .setValue(ordersCurMonth1 != null ? ordersCurMonth1.size() : 0);
            AnalyseItem aItem4 = new AnalyseItem()
                .setType(AnalyseItemEnum.ORDER_TRADE_VOLUME_CUR_MONTH.getType())
                .setTitle(AnalyseItemEnum.ORDER_TRADE_VOLUME_CUR_MONTH.getTitle())
                .setUnit(AnalyseItemEnum.ORDER_TRADE_VOLUME_CUR_MONTH.getUnit())
                .setValue(totalMoneyCurMonth1);
            analyseItems.add(aItem3);
            analyseItems.add(aItem4);

            // 上月订单数及上月订单额
            OrderMaster orderParams2 = new OrderMaster();
            orderParams2.setCustomerIds(customerIds);
            orderParams2.setCreateTimeStart(firstDayCurMonth.atStartOfDay().minusMonths(1));
            orderParams2.setCreateTimeEnd(firstDayCurMonth.atStartOfDay());
            List<OrderMaster> ordersCurMonth2 = orderMasterService.selectOrderMasterList(orderParams2);
            List<Long> orderIdsCurMonth2 = ordersCurMonth2.stream().map(OrderMaster::getId).collect(Collectors.toList());
            BigDecimal totalMoneyCurMonth2 = new BigDecimal(0);
            if (CollectionUtils.isNotEmpty(orderIdsCurMonth2)) {
                FinancialMaster financialParams2 = new FinancialMaster();
                financialParams2.setOrderMasterIds(orderIdsCurMonth2);
                List<FinancialMaster> financialsCurMonth2 = financialMasterService.selectFinancialMasterList(financialParams2);
                totalMoneyCurMonth2 = financialsCurMonth2.stream().map(FinancialMaster::getTotalMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
            }
            AnalyseItem aItem5 = new AnalyseItem()
                .setType(AnalyseItemEnum.ORDER_NUM_LAST_MONTH.getType())
                .setTitle(AnalyseItemEnum.ORDER_NUM_LAST_MONTH.getTitle())
                .setUnit(AnalyseItemEnum.ORDER_NUM_LAST_MONTH.getUnit())
                .setValue(ordersCurMonth2 != null ? ordersCurMonth2.size() : 0);
            AnalyseItem aItem6 = new AnalyseItem()
                .setType(AnalyseItemEnum.ORDER_TRADE_VOLUME_LAST_MONTH.getType())
                .setTitle(AnalyseItemEnum.ORDER_TRADE_VOLUME_LAST_MONTH.getTitle())
                .setUnit(AnalyseItemEnum.ORDER_TRADE_VOLUME_LAST_MONTH.getUnit())
                .setValue(totalMoneyCurMonth2);
            analyseItems.add(aItem5);
            analyseItems.add(aItem6);

            // 当天订单数及当天订单额
            OrderMaster orderParams3 = new OrderMaster();
            orderParams3.setCustomerIds(customerIds);
            orderParams3.setCreateTimeStart(curDay.atStartOfDay());
            List<OrderMaster> ordersCurDay = orderMasterService.selectOrderMasterList(orderParams3);
            List<Long> orderIdsCurDay = ordersCurDay.stream().map(OrderMaster::getId).collect(Collectors.toList());
            BigDecimal totalMoneyCurDay = new BigDecimal(0);
            if (CollectionUtils.isNotEmpty(orderIdsCurDay)) {
                FinancialMaster financialParams3 = new FinancialMaster();
                financialParams3.setOrderMasterIds(orderIdsCurDay);
                List<FinancialMaster> financialsCurDay = financialMasterService.selectFinancialMasterList(financialParams3);
                totalMoneyCurDay = financialsCurDay.stream().map(FinancialMaster::getTotalMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
            }
            AnalyseItem aItem7 = new AnalyseItem()
                .setType(AnalyseItemEnum.ORDER_NUM_CUR_DAY.getType())
                .setTitle(AnalyseItemEnum.ORDER_NUM_CUR_DAY.getTitle())
                .setUnit(AnalyseItemEnum.ORDER_NUM_CUR_DAY.getUnit())
                .setValue(ordersCurDay != null ? ordersCurDay.size() : 0);
            AnalyseItem aItem8 = new AnalyseItem()
                .setType(AnalyseItemEnum.ORDER_TRADE_VOLUME_CUR_DAY.getType())
                .setTitle(AnalyseItemEnum.ORDER_TRADE_VOLUME_CUR_DAY.getTitle())
                .setUnit(AnalyseItemEnum.ORDER_TRADE_VOLUME_CUR_DAY.getUnit())
                .setValue(totalMoneyCurDay);
            analyseItems.add(aItem7);
            analyseItems.add(aItem8);

            // 7天订单数及7天订单额
            OrderMaster orderParams4 = new OrderMaster();
            orderParams4.setCustomerIds(customerIds);
            orderParams4.setCreateTimeStart(firstDayCurWeek.atStartOfDay());
            List<OrderMaster> ordersCurWeek = orderMasterService.selectOrderMasterList(orderParams4);
            List<Long> orderIdsCurWeek = ordersCurWeek.stream().map(OrderMaster::getId).collect(Collectors.toList());
            BigDecimal totalMoneyCurWeek = new BigDecimal(0);
            if (CollectionUtils.isNotEmpty(orderIdsCurWeek)) {
                FinancialMaster financialParams4 = new FinancialMaster();
                financialParams4.setOrderMasterIds(orderIdsCurWeek);
                List<FinancialMaster> financialsCurWeek = financialMasterService.selectFinancialMasterList(financialParams4);
                totalMoneyCurWeek = financialsCurWeek.stream().map(FinancialMaster::getTotalMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
            }
            AnalyseItem aItem9 = new AnalyseItem()
                .setType(AnalyseItemEnum.ORDER_NUM_LAST_7_DAYS.getType())
                .setTitle(AnalyseItemEnum.ORDER_NUM_LAST_7_DAYS.getTitle())
                .setUnit(AnalyseItemEnum.ORDER_NUM_LAST_7_DAYS.getUnit())
                .setValue(ordersCurWeek != null ? ordersCurWeek.size() : 0);
            AnalyseItem aItem10 = new AnalyseItem()
                .setType(AnalyseItemEnum.ORDER_TRADE_VOLUME_LAST_7_DAYS.getType())
                .setTitle(AnalyseItemEnum.ORDER_TRADE_VOLUME_LAST_7_DAYS.getTitle())
                .setUnit(AnalyseItemEnum.ORDER_TRADE_VOLUME_LAST_7_DAYS.getUnit())
                .setValue(totalMoneyCurWeek);
            analyseItems.add(aItem9);
            analyseItems.add(aItem10);

            CustomerPlaceMember customerPlaceMember = new CustomerPlaceMember();
            customerPlaceMember.setAnalyseItems(analyseItems);
            customerPlaceMember.setCustomerId(curCustomer.getCustomerId());
            customerPlaceMember.setName(curCustomer.getName());
            customerPlaceMember.setPhone(curCustomer.getPhone());
            customerPlaceMember.setCustomerLogoUrl(curCustomer.getCustomerLogoUrl());
            response.add(customerPlaceMember);
        }

        return getDataTable(response);
    }

    @GetMapping("/changePlace/{customerId}")
    public String changePlace(@PathVariable("customerId") Long customerId, ModelMap mmap)
    {

        mmap.put("customerId", customerId);
        mmap.put("customerPlaces", customerService.getPlaceCustomerList());
        return prefix + "/changePlace";
    }

    @PostMapping("/changePlace")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult changePlace(Customer customer) {
        Customer place = customerService.selectByCustomerId(customer.getCustomerPlace());
        customer.setParentCustomerPlace(place.getCustomerPlace());
        customerService.updateCustomer(customer);
        return AjaxResult.success();
    }

    @RequiresPermissions("customer:customer:resetPwd")
    @GetMapping("/resetPwd/{customerId}")
    public String resetPwd(@PathVariable("customerId") Long customerId, ModelMap mmap)
    {
        mmap.put("customer", customerService.selectByCustomerId(customerId));
        return prefix + "/resetPwd";
    }

    @PostMapping("/update")
    @ResponseBody
    public AjaxResult updateCustomer(@RequestBody Customer customer){
        try {
            if (customer.getCustomerPlace() != null) {
                Customer curCustomer = customerService.selectByCustomerId(customer.getCustomerId());
                Customer placeCustomer = customerService.selectByCustomerId(customer.getCustomerPlace());
                if (curCustomer.getCustomerPlace() != null) {
                    logger.info("消费者已存在分销人信息，customerId=" + curCustomer.getCustomerId());
                    return AjaxResult.success("消费者已存在分销信息");
                }
                if (customer.getCustomerPlace() == customer.getCustomerId()) {
                    logger.info("消费者id与父级分销人id相同，无效分销信息，customerId=" + curCustomer.getCustomerId());
                    return AjaxResult.success("无效分销信息");
                }
                logger.info("开始查找有效分销者");
                if (!PlaceStatus.CAN_PLACE.getCode().equals(placeCustomer.getPlaceStatus())) {
                    // 当前placeCustomer未通过分销资格审核，查找再上一级分销者
                    if (placeCustomer.getCustomerPlace() == null) {
                        logger.info("无有效上级分销者");
                        return AjaxResult.success();
                    } else {
                        placeCustomer = customerService.selectByCustomerId(placeCustomer.getCustomerPlace());
                        logger.info("存在有效上级分销者：" + placeCustomer.getCustomerId());
                    }
                }
                // 更新父级分销人时需要查询是否有祖父分销人，并进行同步更新
                customer.setCustomerPlace(placeCustomer.getCustomerId());
                customer.setParentCustomerPlace(placeCustomer.getCustomerPlace());
            }
            customerService.updateCustomer(customer);
            return AjaxResult.success("更新消费者信息成功");
        } catch (Exception e){
            ExceptionUtil.getExceptionMessage(e);
            return AjaxResult.error(e.getMessage());
        }
    }

}
