package com.cxyxiaomo.epp.shop.controller;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.cxyxiaomo.epp.PageTable.enums.AddType;
import com.cxyxiaomo.epp.PageTable.enums.EditType;
import com.cxyxiaomo.epp.PageTable.enums.FieldType;
import com.cxyxiaomo.epp.PageTable.enums.SearchType;
import com.cxyxiaomo.epp.PageTable.query.PageQuery;
import com.cxyxiaomo.epp.PageTable.utils.FieldBuilder;
import com.cxyxiaomo.epp.PageTable.utils.FieldMapperBuilder;
import com.cxyxiaomo.epp.PageTable.utils.FieldRuleBuilder;
import com.cxyxiaomo.epp.PageTable.utils.FieldRuleListBuilder;
import com.cxyxiaomo.epp.common.enums.OrderStatus;
import com.cxyxiaomo.epp.common.pojo.Order;
import com.cxyxiaomo.epp.common.pojo.OrderDetail;
import com.cxyxiaomo.epp.common.query.OrderQuery;
import com.cxyxiaomo.epp.common.response.Res;
import com.cxyxiaomo.epp.common.vo.GoodVO;
import com.cxyxiaomo.epp.common.vo.OrderDetailVO;
import com.cxyxiaomo.epp.common.vo.OrderVO;
import com.cxyxiaomo.epp.shop.service.GoodService;
import com.cxyxiaomo.epp.shop.service.OrderService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/shop/order")
public class OrderController {

    @Resource
    OrderService orderService;

    @Resource
    GoodService goodService;

    /**
     * 小程序端创建订单
     *
     * @param params userId    下单用户
     * @param params orderList 下单商品 [ { goodId, count }, ... ]
     * @return
     */
    @PostMapping("/miniprogram/createOrder")
    @ResponseBody
    public Res createOrder(@RequestBody JSONObject params) {
        Integer userId = params.getInteger("userId");
        JSONArray orderList = params.getJSONArray("orderList");
        if (userId == null || orderList == null) {
            return Res.error("参数错误");
        }

        LinkedList<OrderDetail> orderDetailList = new LinkedList<>();
        for (Object o : orderList) {
            if (o == null || o instanceof JSONObject) {
                return Res.error("参数错误");
            }
            JSONObject order = new JSONObject((Map) o);
            Long goodId = order.getLong("goodId");
            Integer count = order.getInteger("count");
            if (goodId == null || goodId < 1 || count == null || count < 1) {
                return Res.error("参数错误");
            }
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setGoodId(goodId);
            orderDetail.setGoodCount(count);
            orderDetailList.add(orderDetail);
        }

        if (orderDetailList.size() == 0) {
            return Res.error("订单中不包含商品，不能创建空订单");
        }

        try {
            long orderId = orderService.createOrder(userId, orderDetailList);
            return Res.success(String.valueOf(orderId)); // 转为 String 避免前端丢失精度
        } catch (Exception e) {
            String message = e.getMessage();
            if (message.contains("Exception")) {
                // 内部异常不打印出去
                return Res.error("创建订单失败，请重试");
            } else {
                return Res.error(message);
            }
        }
    }

    /**
     * 获取指定订单的详情
     *
     * @param orderId
     * @return
     */
    @GetMapping("/miniprogram/orderDetail")
    @ResponseBody
    public Res orderDetail(@RequestParam Long orderId) {
        if (orderId == null) {
            return Res.error("订单不存在");
        }

        try {
            Order order = orderService.getOrderById(orderId);
            if (order == null) {
                return Res.error("订单不存在");
            }
            List<OrderDetailVO> orderDetailVOList = orderService.getOrderDetailById(orderId);

            List<Long> goodIdList = orderDetailVOList.stream().map(orderDetailVO -> {
                String goodId = orderDetailVO.getGoodId();
                return Long.parseLong(goodId);
            }).collect(Collectors.toList());

            List<GoodVO> goodVOList = goodService.listByIds(goodIdList);
            HashMap<String, Object> resultMap = new HashMap<>();
            resultMap.put("order", OrderVO.convertFrom(order));
            resultMap.put("orderItem", orderDetailVOList);
            resultMap.put("goods", goodVOList);
            return Res.success(resultMap);
        } catch (Exception e) {
            String message = e.getMessage();
            if (message.contains("Exception")) {
                // 内部异常不打印出去
                return Res.error("查询订单失败，请重试");
            } else {
                return Res.error(message);
            }
        }
    }

    /**
     * 获取用户的订单列表
     *
     * @param userId
     * @return
     */
    @GetMapping("/miniprogram/listUserOrder")
    @ResponseBody
    public Res listUserOrder(@RequestParam Integer userId,
                             @RequestParam(value = "filter", required = false) String orderStatusFilter) {
        if (userId == null) {
            return Res.error("参数错误");
        }
        List<Order> orders = orderService.listUserOrder(userId, orderStatusFilter);
        List<OrderVO> orderVOS = OrderVO.convertFrom(orders);

        HashMap<String, Object> map = new HashMap<>();


        JSONObject filter = new JSONObject();
        Arrays.stream(OrderStatus.values())
                .forEach(orderStatus -> filter.put(orderStatus.getValue(), orderStatus.toString()));
        // List<String> filter = Arrays.stream(OrderStatus.values())
        //         .map(OrderStatus::toString).collect(Collectors.toList());

        map.put("filter", filter);
        map.put("orders", orderVOS);
        return Res.success(map);
    }

    @PostMapping("/miniprogram/payOrder")
    @ResponseBody
    public Res payOrder(@RequestBody JSONObject params) {
        Long orderId = params.getLong("orderId");
        if (orderId == null) {
            return Res.error("参数错误");
        }

        // 查询订单详情
        Order order = orderService.getOrderById(orderId);
        if (order == null) {
            return Res.error("订单不存在");
        }

        //判断是否可以支付
        OrderStatus orderStatus = OrderStatus.get(order.getOrderStatus());
        switch (orderStatus) {
            case PENDING:
                // 可以支付
                break;
            case PROCESSING:
                return Res.error("订单已支付，无需重复支付");
            case CANCELLED:
                return Res.error("订单已取消，无法支付");
            default:
                return Res.error("当前订单状态无法支付");
        }

        // 更新支付信息
        Boolean success = orderService.updateOrderStatus(orderId, OrderStatus.PROCESSING);

        return Res.success(success ? "支付成功" : "支付失败");
    }

    /**
     * 用户取消订单
     *
     * @param params
     * @return
     */
    @PostMapping("/miniprogram/cancelOrder")
    @ResponseBody
    public Res cancelOrder(@RequestBody JSONObject params) {
        Long orderId = params.getLong("orderId");
        if (orderId == null) {
            return Res.error("参数错误");
        }

        // 查询订单详情
        Order order = orderService.getOrderById(orderId);
        if (order == null) {
            return Res.error("订单不存在");
        }

        //判断是否可以取消
        OrderStatus orderStatus = OrderStatus.get(order.getOrderStatus());
        switch (orderStatus) {
            case PENDING:
                // 可以取消
                break;
            case PROCESSING:
                // 可以取消
                // return Res.error("订单已支付，不可取消");
                break;
            case SHIPPED:
                return Res.error("订单已发货，不可取消");
            case DELIVERED:
                return Res.error("订单已送达，不可取消");
            case CANCELLED:
                return Res.error("订单已取消");
            default:
                return Res.error("当前订单状态无法取消");
        }

        // 更新支付信息
        Boolean success = orderService.updateOrderStatus(orderId, OrderStatus.CANCELLED);

        return Res.success(success ? "取消成功" : "取消失败");
    }

    /**
     * 订单发货
     *
     * @param orderId
     * @param expressId
     * @param comment
     * @return
     */
    @PostMapping("/manage/deliverOrder")
    @ResponseBody
    public Res deliverOrder(Long orderId, String expressId, String comment) {
        if (orderId == null || expressId == null || comment == null) {
            return Res.error("参数错误");
        }

        if (expressId.equals("") && comment.equals("")) {
            return Res.error("运单号 和 发货备注 不可同时为空");
        }

        // 查询订单详情
        Order order = orderService.getOrderById(orderId);
        if (order == null) {
            return Res.error("订单不存在");
        }

        //判断是否可以发货
        OrderStatus orderStatus = OrderStatus.get(order.getOrderStatus());
        switch (orderStatus) {
            case PENDING:
                return Res.error("订单尚未支付，不可发货");
            case PROCESSING: // 订单未发货
                // 更新订单发货信息
                orderService.updateOrderShipInfo(orderId, expressId, comment);
                // 更新支付信息
                orderService.updateOrderStatus(orderId, OrderStatus.SHIPPED);
                return Res.success("发货成功");
            case SHIPPED: // 订单已发货，修改发货信息
                // 更新订单发货信息
                orderService.updateOrderShipInfo(orderId, expressId, comment);
                return Res.success("发货信息修改成功");
            case DELIVERED:
                return Res.error("订单已完成，无法再次发货");
            case CANCELLED:
                return Res.error("订单已取消，不可发货");
            default:
                return Res.error("当前订单状态不可发货");
        }
    }

    /**
     * 管理员取消订单
     *
     * @param orderId
     * @return
     */
    @PostMapping("/manage/cancelOrder")
    @ResponseBody
    public Res cancelOrderByManager(Long orderId) {
        if (orderId == null) {
            return Res.error("参数错误");
        }

        // 查询订单详情
        Order order = orderService.getOrderById(orderId);
        if (order == null) {
            return Res.error("订单不存在");
        }

        //判断是否可以取消
        OrderStatus orderStatus = OrderStatus.get(order.getOrderStatus());
        switch (orderStatus) {
            case PENDING:
                // 更新订单发货信息
                orderService.updateOrderShipInfo(orderId, "", "管理员取消了您的订单，如有疑问请联系管理员");
                // 更新支付信息
                orderService.updateOrderStatus(orderId, OrderStatus.CANCELLED);
                return Res.success("操作成功");
            case PROCESSING:
                // 更新订单发货信息
                orderService.updateOrderShipInfo(orderId, "", "管理员取消了您的订单，费用已退回至您的帐户，如有疑问请联系管理员");
                // 更新支付信息
                orderService.updateOrderStatus(orderId, OrderStatus.CANCELLED);
                return Res.success("操作成功");
            case SHIPPED:
                return Res.error("订单已发货，不可取消");
            case DELIVERED:
                return Res.error("订单已送达，不可取消");
            case CANCELLED:
                return Res.error("订单已取消");
            default:
                return Res.error("当前订单状态无法取消");
        }
    }

    /**
     * 订单确认收货
     *
     * @param params
     * @return
     */
    @PostMapping("/miniprogram/confirmOrder")
    @ResponseBody
    public Res confirmOrder(@RequestBody JSONObject params) {
        Long orderId = params.getLong("orderId");
        if (orderId == null) {
            return Res.error("参数错误");
        }

        // 查询订单详情
        Order order = orderService.getOrderById(orderId);
        if (order == null) {
            return Res.error("订单不存在");
        }

        //判断是否可以取消
        OrderStatus orderStatus = OrderStatus.get(order.getOrderStatus());
        switch (orderStatus) {
            case PENDING:
                return Res.error("订单尚未支付，不可确认收货");
            case PROCESSING:
                return Res.error("订单尚未发货，不可确认收货");
            case SHIPPED:
                // 可以确认收货
                break;
            case DELIVERED:
                return Res.error("您已确认收货，无需再次确认");
            case CANCELLED:
                return Res.error("订单已取消，不可确认收货");
            default:
                return Res.error("当前订单状态无法确认收货");
        }

        // 更新支付信息
        Boolean success = orderService.updateOrderStatus(orderId, OrderStatus.DELIVERED);

        return Res.success(success ? "确认收货成功" : "确认收货失败");
    }


    /**
     * 获取订单列表
     *
     * @return
     */
    @GetMapping("/manage/getOrderList")
    @ResponseBody
    public Res getOrderList(PageQuery pageQuery, OrderQuery orderQuery) {
        // 查询分页数据
        PageHelper.startPage(pageQuery.getPageIndex(), pageQuery.getPageSize());
        List<Order> orderList = orderService.getOrderList(orderQuery);
        PageInfo<Order> orderPageInfo = new PageInfo<>(orderList);
        List<Order> list = orderPageInfo.getList();
        List<OrderVO> voList = OrderVO.convertFrom(list);

        // id列 字段名（区分大小写；以VO中的变量名为准）
        // 新增、修改弹窗时，使用该列作为主键列进行操作
        String idFieldName = "id";

        // 当前管理页面
        String pageName = "订单管理";

        // 指定前端表格显示列
        JSONArray columns = FieldBuilder.create()
                .add("userId", "userId", "用户ID", "",
                        FieldType.TEXT, SearchType.INPUT, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        null, null, null, null
                )
                .add("orderStatusCode", "orderStatusName", "订单状态", true,
                        FieldType.TEXT, SearchType.SELECT, AddType.CAN_NOT_ADD, EditType.SELECT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        null, "订单状态",
                        FieldRuleListBuilder.create()
                                .add(FieldRuleBuilder.create("订单状态").required()),
                        null
                )
                .add("orderPrice", "orderPrice", "订单价格", "",
                        FieldType.TEXT, SearchType.CAN_NOT_SEARCH, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        null, null, null, null
                )
                .add("orderDate", "orderDate", "下单时间", "",
                        FieldType.TEXT, SearchType.CAN_NOT_SEARCH, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        null, null, null, null
                )
                .add("payDate", "payDate", "支付时间", "",
                        FieldType.TEXT, SearchType.CAN_NOT_SEARCH, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        null, null, null, null
                )
                .add("cancelDate", "cancelDate", "取消时间", "",
                        FieldType.TEXT, SearchType.CAN_NOT_SEARCH, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        null, null, null, null
                )
                .add("shipDate", "shipDate", "发货时间", "",
                        FieldType.TEXT, SearchType.CAN_NOT_SEARCH, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        null, null, null, null
                )
                .add("deliverDate", "deliverDate", "送达时间", "",
                        FieldType.TEXT, SearchType.CAN_NOT_SEARCH, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        null, null, null, null
                )
                .add("expressId", "expressId", "运单号", "",
                        FieldType.TEXT, SearchType.INPUT, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        null, null, null, null
                )
                .add("comment", "comment", "发货备注", "",
                        FieldType.LONG_TEXT, SearchType.CAN_NOT_SEARCH, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        null, null, null, null
                )
                .build();

        // 指定需要翻译的字段
        OrderStatus[] orderStatusList = OrderStatus.values();
        HashMap<String, String> orderStatusMap = new HashMap<>(orderStatusList.length);
        for (OrderStatus orderStatus : orderStatusList) {
            orderStatusMap.put(orderStatus.getValue(), orderStatus.toString());
        }
        // build
        JSONArray fieldMapper = FieldMapperBuilder.create()
                .add("orderStatusCode", "orderStatusName", orderStatusMap)
                .build();

        // 拼装返回结果
        JSONObject map = new JSONObject(6);
        map.put("total", orderPageInfo.getTotal());
        map.put("list", voList);
        map.put("columns", columns);
        map.put("fieldMapper", fieldMapper);
        map.put("idFieldName", idFieldName);
        map.put("pageName", pageName);

        // 返回结果
        return Res.success(map);
    }

    // /**
    //  * 编辑订单
    //  *
    //  * @return
    //  */
    // @PostMapping("/manage/editOrder")
    // @ResponseBody
    // public Res editOrder(@ModelAttribute OrderVO OrderVO) {
    //     Order Order = OrderVO.convertTo(OrderVO);
    //
    //     // 先查询订单是否存在
    //     Order existOrder = orderService.getOrderById(Order.getId());
    //
    //     if (Order.getId() == null || Order.getId() < 1) {
    //         // 新增订单
    //         if (existOrder != null) {
    //             return Res.error("订单已存在，操作失败");
    //         }
    //
    //         if (Order.getOrdersName() == null || "".equals(Order.getOrdersName())) {
    //             return Res.error("订单名称不能为空");
    //         }
    //         Order.setId(null);
    //         orderService.addOrder(Order);
    //     } else {
    //         // 修改订单
    //         if (existOrder == null) {
    //             return Res.error("订单不存在，操作失败");
    //         }
    //
    //         orderService.updateOrder(Order);
    //     }
    //     return Res.success(true);
    // }
    //
    // /**
    //  * 关闭订单
    //  *
    //  * @param id
    //  * @return
    //  */
    // @PostMapping("/manage/deleteOrder")
    // @ResponseBody
    // public Res deleteOrder(Long id) {
    //     if (id == null || id <= 0) {
    //         return Res.error("订单不存在，删除失败");
    //     }
    //     // 先查询订单是否存在
    //     Order existOrder = orderService.getOrderById(id);
    //     if (existOrder == null) {
    //         return Res.error("订单不存在，删除失败");
    //     }
    //     boolean b = orderService.deleteOrder(existOrder.getId());
    //     return Res.success(b);
    // }

    /**
     * 导出订单列表
     *
     * @return
     */
    @GetMapping("/manage/exportOrderList")
    @ResponseBody
    public Res exportOrderList(OrderQuery orderQuery) {
        List<Order> orderList = orderService.getOrderList(orderQuery);
        List<OrderVO> orderVOList = OrderVO.convertFrom(orderList);

        // 当前时间
        Date now = Calendar.getInstance().getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd_HHmmss");
        String dateTime = format.format(now);

        HashMap<String, Object> map = new HashMap<>();
        map.put("list", orderVOList);
        map.put("sheetName", "订单表-" + System.currentTimeMillis());
        map.put("fileName", "订单表_导出时间_" + dateTime);

        return Res.success(map);
    }

}
