package com.yc.ship.module.trade.controller.admin.orderjzdetail;

import com.yc.ship.framework.apilog.core.annotation.ApiAccessLog;
import com.yc.ship.framework.common.pojo.CommonResult;
import com.yc.ship.framework.common.pojo.PageParam;
import com.yc.ship.framework.common.pojo.PageResult;
import com.yc.ship.framework.common.util.object.BeanUtils;
import com.yc.ship.framework.excel.core.util.ExcelUtils;
import com.yc.ship.framework.operatelog.core.annotations.OperateLog;
import com.yc.ship.module.product.dal.dataobject.voyage.VoyageDO;
import com.yc.ship.module.product.service.voyage.VoyageService;
import com.yc.ship.module.resource.dal.dataobject.route.ResourceRouteDO;
import com.yc.ship.module.resource.service.route.ResourceRouteService;
import com.yc.ship.module.system.api.dict.DictDataApi;
import com.yc.ship.module.system.api.dict.dto.DictDataRespDTO;
import com.yc.ship.module.trade.controller.admin.orderjzdetail.vo.*;
import com.yc.ship.module.trade.dal.dataobject.orderjzdetail.OrderJzDetailDO;
import com.yc.ship.module.trade.service.orderjzdetail.OrderJzDetailService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

import static com.yc.ship.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static com.yc.ship.framework.common.pojo.CommonResult.success;
import static com.yc.ship.framework.operatelog.core.enums.OperateTypeEnum.TRADE;

@Tag(name = "管理后台 - 订单接站人员名单")
@RestController
@RequestMapping("/trade/order-jz-detail")
@Validated
public class OrderJzDetailController {

  @Resource
  private OrderJzDetailService orderJzDetailService;

  @Resource
  private VoyageService voyageService;

  @Resource
  private ResourceRouteService resourceRouteService;

  @Resource
  DictDataApi dictDataApi;

  @PostMapping("/create")
  @Operation(summary = "创建订单接站人员名单")
  @PreAuthorize("@ss.hasPermission('trade:order-jz-detail:create')")
  public CommonResult<Long> createOrderJzDetail(@Valid @RequestBody OrderJzDetailSaveReqVO createReqVO) {
    return success(orderJzDetailService.createOrderJzDetail(createReqVO));
  }

  @PutMapping("/update")
  @Operation(summary = "更新订单接站人员名单")
  @PreAuthorize("@ss.hasPermission('trade:order-jz-detail:update')")
  public CommonResult<Boolean> updateOrderJzDetail(@Valid @RequestBody OrderJzDetailSaveReqVO updateReqVO) {
    orderJzDetailService.updateOrderJzDetail(updateReqVO);
    return success(true);
  }

  @DeleteMapping("/delete")
  @Operation(summary = "删除订单接站人员名单")
  @Parameter(name = "id", description = "编号", required = true)
  public CommonResult<Boolean> deleteOrderJzDetail(@RequestParam("id") Long id) {
    orderJzDetailService.deleteOrderJzDetail(id);
    return success(true);
  }

  @GetMapping("/get")
  @Operation(summary = "获得订单接站人员名单")
  @Parameter(name = "id", description = "编号", required = true, example = "1024")
  @PreAuthorize("@ss.hasPermission('trade:order-jz-detail:query')")
  public CommonResult<OrderJzDetailRespVO> getOrderJzDetail(@RequestParam("id") Long id) {
    OrderJzDetailDO orderJzDetail = orderJzDetailService.getOrderJzDetail(id);
    return success(BeanUtils.toBean(orderJzDetail, OrderJzDetailRespVO.class));
  }

  @GetMapping("/page")
  @Operation(summary = "获得订单接站人员名单分页")
  @PreAuthorize("@ss.hasPermission('trade:order-jz-detail:query')")
  public CommonResult<PageResult<OrderJzDetailRespVO>> getOrderJzDetailPage(@Valid OrderJzDetailPageReqVO pageReqVO) {
    PageResult<OrderJzDetailDO> pageResult = orderJzDetailService.getOrderJzDetailPage(pageReqVO);
    return success(BeanUtils.toBean(pageResult, OrderJzDetailRespVO.class));
  }

  @GetMapping("/export-excel")
  @Operation(summary = "导出订单接站人员名单 Excel")
  @ApiAccessLog(operateType = EXPORT)
//  @PreAuthorize("@ss.hasPermission('trade:order-jz-detail:query')")
  public void exportOrderJzDetailExcel(@Valid OrderJzDetailPageReqVO pageReqVO,
                                       HttpServletResponse response) throws IOException {
    if (StringUtils.isEmpty(pageReqVO.getVoyageId())) {
      throw new RuntimeException("航次编号不能为空");
    }
    VoyageDO voyageDO = voyageService.getVoyage(Long.valueOf(pageReqVO.getVoyageId()));
    if (voyageDO == null) {
      throw new RuntimeException("航次信息不能为空");
    }

    pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
    List<OrderJzDetailDO> list = orderJzDetailService.selectPageByVoyageId(pageReqVO.getVoyageId());

    List<DictDataRespDTO> dictAddressList = null;
    ResourceRouteDO resourceRouteDO = resourceRouteService.getRoute(voyageDO.getRouteId());
    if (resourceRouteDO != null) {
      int dir = resourceRouteDO.getDirection().intValue();
      if (dir == 2) {
        dictAddressList = dictDataApi.getDictDataList("order_jz_x");
      } else {
        dictAddressList = dictDataApi.getDictDataList("order_jz");
      }
    }


    final List<DictDataRespDTO> dictTimeList = dictDataApi.getDictDataList("order_time_jz");
    // 导出 Excel
    List<OrderJzDetailRespVO> exportList = BeanUtils.toBean(list, OrderJzDetailRespVO.class);
    final List<DictDataRespDTO> finalAddressList = dictAddressList;
    exportList.forEach(vo -> {
      vo.setVoyage(voyageDO.getName());

      // 接站地点
      if (finalAddressList != null) {
        List<DictDataRespDTO> addressList = finalAddressList.stream().filter(d -> d.getValue().equals(vo.getAddress())).collect(Collectors.toList());
        if (!addressList.isEmpty()) {
          vo.setAddress(addressList.get(0).getLabel());
        }
      }

      // 接站时间
      if(dictTimeList!=null) {
        List<DictDataRespDTO> timeList = dictTimeList.stream().filter(d -> d.getValue().equals(vo.getArriveTime())).collect(Collectors.toList());
        if (!timeList.isEmpty()) {
          vo.setArriveTime(timeList.get(0).getLabel());
        }
      }
    });
    ExcelUtils.write(response, "订单接站人员名单.xls", "数据", OrderJzDetailRespVO.class,
      BeanUtils.toBean(exportList, OrderJzDetailRespVO.class));
  }


  @PostMapping("/sign")
  @PermitAll
  @Operation(summary = "订单接站人员名单签到")
  @OperateLog(type = TRADE)
  public CommonResult<Long> createOrderJzDetail(@Valid @RequestBody List<OrderJzDetailSaveReqVO> createReqVOList) {
    // 校验身份证号是否与订单游客信息一致，并填充 visitorId
    orderJzDetailService.validateAndFillVisitorId(createReqVOList);
    return success(orderJzDetailService.createOrderJzDetail(createReqVOList));
  }

  @GetMapping("/simple-list")
  @Operation(summary = "获得订单接站人员名单")
  public CommonResult<List<OrderJzDetailRespVO>> getOrderJzDetailList(@Valid OrderJzDetailPageReqVO pageReqVO) {
    List<OrderJzDetailDO> pageResult = orderJzDetailService.getOrderJzDetailList(pageReqVO);
    return success(BeanUtils.toBean(pageResult, OrderJzDetailRespVO.class));
  }




  @GetMapping("/visitor/query")
  @Operation(summary = "获得订单接站人员名单分页")
  @PreAuthorize("@ss.hasPermission('trade:order-jz-detail-sign:query')")
  public CommonResult<PageResult<OrderJzDetailRespVO>> queryOrderVisitorPage(@Valid OrderJzDetailPageReqVO pageReqVO) {
    PageResult<OrderJzDetailDO> pageResult = orderJzDetailService.getOrderJzDetailPage2(pageReqVO);
    return success(BeanUtils.toBean(pageResult, OrderJzDetailRespVO.class));
  }

  @GetMapping("/visitor/export-excel")
  @Operation(summary = "导出游客接站明细 Excel")
  @ApiAccessLog(operateType = EXPORT)
  @PreAuthorize("@ss.hasPermission('trade:order-jz-detail-sign:query')")
  public void exportVisitorExcel(@Valid OrderJzDetailPageReqVO pageReqVO,
                                 HttpServletResponse response) throws IOException {
    if (StringUtils.isEmpty(pageReqVO.getVoyageId())) {
      throw new RuntimeException("航次编号不能为空");
    }
    VoyageDO voyageDO = voyageService.getVoyage(Long.valueOf(pageReqVO.getVoyageId()));
    if (voyageDO == null) {
      throw new RuntimeException("航次信息不能为空");
    }

    // 查询导出数据（条件与visitor/query一致）
    List<OrderJzDetailDO> list = orderJzDetailService.getVisitorExportList(pageReqVO);

    // 获取字典数据
    List<DictDataRespDTO> dictAddressList = null;
    ResourceRouteDO resourceRouteDO = resourceRouteService.getRoute(voyageDO.getRouteId());
    if (resourceRouteDO != null) {
      int dir = resourceRouteDO.getDirection().intValue();
      if (dir == 2) {
        dictAddressList = dictDataApi.getDictDataList("order_jz_x");
      } else {
        dictAddressList = dictDataApi.getDictDataList("order_jz");
      }
    }
    final List<DictDataRespDTO> dictTimeList = dictDataApi.getDictDataList("order_time_jz");

    // 转换为导出 VO
    List<OrderJzDetailExportVO> exportList = new java.util.ArrayList<>();
    final List<DictDataRespDTO> finalAddressList = dictAddressList;
    for (int i = 0; i < list.size(); i++) {
      OrderJzDetailDO detail = list.get(i);
      OrderJzDetailExportVO vo = new OrderJzDetailExportVO();
      vo.setIndex(i + 1);
      vo.setOrderNo(detail.getOrderNo());
      vo.setName(detail.getName());
      vo.setIdCard(detail.getIdCard());
      vo.setPhone(detail.getPhone());
      vo.setRoomModelName(detail.getRoomModelName());
      vo.setRemark(detail.getRemark());
      vo.setSignTime(detail.getSignTime());
      vo.setDispatchNo(detail.getDispatchNo());
        vo.setGroupNo(detail.getGroupNo());
        vo.setBusNumber(detail.getBusNumber());
        vo.setDriverName(detail.getDriverName());
        vo.setDriverPhone(detail.getDriverPhone());
        vo.setReceiverName(detail.getReceiverName());
        vo.setReceiverPhone(detail.getReceiverPhone());
        vo.setDispatchRemark(detail.getDispatchRemark());
      vo.setReservationInfo(detail.getRemark());

      // 站点字典转义
      if (finalAddressList != null && detail.getAddress() != null) {
        final String addr = detail.getAddress();
        DictDataRespDTO matched = finalAddressList.stream()
          .filter(d -> d.getValue().equals(addr)).findFirst().orElse(null);
        if (matched != null) {
          vo.setAddress(matched.getLabel());
        } else {
          vo.setAddress(addr);
        }
      }

      // 接站时间字典转义
      if (dictTimeList != null && detail.getArriveTime() != null) {
        final String time = detail.getArriveTime();
        DictDataRespDTO matched = dictTimeList.stream()
          .filter(d -> d.getValue().equals(time)).findFirst().orElse(null);
        if (matched != null) {
          vo.setArriveTime(matched.getLabel());
        } else {
          vo.setArriveTime(time);
        }
      }

      exportList.add(vo);
    }

    ExcelUtils.write(response, "游客接站明细.xls", "数据",
      OrderJzDetailExportVO.class, exportList);
  }


  @GetMapping("/order/query")
  @Operation(summary = "获得订单接站人员订单分页")
  @PreAuthorize("@ss.hasPermission('trade:order-jz-detail-sign:query')")
  public CommonResult<PageResult<?>> queryOrderPage(@Valid OrderJzDetailPageReqVO pageReqVO) {
    PageResult<?> pageResult = orderJzDetailService.getOrderJzDetailPage3(pageReqVO);
    return success(pageResult);
  }

  @PostMapping("/visitor/sign")
  @Operation(summary = "游客登记")
  @PreAuthorize("@ss.hasPermission('trade:order-jz-detail-sign:save')")
  public CommonResult<Long> visitorSign(@Valid @RequestBody OrderJzDetailSaveReqVO createReqVO) {
    return success(orderJzDetailService.signOrderJzDetail(createReqVO));
  }

  @PostMapping("/visitor/batch-sign")
  @Operation(summary = "批量核销（一键核销）")
  public CommonResult<Integer> batchVisitorSign(@Valid @RequestBody OrderJzDetailBatchSignReqVO reqVO) {
    int count = orderJzDetailService.batchSignOrderJzDetail(reqVO.getIds(), reqVO.getSignRemark());
    return success(count);
  }


  @DeleteMapping("/visitor/sign/clean")
  @Operation(summary = "游客登记")
  @PreAuthorize("@ss.hasPermission('trade:order-jz-detail-sign:delete')")
  public CommonResult<Long> visitorSignClean(String  id) {
    return success(orderJzDetailService.cleanOrderJzDetail(id));
  }

  // ==================== 订单分车相关接口 ====================

  @Resource
  private com.yc.ship.module.trade.service.orderjzdetail.OrderJzDispatchService orderJzDispatchService;

  @PostMapping("/dispatch/create")
  @Operation(summary = "创建订单分车")
  @PreAuthorize("@ss.hasPermission('trade:order-jz-detail:dispatch')")
  public CommonResult<Long> createOrderJzDispatch(@Valid @RequestBody com.yc.ship.module.trade.controller.admin.orderjzdetail.vo.OrderJzDispatchSaveReqVO createReqVO) {
    // 如果前端没有传分车时间，则使用当前时间
    if (createReqVO.getDispatchTime() == null) {
      createReqVO.setDispatchTime(java.time.LocalDateTime.now());
    }
    return success(orderJzDispatchService.createOrderJzDispatch(createReqVO));
  }

  @PutMapping("/dispatch/update")
  @Operation(summary = "更新订单分车")
  @PreAuthorize("@ss.hasPermission('trade:order-jz-detail:dispatch')")
  public CommonResult<Boolean> updateOrderJzDispatch(@Valid @RequestBody com.yc.ship.module.trade.controller.admin.orderjzdetail.vo.OrderJzDispatchSaveReqVO updateReqVO) {
    orderJzDispatchService.updateOrderJzDispatch(updateReqVO);
    return success(true);
  }

  @DeleteMapping("/dispatch/delete")
  @Operation(summary = "删除订单分车")
  @Parameter(name = "id", description = "接站人员ID（OrderJzDetailDO.id）", required = true)
  public CommonResult<Boolean> deleteOrderJzDispatch(@RequestParam("id") Long id) {
    orderJzDispatchService.deleteOrderJzDispatch(id);
    return success(true);
  }

  @GetMapping("/dispatch/get")
  @Operation(summary = "获得订单分车")
  @Parameter(name = "id", description = "编号", required = true, example = "1024")
  public CommonResult<com.yc.ship.module.trade.controller.admin.orderjzdetail.vo.OrderJzDispatchRespVO> getOrderJzDispatch(@RequestParam("id") Long id) {
    com.yc.ship.module.trade.dal.dataobject.orderjzdispatch.OrderJzDispatchDO orderJzDispatch = orderJzDispatchService.getOrderJzDispatch(id);
    return success(BeanUtils.toBean(orderJzDispatch, com.yc.ship.module.trade.controller.admin.orderjzdetail.vo.OrderJzDispatchRespVO.class));
  }

  @PostMapping("/dispatch/batch-create")
  @Operation(summary = "批量保存订单分车（有dispatchId更新，无则新建）")
  @PreAuthorize("@ss.hasPermission('trade:order-jz-detail:dispatch')")
  public CommonResult<Boolean> batchSaveOrderJzDispatch(@Valid @RequestBody OrderJzDispatchBatchReqVO batchReqVO) {
    // 校验分车记录是否重复：按分车号+航次ID（有组团号则加上组团号）条件查询
    String duplicateMsg = orderJzDispatchService.checkDispatchDuplicate(batchReqVO.getDispatchInfo());
    if (duplicateMsg != null) {
      return CommonResult.error(500, duplicateMsg);
    }
    orderJzDispatchService.batchSaveOrderJzDispatch(batchReqVO);
    return success(true);
  }

    // ==================== 赠送行程接站相关接口 ====================

  @GetMapping("/gift/query")
  @Operation(summary = "获得赠送行程接站人员分页")
  @PreAuthorize("@ss.hasPermission('trade:order-jz-detail-sign:query')")
  public CommonResult<PageResult<OrderJzDetailRespVO>> queryGiftPage(@Valid OrderJzDetailPageReqVO pageReqVO) {
    PageResult<OrderJzDetailDO> pageResult = orderJzDetailService.getGiftPage(pageReqVO);
    return success(BeanUtils.toBean(pageResult, OrderJzDetailRespVO.class));
  }

  @GetMapping("/gift/export-excel")
  @Operation(summary = "导出赠送行程接站明细 Excel")
  @ApiAccessLog(operateType = EXPORT)
  @PreAuthorize("@ss.hasPermission('trade:order-jz-detail-sign:query')")
  public void exportGiftExcel(@Valid OrderJzDetailPageReqVO pageReqVO,
                              HttpServletResponse response) throws IOException {
    if (StringUtils.isEmpty(pageReqVO.getVoyageId())) {
      throw new RuntimeException("航次编号不能为空");
    }
    VoyageDO voyageDO = voyageService.getVoyage(Long.valueOf(pageReqVO.getVoyageId()));
    if (voyageDO == null) {
      throw new RuntimeException("航次信息不能为空");
    }

    // 查询导出数据（条件与gift/query一致）
    List<OrderJzDetailDO> list = orderJzDetailService.getGiftExportList(pageReqVO);

    // 获取字典数据
    List<DictDataRespDTO> dictAddressList = null;
    ResourceRouteDO resourceRouteDO = resourceRouteService.getRoute(voyageDO.getRouteId());
    if (resourceRouteDO != null) {
      int dir = resourceRouteDO.getDirection().intValue();
      if (dir == 2) {
        dictAddressList = dictDataApi.getDictDataList("order_jz_x");
      } else {
        dictAddressList = dictDataApi.getDictDataList("order_jz");
      }
    }
    final List<DictDataRespDTO> dictTimeList = dictDataApi.getDictDataList("order_time_jz");

    // 转换为导出 VO
    List<OrderJzDetailExportVO> exportList = new java.util.ArrayList<>();
    final List<DictDataRespDTO> finalAddressList = dictAddressList;
    for (int i = 0; i < list.size(); i++) {
      OrderJzDetailDO detail = list.get(i);
      OrderJzDetailExportVO vo = new OrderJzDetailExportVO();
      vo.setIndex(i + 1);
      vo.setOrderNo(detail.getOrderNo());
      vo.setName(detail.getName());
      vo.setIdCard(detail.getIdCard());
      vo.setPhone(detail.getPhone());
      vo.setRoomModelName(detail.getRoomModelName());
      vo.setRemark(detail.getRemark());
      vo.setSignTime(detail.getSignTime());
      vo.setDispatchNo(detail.getDispatchNo());
        vo.setGroupNo(detail.getGroupNo());
        vo.setBusNumber(detail.getBusNumber());
        vo.setDriverName(detail.getDriverName());
        vo.setDriverPhone(detail.getDriverPhone());
        vo.setReceiverName(detail.getReceiverName());
        vo.setReceiverPhone(detail.getReceiverPhone());
        vo.setDispatchRemark(detail.getDispatchRemark());
      vo.setReservationInfo(detail.getRemark());

      // 站点字典转义
      if (finalAddressList != null && detail.getAddress() != null) {
        final String addr = detail.getAddress();
        DictDataRespDTO matched = finalAddressList.stream()
          .filter(d -> d.getValue().equals(addr)).findFirst().orElse(null);
        if (matched != null) {
          vo.setAddress(matched.getLabel());
        } else {
          vo.setAddress(addr);
        }
      }

      // 接站时间字典转义
      if (dictTimeList != null && detail.getArriveTime() != null) {
        final String time = detail.getArriveTime();
        DictDataRespDTO matched = dictTimeList.stream()
          .filter(d -> d.getValue().equals(time)).findFirst().orElse(null);
        if (matched != null) {
          vo.setArriveTime(matched.getLabel());
        } else {
          vo.setArriveTime(time);
        }
      }

      exportList.add(vo);
    }

    ExcelUtils.write(response, "赠送行程接站明细.xls", "数据",
      OrderJzDetailExportVO.class, exportList);
  }

  @GetMapping("/gift/order/query")
  @Operation(summary = "获得赠送行程补登订单分页")
  @PreAuthorize("@ss.hasPermission('trade:order-jz-detail-sign:query')")
  public CommonResult<PageResult<?>> queryGiftOrderPage(@Valid OrderJzDetailPageReqVO pageReqVO) {
    PageResult<?> pageResult = orderJzDetailService.getGiftOrderPage(pageReqVO);
    return success(pageResult);
  }


    // ==================== 分车记录相关接口 ====================

  @GetMapping("/dispatch/record/page")
  @Operation(summary = "获得分车记录分页")
  @PreAuthorize("@ss.hasPermission('trade:order-jz-detail:query')")
  public CommonResult<PageResult<OrderJzDispatchRecordRespVO>> getDispatchRecordPage(
          @Valid OrderJzDispatchPageReqVO pageReqVO) {
    PageResult<OrderJzDispatchRecordRespVO> pageResult = orderJzDispatchService.getDispatchRecordPage(pageReqVO);
    return success(pageResult);
  }

  @GetMapping("/dispatch/record/export-excel")
  @Operation(summary = "导出分车记录 Excel")
  @ApiAccessLog(operateType = EXPORT)
  @PreAuthorize("@ss.hasPermission('trade:order-jz-detail:query')")
  public void exportDispatchRecordExcel(@Valid OrderJzDispatchPageReqVO pageReqVO,
                                         HttpServletResponse response) throws IOException {
    if (pageReqVO.getVoyageId() == null) {
      throw new RuntimeException("航次编号不能为空");
    }
    List<OrderJzDispatchRecordRespVO> list = orderJzDispatchService.getDispatchRecordExportList(pageReqVO);
    ExcelUtils.write(response, "分车记录.xls", "数据", OrderJzDispatchRecordRespVO.class, list);
  }

  // ==================== 分车记录编辑接口 ====================

  @PostMapping("/dispatch/record/update")
  @Operation(summary = "更新分车记录")
  /*@PreAuthorize("@ss.hasPermission('trade:order-jz-detail:dispatch')")*/
  public CommonResult<Boolean> updateDispatchRecord(@Valid @RequestBody OrderJzDispatchSaveReqVO updateReqVO) {
    orderJzDispatchService.updateDispatchRecord(updateReqVO);
    return success(true);
  }

}