package com.boco.nbd.wios.manage.controller;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.boco.nbd.wios.manage.client.DepponClient;
import com.boco.nbd.wios.manage.convert.WallboxApplyConvert;
import com.boco.nbd.wios.manage.entity.bo.Order;
import com.boco.nbd.wios.manage.entity.bo.Supplier;
import com.boco.nbd.wios.manage.entity.bo.SupplierStaff;
import com.boco.nbd.wios.manage.entity.bo.WallboxApply;
import com.boco.nbd.wios.manage.entity.cams.enums.OrderStatus;
import com.boco.nbd.wios.manage.entity.dto.WallboxApplyBatchCheckDTO;
import com.boco.nbd.wios.manage.entity.vo.*;
import com.boco.nbd.wios.manage.service.impl.*;
import com.boco.nbd.wios.utils.ExcelUtils;
import com.ihidea.component.api.v2.BaseResponse;
import com.ihidea.core.support.exception.ServiceException;
import com.ihidea.core.support.session.SessionInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 * <p>
 * 墙盒申请Controller
 * <p>
 *
 * @author <a href="mail to: ning.chai@foxmail.com" rel="nofollow">chaining</a>
 */
@RestController
@Api(tags = "墙盒申请接口")
@RequestMapping("api/wallbox/apply")
public class WallboxApplyController {
    @Autowired
    private WallboxApplyService wallboxApplyService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private SupplierStaffService supplierStaffService;
    @Autowired
    private SupplierService supplierService;
    @Resource
    private DepponClient depponClient;

    @ApiOperation(value = "墙盒申请")
    @PostMapping("/add")
    @ApiImplicitParams({@ApiImplicitParam(name = "orderId", value = "订单id", dataType = "string", paramType = "query",
            required = true), @ApiImplicitParam(name = "ifEmergency", value = "是否紧急0否,1是", dataType = "int",
            paramType = "query", required = true),})
    public BaseResponse<Object> applyInstallation(String orderId, Integer ifEmergency) {
        Assert.notNull(orderId, "订单id不能为空");
        Order order = orderService.get(orderId);
        if (ObjectUtil.isNull(order)) {
            throw new ServiceException("订单不存在");
        }
        Integer status = order.getStatus();
        // 检查订单状态是否在0-43之间
        boolean allowed = status >= OrderStatus.DISPATCHING.getType() && status <= OrderStatus.INSTALLING.getType();
        if (!allowed) {
            throw new ServiceException("订单已在安装中,无法申请");
        }

        SessionInfo loginUser = tokenService.getUser();
        String userId = loginUser.getUserId();
        SupplierStaff infoByAccount = supplierStaffService.getByAccountId(Integer.valueOf(userId));
        Supplier supplier = supplierService.getById(infoByAccount.getSupplierId());
        if (supplier == null) {
            throw new ServiceException("供应商不存在");
        }
        WallboxApply wa = new WallboxApply();
        wa.setSupplierId(Long.valueOf(supplier.getId()));
        wa.setSupplierTeam(supplier.getName());
        wa.setOrderId(orderId);
        wa.setIfEmergency(ifEmergency);
        wa.setCreateAccount(tokenService.getUser().getUserId());
        wallboxApplyService.insertWallboxApply(wa);
        return new BaseResponse<>(true);

    }

    /**
     * 查询墙盒申请列表
     */
    @GetMapping("/list")
    @ApiOperation(value = "分页查询墙盒申请列表-总仓")
    @ApiImplicitParams({@ApiImplicitParam(name = "page", value = "一页显示数量", dataType = "int", paramType = "query",
            required = true), @ApiImplicitParam(name = "pagecount", value = "页码", dataType = "int", paramType =
            "query", required = true)})
    public BaseResponse<List<WallboxApplyInstallListVO>> list(WallboxApplyReqVO req) {
        List<WallboxApplyInstallListVO> list =
                wallboxApplyService.selectWallboxApplyListFromOrder(WallboxApplyConvert.INSTANCE.convert(req));
        LocalDateTime currentTime = LocalDateTime.now();
        for (WallboxApplyInstallListVO apply : list) {
            Date createdDate = apply.getCreatedTime();
            LocalDateTime createdTime = LocalDateTime.ofInstant(createdDate.toInstant(), ZoneId.systemDefault());
            LocalDateTime endTime = createdTime.plusHours(24);

            long remainingHours = currentTime.until(endTime, ChronoUnit.HOURS);
            remainingHours = Math.max(remainingHours, 0);  // 将剩余小时数限制在0-24之间
            if (remainingHours == 0) {
                apply.setIfTimeout(1L);
            } else {
                apply.setIfTimeout(0L);
            }
            apply.setTimeRemaining(Long.toString(remainingHours));
        }
        return new BaseResponse<>(list);
    }

    /**
     * 墙盒申请安装团队分页查询
     */
    @GetMapping("/supplierList")
    @ApiOperation(value = "分页查询墙盒申请列表-安装团队")
    @ApiImplicitParams({@ApiImplicitParam(name = "page", value = "一页显示数量", dataType = "int", paramType = "query",
            required = true), @ApiImplicitParam(name = "pagecount", value = "页码", dataType = "int", paramType =
            "query", required = true)})
    public BaseResponse<List<WallboxApplyInstallListVO>> supplierList(WallboxApplyReqVO req) {
        SessionInfo loginUser = tokenService.getUser();
        String userId = loginUser.getUserId();

        SupplierStaff infoByAccount = supplierStaffService.getByAccountId(Integer.valueOf(userId));
        Supplier supplier = supplierService.getById(infoByAccount.getSupplierId());
        if (supplier == null) {
            throw new ServiceException("供应商不存在");
        }
        req.setSupplierId(supplier.getId());
        List<WallboxApplyInstallListVO> list =
                wallboxApplyService.selectWallboxApplyListFromOrder(WallboxApplyConvert.INSTANCE.convert(req));
        LocalDateTime currentTime = LocalDateTime.now();
        for (WallboxApplyInstallListVO apply : list) {
            Date createdDate = apply.getCreatedTime();
            LocalDateTime createdTime = LocalDateTime.ofInstant(createdDate.toInstant(), ZoneId.systemDefault());
            LocalDateTime endTime = createdTime.plusHours(24);

            long remainingHours = currentTime.until(endTime, ChronoUnit.HOURS);
            remainingHours = Math.max(remainingHours, 0);  // 将剩余小时数限制在0-24之间
            if (remainingHours == 0) {
                apply.setIfTimeout(1L);
            } else {
                apply.setIfTimeout(0L);
            }
            apply.setTimeRemaining(Long.toString(remainingHours));
        }
        return new BaseResponse<>(list);
    }


    @GetMapping("/get-import-template")
    @ApiOperation("获得导入模板")
    public void importTemplate(HttpServletResponse response) throws IOException {
        // 手动创建导出 demo
        WallboxApplyExcelVO excelDemo = new WallboxApplyExcelVO();
        excelDemo.setIfEmergency(0);
        excelDemo.setOrderId("CA20201204044558");
        List<WallboxApplyExcelVO> list = Arrays.asList(
                excelDemo
        );
        // 输出
        ExcelUtils.write(response, "墙盒申请导入模板.xls", "墙盒申请", WallboxApplyExcelVO.class, list);
    }

    @PostMapping("/import")
    @ApiOperation("导入墙盒申请")
    public BaseResponse<WallboxApplyExcelVO> importExcel(@RequestParam(value = "file") MultipartFile file
    ) throws Exception {
        List<WallboxApplyExcelVO> list = ExcelUtils.read(file, WallboxApplyExcelVO.class);
        return new BaseResponse<>();
    }

    /**
     * 导出墙盒申请模板
     */
    @PostMapping("/export")
    @ApiOperation("导出墙盒申请")
    @ApiImplicitParams({@ApiImplicitParam(name = "page", value = "一页显示数量", dataType = "int", paramType = "query",
            required = true), @ApiImplicitParam(name = "pagecount", value = "页码", dataType = "int", paramType =
            "query", required = true)})
    public void export(HttpServletResponse response, WallboxApplyReqVO req) throws IOException {
        List<WallboxApplyInstallListVO> list =
                wallboxApplyService.selectWallboxApplyListFromOrder(WallboxApplyConvert.INSTANCE.convert(req));
        ExcelUtils.write(response, "墙盒申请数据导出.xls", "墙盒申请数据", WallboxApplyInstallListVO.class, list);
    }


    /**
     * 获取墙盒申请详细信息
     */
    @ApiOperation(value = "获取墙盒详细信息")
    @GetMapping(value = "/{id}")
    public BaseResponse<Object> getInfo(@PathVariable("id") Long id) {
        return new BaseResponse<>(wallboxApplyService.selectWallboxApplyById(id));
    }

    /**
     * 获取墙盒详细信息
     */
    @ApiOperation(value = "墙盒状态")
    @PostMapping(value = "/status")
    public BaseResponse<Object> wallboxStatus(@RequestParam("orderId") String orderId) {
        WallboxApplyDetailVO rest = wallboxApplyService.selectWallboxDetail(orderId);
        return new BaseResponse<>(rest);
    }

    @ApiOperation(value = "获取物流信息")
    @GetMapping(value = "/trace/{id}")
    public BaseResponse<Object> getTrace(@PathVariable("id") String id) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("mailNo", id);
        return new BaseResponse<>(JSON.parseObject(depponClient.newTraceQuery(paramMap)));
    }

    /**
     * 新增墙盒申请
     */
    @ApiOperation(value = "批量新增")
    @PostMapping
    public BaseResponse<Object> add(@RequestBody List<WallboxApply> tWallboxApply) {
        tWallboxApply.forEach(t -> {
            wallboxApplyService.insertWallboxApply(t);
        });
        return new BaseResponse<>();
    }

    @ApiOperation(value = "查询当前账号所属团队")
    @GetMapping("/get-team")
    public BaseResponse<Object> getTeamInfo() {
        SessionInfo loginUser = tokenService.getUser();
        String userId = loginUser.getUserId();

        SupplierStaff infoByAccount = supplierStaffService.getByAccountId(Integer.valueOf(userId));
        Supplier supplier = supplierService.getById(infoByAccount.getSupplierId());
        if (supplier == null) {
            throw new ServiceException("供应商不存在");
        }
        return new BaseResponse<>(supplier);
    }

    @ApiOperation(value = "查询当前账号所属团队")
    @GetMapping("/getTeamOrder")
     public BaseResponse<Object> getTeamOrder(){
        SessionInfo loginUser = tokenService.getUser();
        String userId = loginUser.getUserId();

        SupplierStaff infoByAccount = supplierStaffService.getByAccountId(Integer.valueOf(userId));
        Supplier supplier = supplierService.getById(infoByAccount.getSupplierId());
        return new BaseResponse<>();
    }

    /**
     * 修改墙盒申请
     */
    @PutMapping
    @ApiOperation(value = "修改")
    public BaseResponse<Object> edit(@RequestBody WallboxApply tWallboxApply) {
        return new BaseResponse<>(wallboxApplyService.updateWallboxApply(tWallboxApply));
    }


    @ApiOperation(value = "申请审核")
    @PostMapping("/check")
    public BaseResponse<Object> check(@RequestBody @Validated WallboxApplyCheckVO req) {
        wallboxApplyService.checkWallboxApply(req);
        return new BaseResponse<>();
    }

    @ApiOperation(value = "同订单多申请情况")
    @PostMapping("/unapproved")
    public BaseResponse<Object> hasUnapprovedOrders(@RequestBody @Validated WallboxApplyCheckVO req) {
        WallboxApply cond = new WallboxApply();
        cond.setOrderId(req.getOrderId());
        long count =
                wallboxApplyService.selectWallboxApplyList(cond).stream().filter(l -> l.getCheckStatus() == 1).count();
        if (count > 0) {
            throw new ServiceException("该安装订单号存在多个申请");
        }
        return new BaseResponse<>();
    }

    @ApiOperation(value = "批量申请审核")
    @PostMapping("/check-batch")
    public BaseResponse<Object> checkBatch(@RequestBody WallboxApplyBatchCheckDTO req) {
        return new BaseResponse<>(wallboxApplyService.checkBatch(req));
    }

    @ApiOperation(value = "墙盒申请状态统计")
    @PostMapping("/count")
    public BaseResponse<Object> count() {
        //查询当前团队的已审批、未审批、已发货、未发货数据
        String currentLogin = tokenService.getUser().getUserId();
        WallboxApply cond = new WallboxApply();
        cond.setCreateAccount(currentLogin);
        List<WallboxApply> list = wallboxApplyService.selectWallboxApplyList(cond);
        // 使用 Lambda 表达式统计每种情况的数据数量
        long unapprovedCount = list.stream()
                .filter(apply -> apply.getCheckStatus() == 1)
                .count();

        LocalDateTime currentDateTime = LocalDateTime.now();
        long timeoutCount = list.stream()
                .filter(apply -> apply.getCheckStatus() == 1 && Duration.between(LocalDateTimeUtil.of(apply.getCreatedTime()),
                        currentDateTime).toHours() > 24)
                .count();

        long awaitingDeliveryCount = list.stream()
                .filter(apply -> "0".equals(apply.getTrackingStatus()))
                .count();

        long deliveredCount = list.stream()
                .filter(apply -> "1".equals(apply.getTrackingStatus()))
                .count();

        Map<String, Object> rest = new HashMap<>();
        rest.put("unapprovedCount", unapprovedCount);
        rest.put("timeoutCount", timeoutCount);
        rest.put("awaitingDeliveryCount", awaitingDeliveryCount);
        rest.put("deliveredCount", deliveredCount);
        return new BaseResponse<>(rest);

    }
}