package org.wcs.serve.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.wcs.constant.enums.common.OnOrOffEnum;
import org.wcs.constant.enums.database.TrayConveyLocationTypeEnum;
import org.wcs.factory.AppServeResponseFactory;
import org.wcs.mapper.intf.AppTrayConveyLocationService;
import org.wcs.model.bo.tuple.Tuple2;
import org.wcs.model.dto.serve.trayConveyLocation.AddTrayConveyLocationReq;
import org.wcs.model.dto.serve.trayConveyLocation.QueryTrayConveyLocationReq;
import org.wcs.model.dto.serve.trayConveyLocation.UpdateTrayConveyLocationReq;
import org.wcs.model.po.app.AppTrayConveyLocation;
import org.wcs.model.vo.serve.AppServeDataResponse;
import org.wcs.model.vo.serve.AppServeResponse;
import org.wcs.model.vo.serve.common.PageDataResponse;
import org.wcs.model.vo.serve.trayConveyLocation.ExportAppTrayConveyLocationVo;
import org.wcs.model.vo.serve.trayConveyLocation.QueryTrayConveyLocationVo;
import org.wcs.model.vo.serve.trayConveyLocation.TrayConveyStatusVo;
import org.wcs.plugin.excel.ExcelPoi;
import org.wcs.plugin.plc.PlcCommunicationFactory;
import org.wcs.plugin.plc.model.TaskConveyStatus;
import org.wcs.serve.service.intf.ITrayConveyLocationService;
import org.wcs.utils.AppBeanUtils;
import org.wcs.utils.AppStringUtils;
import org.wcs.utils.AppUUIDUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class TrayConveyLocationService implements ITrayConveyLocationService {

    private final ExcelPoi excelPoi;
    private final AppTrayConveyLocationService trayConveyLocationService;

    /**
     * 分页查询托盘线点位数据
     * @param request 查询参数
     * @param pageSize 分页单页大小
     * @param pageIndex 分页页码
     * @return 查询结果
     */
    @Override
    public AppServeDataResponse<PageDataResponse<QueryTrayConveyLocationVo>> queryTrayConveyLocation(QueryTrayConveyLocationReq request, Integer pageSize, Integer pageIndex) {
        if(pageSize == null || pageSize <= 0 || pageIndex == null || pageIndex <= 0) {
            return AppServeResponseFactory.fail("分页参数错误", null);
        }
        Tuple2<Long, List<AppTrayConveyLocation>> queryResult = trayConveyLocationService.queryTrayConveyLocation(request, pageSize, pageIndex);
        if(queryResult == null) {
            return AppServeResponseFactory.internalServerError("数据服务异常", null);
        }
        List<QueryTrayConveyLocationVo> queryTrayConveyLocationVos = AppBeanUtils.copyListProperties(queryResult.getItem2(), QueryTrayConveyLocationVo::new);
        PageDataResponse<QueryTrayConveyLocationVo> pageDataResponse = new PageDataResponse<>();
        pageDataResponse.setPageIndex(pageIndex);
        pageDataResponse.setPageSize(pageSize);
        pageDataResponse.setTotalCount(queryResult.getItem1());
        pageDataResponse.setData(queryTrayConveyLocationVos);
        return AppServeResponseFactory.success("查询成功", pageDataResponse);
    }

    /**
     * 添加托盘线点位数据
     * @param request 添加参数
     * @return 添加结果
     */
    @Override
    public AppServeResponse addTrayConveyLocation(AddTrayConveyLocationReq request) {
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录");
        }
        String operationUserId = userIdObj.toString();
        log.info("用户：{} 想要添加托盘输送线点位数据：{}", operationUserId, AppStringUtils.objectToString(request));
        AppTrayConveyLocation appTrayConveyLocation = new AppTrayConveyLocation();
        appTrayConveyLocation.setId(AppUUIDUtils.getNewUUID());
        appTrayConveyLocation.setLocationId(request.getLocationId());
        appTrayConveyLocation.setBusinessLocationId(request.getBusinessLocationId());
        appTrayConveyLocation.setLocationName(request.getLocationName());
        appTrayConveyLocation.setLocationStatus(request.getLocationStatus());
        appTrayConveyLocation.setLocationType(request.getLocationType());
        appTrayConveyLocation.setPlcId(request.getPlcId());
        appTrayConveyLocation.setLocationXyz(request.getLocationXyz());
        appTrayConveyLocation.setAreaId(request.getAreaId());
        appTrayConveyLocation.setReadStatusAddress(request.getReadStatusAddress());
        appTrayConveyLocation.setWriteTaskAddress(request.getWriteTaskAddress());
        appTrayConveyLocation.setCreateTime(LocalDateTime.now());
        appTrayConveyLocation.setUpdateTime(LocalDateTime.now());
        appTrayConveyLocation.setRemark(request.getRemark());
        int saveResult = trayConveyLocationService.insert(appTrayConveyLocation);
        return saveResult > 0 ? AppServeResponseFactory.success() : AppServeResponseFactory.fail("数据服务异常");
    }

    /**
     * 更新托盘站台的数据
     * @param request  数据
     * @return 响应结果
     */
    @Override
    public AppServeResponse updateTrayConveyLocation(UpdateTrayConveyLocationReq request) {
        if(request == null) {
            return AppServeResponseFactory.fail("数据不能为空");
        }
        Object userIdObj = StpUtil.getLoginId();
        if(userIdObj == null) {
            return AppServeResponseFactory.unauthorized("用户未登录");
        }
        String operationUserId = userIdObj.toString();
        log.info("用户：{} 想要更新托盘输送线点位数据：{}", operationUserId, AppStringUtils.objectToString(request));
        AppTrayConveyLocation appTrayConveyLocation = new AppTrayConveyLocation();
        appTrayConveyLocation.setId(request.getId());
        appTrayConveyLocation.setLocationId(request.getLocationId());
        appTrayConveyLocation.setBusinessLocationId(request.getBusinessLocationId());
        appTrayConveyLocation.setLocationName(request.getLocationName());
        appTrayConveyLocation.setLocationStatus(request.getLocationStatus());
        appTrayConveyLocation.setLocationType(request.getLocationType());
        appTrayConveyLocation.setPlcId(request.getPlcId());
        appTrayConveyLocation.setLocationXyz(request.getLocationXyz());
        appTrayConveyLocation.setAreaId(request.getAreaId());
        appTrayConveyLocation.setReadStatusAddress(request.getReadStatusAddress());
        appTrayConveyLocation.setWriteTaskAddress(request.getWriteTaskAddress());
        appTrayConveyLocation.setCreateTime(LocalDateTime.now());
        appTrayConveyLocation.setUpdateTime(LocalDateTime.now());
        appTrayConveyLocation.setRemark(request.getRemark());
        int saveResult = trayConveyLocationService.update(appTrayConveyLocation);
        return saveResult > 0 ? AppServeResponseFactory.success() : AppServeResponseFactory.fail("数据服务异常");
    }

    /**
     * 查询托盘输送线点位数据
     * @param conveyId 输送点位ID
     * @return 查询结果
     */
    @Override
    public AppServeDataResponse<TrayConveyStatusVo> queryTrayConveyStatus(String conveyId) {
        List<AppTrayConveyLocation> locationList = trayConveyLocationService.getDataByLocationId(conveyId);
        if(locationList == null || locationList.isEmpty()) {
            return AppServeResponseFactory.fail("数据服务异常或者点位不存在", null);
        }
        AppTrayConveyLocation trayConveyLocation = locationList.getFirst();
        Tuple2<String, TaskConveyStatus> taskConveyStatusTuple2 = PlcCommunicationFactory.getPlcCommunicationByPlcId(trayConveyLocation.getPlcId()).readTaskConveyStatus(conveyId);
        if(AppStringUtils.isNotEmpty(taskConveyStatusTuple2.item1)) {
            return AppServeResponseFactory.fail(taskConveyStatusTuple2.item1, null);
        }
        if(taskConveyStatusTuple2.item2 == null) {
            return AppServeResponseFactory.fail("查询失败", null);
        }
        TrayConveyStatusVo trayConveyStatusVo = new TrayConveyStatusVo();
        AppBeanUtils.copyProperties(taskConveyStatusTuple2.item2, trayConveyStatusVo);
        return AppServeResponseFactory.success("查询成功", trayConveyStatusVo);
    }

    /**
     * 下载托盘输送线点位数据
     * @param response 响应对象
     * @param request 请求参数
     */
    @Override
    public void downLoadTrayConveyLocation(HttpServletResponse response, QueryTrayConveyLocationReq request) {
        List<AppTrayConveyLocation> trayConveyLocations = trayConveyLocationService.queryTrayConveyLocation(request);
        if(trayConveyLocations == null || trayConveyLocations.isEmpty()) {
            trayConveyLocations = new ArrayList<>();
        }
        List<ExportAppTrayConveyLocationVo> exportAppTrayConveyLocationVos = new ArrayList<>();
        for (AppTrayConveyLocation trayConveyLocation : trayConveyLocations) {
            ExportAppTrayConveyLocationVo exportAppTrayConveyLocationVo = new ExportAppTrayConveyLocationVo();
            BeanUtils.copyProperties(trayConveyLocation, exportAppTrayConveyLocationVo);
            exportAppTrayConveyLocationVo.setLocationStatus(OnOrOffEnum.getByCode(trayConveyLocation.getLocationStatus()).getMsg());
            exportAppTrayConveyLocationVo.setLocationType(TrayConveyLocationTypeEnum.getByCode(trayConveyLocation.getLocationType()).getMsg());
            exportAppTrayConveyLocationVos.add(exportAppTrayConveyLocationVo);
        }
        try{
            excelPoi.doWriteExcel("托盘输送点位", response, exportAppTrayConveyLocationVos, ExportAppTrayConveyLocationVo.class);
        } catch (Exception e) {
            log.error("导出托盘输送点位失败", e);
        }
    }
}
