package cn.iocoder.yudao.module.system.service.biz;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.common.util.string.StringUtil;
import cn.iocoder.yudao.framework.excel.core.util.ExportData;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.system.controller.admin.biz.vo.*;
import cn.iocoder.yudao.module.system.controller.admin.biz.vo.excel.ScheduleShiftExcelVO;
import cn.iocoder.yudao.module.system.dal.dataobject.biz.NurseScheduleDO;
import cn.iocoder.yudao.module.system.dal.dataobject.biz.ScheduleShiftDO;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.yudao.module.system.dal.mysql.biz.ScheduleMapper;
import cn.iocoder.yudao.module.system.dal.mysql.biz.ScheduleShiftMapper;
import cn.iocoder.yudao.module.system.dal.mysql.dept.DeptMapper;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SCHEDULE_SHIFT_NOT_EXISTS;

/**
 * @Author: jinyd
 * @CreateTime: 2024/9/14  9:34
 * @Description:
 * @Version: 4.0
 */

@Service
@Validated
public class ScheduleShiftServiceImpl implements ScheduleShiftService{

    @Resource
    private ScheduleShiftMapper scheduleShiftMapper;
    @Resource
    private ScheduleMapper scheduleMapper;

    @Resource
    private DeptMapper deptMapper;

    @Override
    public Long createScheduleShift(ScheduleShiftSaveReqVO createReqVO) {
        Long nurseScheduleId = scheduleMapper.checkExist(createReqVO.getDeptId(), createReqVO.getScheduleDate());
        if (null == nurseScheduleId || nurseScheduleId < 1) {
            DeptDO deptDO = deptMapper.selectById(createReqVO.getDeptId());
            LocalDate localDate = LocalDate.parse(createReqVO.getScheduleDate() + "-01");
            NurseScheduleDO nurseScheduleDO = new NurseScheduleDO();
            nurseScheduleDO.setScheduleName(deptDO.getName() + " " + createReqVO.getScheduleDate() + " 月排班表");
            nurseScheduleDO.setStartDate(localDate.with(TemporalAdjusters.firstDayOfMonth()));
            nurseScheduleDO.setEndDate(localDate.with(TemporalAdjusters.lastDayOfMonth()));
            nurseScheduleDO.setScheduleDate(createReqVO.getScheduleDate());
            nurseScheduleDO.setDeptId(createReqVO.getDeptId());
            nurseScheduleDO.setTenantId(createReqVO.getTenantId());
            scheduleMapper.insert(nurseScheduleDO);
            nurseScheduleId = nurseScheduleDO.getId();
        }
        List<ScheduleShiftSaveDetailReqVO> scheduleShiftList = createReqVO.getScheduleShiftList();
        if (scheduleShiftList != null && !scheduleShiftList.isEmpty()) {
            List<ScheduleShiftDO> insertList = new ArrayList<>();
            for (int i = 0; i < scheduleShiftList.size(); i++) {
                ScheduleShiftSaveDetailReqVO scheduleShiftSaveDetailReqVO = scheduleShiftList.get(i);
                List<ScheduleShiftSaveListReqVO> scheduleShiftDetailList = scheduleShiftSaveDetailReqVO.getScheduleShiftDetailList();
                if (null == scheduleShiftDetailList || scheduleShiftDetailList.size() == 0) {
                    continue;
                }
                if (1 == scheduleShiftSaveDetailReqVO.getType()) {
                    scheduleShiftMapper.delete(new LambdaQueryWrapperX<ScheduleShiftDO>()
                            .eq(ScheduleShiftDO::getNurseId, scheduleShiftSaveDetailReqVO.getNurseId()));
                } else {
                    //先删除
                    // 格式化getWorkDate日期比较createReqVO.getScheduleDate()
                    scheduleShiftMapper.deleteWorkDate(scheduleShiftSaveDetailReqVO.getNurseId(),
                            nurseScheduleId, createReqVO.getScheduleDate());
                }
                for (int j = 0; j < scheduleShiftDetailList.size(); j++) {
                    ScheduleShiftSaveListReqVO scheduleShiftSaveListReqVO = scheduleShiftDetailList.get(j);
                    ScheduleShiftDO scheduleShiftDO = BeanUtils.toBean(scheduleShiftSaveListReqVO, ScheduleShiftDO.class);
                    scheduleShiftDO.setScheduleId(nurseScheduleId);
                    scheduleShiftDO.setType(scheduleShiftSaveDetailReqVO.getType());
                    scheduleShiftDO.setNurseId(scheduleShiftSaveDetailReqVO.getNurseId());
                    scheduleShiftDO.setTenantId(createReqVO.getTenantId());
                    if (null != scheduleShiftDO.getId()) {
                        scheduleShiftMapper.updateById(scheduleShiftDO);
                    } else {
                        if (null == scheduleShiftDO.getShiftId()) continue;
                        insertList.add(scheduleShiftDO);
                    }

                }
            }
            if (insertList.size() > 0) {
                scheduleShiftMapper.batchInsert(insertList);
            }
        }
        // 返回
        return nurseScheduleId;
    }

//    @Override
//    public void updateScheduleShift(ScheduleShiftSaveDetailReqVO updateReqVO) {
//        // 校验存在
//        validateScheduleShiftExists(updateReqVO.getId());
//        // 更新
//        ScheduleShiftDO updateObj = BeanUtils.toBean(updateReqVO, ScheduleShiftDO.class);
//        scheduleShiftMapper.updateById(updateObj);
//    }

    @Override
    public void deleteScheduleShift(Long id) {
        // 校验存在
        validateScheduleShiftExists(id);
        // 删除
        scheduleShiftMapper.deleteById(id);
    }

    private void validateScheduleShiftExists(Long id) {
        if (scheduleShiftMapper.selectById(id) == null) {
            throw exception(SCHEDULE_SHIFT_NOT_EXISTS);
        }
    }

    @Override
    public ScheduleShiftDO getScheduleShift(Long id) {
        return scheduleShiftMapper.selectById(id);
    }

    @Override
    public PageResult<ScheduleShiftPageListRespVO> getScheduleShiftPage(ScheduleShiftPageReqVO pageReqVO) {
        List<ScheduleShiftPageListRespVO> pageListRespVOList = new ArrayList<>();
        List<JSONObject> dayArr = new ArrayList<>();
        String scheduleDate = pageReqVO.getScheduleDate();
        LocalDate localDate = LocalDate.parse((scheduleDate + "-01").trim());
        int dayNum = localDate.lengthOfMonth();
        for (int i = 1; i <= dayNum; i++) {
            JSONObject obj = new JSONObject();
            String valueDate = scheduleDate + (i < 10 ? "-0" + i : "-" + i);
            obj.put("title", i);
            obj.put("value", valueDate);
            LocalDate valueLocalDate = LocalDate.parse(valueDate.trim());
            obj.put("week", convertToChinese(valueLocalDate.getDayOfWeek().getValue()));
            obj.put("prop", "a" + i);
            dayArr.add(obj);
        }

        Long nurseScheduleId = scheduleMapper.checkExist(pageReqVO.getDeptId(), pageReqVO.getScheduleDate());
        if (null != nurseScheduleId && nurseScheduleId > 0) {
            pageReqVO.setQueryFlag(1);
        }
        Page<ScheduleShiftPageRespVO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
        List<ScheduleShiftPageRespVO> list = scheduleShiftMapper.selectScheduleShiftList(page, pageReqVO);
        List<Map<String, Object>> dataList = new ArrayList<>();
        list.forEach(item -> {
            Map<String, Object> map = new HashMap<>();
            map.put("id", item.getId());
            map.put("nickname", item.getNickname());
            map.put("nurseScheduleId", item.getNurseScheduleId());
            map.put("nurseScheduleName", item.getNurseScheduleName());
            map.put("workStatus", item.getWorkStatus());
            map.put("scheduleName", item.getScheduleName());
            map.put("configs", item.getConfigs());
            map.put("workDate", item.getWorkDate());
            map.put("type", item.getType());
            if (!StringUtils.isEmpty(item.getShiftIds()) && StringUtil.isNotEmptyORNull(item.getScheduleDate())) {
                String[] shiftIds = item.getShiftIds().split(";");
                String[] shiftDates = item.getShiftDates().split(";");
                for (int i = 0; i < shiftDates.length; i++) {
                    map.put("a" + Integer.parseInt(shiftDates[i].substring(8)), Long.parseLong(shiftIds[i]));
                }
            }
            dataList.add(map);
        });

        ScheduleShiftPageListRespVO pageListRespVO = new ScheduleShiftPageListRespVO();
        pageListRespVO.setHeadList(dayArr);
        pageListRespVO.setDataList(dataList);
        pageListRespVOList.add(pageListRespVO);
        return new PageResult<>(pageListRespVOList, page.getTotal());
    }

    private String convertToChinese(int value) {
        String weekStr = "";
        switch (value) {
            case 1 : weekStr = "一"; break;
            case 2 : weekStr = "二"; break;
            case 3 : weekStr = "三"; break;
            case 4 : weekStr = "四"; break;
            case 5 : weekStr = "五"; break;
            case 6 : weekStr = "六"; break;
            case 7 : weekStr = "七"; break;
            default:
                throw new IllegalArgumentException("不支持的日期类型：" + value);

        }
        return weekStr;
    }

    @Override
    public List<NurseScheduleDO> getNurseScheduleList(ScheduleShiftPageReqVO pageReqVO) {
        return scheduleMapper.getNurseScheduleList(pageReqVO.getDeptId(), pageReqVO.getScheduleDate());
    }

    @Override
    public Boolean syncNurseSchedule(ScheduleShiftSaveReqVO createReqVO) {
        NurseScheduleDO nurseScheduleDO = scheduleMapper.selectById(createReqVO.getNurseScheduleId());
        List<ScheduleShiftDO> list = scheduleMapper.getNurseScheduleShiftList(createReqVO.getDeptId(), nurseScheduleDO.getScheduleDate());
        Long nurseScheduleId = scheduleMapper.checkExist(createReqVO.getDeptId(), createReqVO.getScheduleDate());
        if (null == nurseScheduleId || nurseScheduleId < 1) {
            DeptDO deptDO = deptMapper.selectById(createReqVO.getDeptId());
            LocalDate localDate = LocalDate.parse(createReqVO.getScheduleDate() + "-01");
            NurseScheduleDO insertDO = new NurseScheduleDO();
            insertDO.setScheduleName(deptDO.getName() + " "  + createReqVO.getScheduleDate() + " 月排班表");
            insertDO.setStartDate(localDate.with(TemporalAdjusters.firstDayOfMonth()));
            insertDO.setEndDate(localDate.with(TemporalAdjusters.lastDayOfMonth()));
            insertDO.setScheduleDate(createReqVO.getScheduleDate());
            insertDO.setDeptId(createReqVO.getDeptId());
            scheduleMapper.insert(insertDO);
            nurseScheduleId = insertDO.getId();
        }
        if (list != null && !list.isEmpty()) {
            scheduleShiftMapper.update(new LambdaUpdateWrapper<ScheduleShiftDO>().set(ScheduleShiftDO::getDeleted, true)
                    .eq(ScheduleShiftDO::getScheduleId, nurseScheduleId));
            for (int i = 0; i < list.size(); i++) {
                ScheduleShiftDO scheduleShiftDO = list.get(i);
                scheduleShiftDO.setId(null);
                scheduleShiftDO.setScheduleId(nurseScheduleId);
                if (!StringUtils.isEmpty(scheduleShiftDO.getWorkDate())) {
                    String[] split = scheduleShiftDO.getWorkDate().split("-");
                    scheduleShiftDO.setWorkDate(createReqVO.getScheduleDate() + "-" + split[2]);
                }
                scheduleShiftDO.getWorkDate();
                scheduleShiftMapper.insert(scheduleShiftDO);
            }
        }
        return Boolean.TRUE;
    }

    @Override
    public List<ScheduleShiftExcelVO> getScheduleShiftExcel(ScheduleShiftPageReqVO pageReqVO) {

        return null;
    }

    @Override
    public List<ExportData> getExportData(ScheduleShiftPageReqVO pageReqVO) {
        String scheduleDate = pageReqVO.getScheduleDate();
        LocalDate localDate = LocalDate.parse(scheduleDate + "-01");
        int daysInMonth = localDate.lengthOfMonth();
        List<LocalDate> datesInMonthList = IntStream.range(1, daysInMonth + 1)
                .mapToObj(day -> localDate.withDayOfMonth(day))
                .collect(Collectors.toList());



        ExportData exportData = new ExportData();
        exportData.setName("第一行");
        exportData.setValues(Arrays.asList("颐年养老院 2024-03月排班表"));
        List<ExportData> list = new ArrayList<>();
        list.add(exportData);


        ExportData exportData1 = new ExportData();
        exportData1.setName("第一行");
        exportData1.setValues(Arrays.asList("序号", "姓名", "性别", "年龄", "联系电话", "工作班次", "班次时间", "工作班次", "班次时间", "工作班次", "班次时间", "工作班次"));
        list.add(exportData1);
        return list;
    }
}
