package com.ecep.contract.ds.company.service;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.other.repository.HolidayTableRepository;
import com.ecep.contract.model.HolidayTable;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.vo.HolidayTableVo;
import com.fasterxml.jackson.databind.JsonNode;

import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Root;
import lombok.extern.slf4j.Slf4j;

/**
 * 节假日表服务类
 * 
 * @author System
 */
@Service
@CacheConfig(cacheNames = "HolidayTable")
@Slf4j
public class HolidayService implements IEntityService<HolidayTable>, QueryService<HolidayTableVo>, VoableService<HolidayTable, HolidayTableVo> {
    
    @Autowired
    private HolidayTableRepository holidayTableRepository;
    
    /**
     * 调整日期到工作日
     *
     * @param date 要调整的日期
     * @return 调整的日期
     */
    public LocalDate adjustToWorkDay(LocalDate date) {
        if (date == null) {
            return null;
        }
        
        while (date.getDayOfWeek() == DayOfWeek.SATURDAY || date.getDayOfWeek() == DayOfWeek.SUNDAY || isHoliday(date)) {
            date = date.plusDays(1);
        }
        return date;
    }
    
    /**
     * 检查日期是否为节假日
     * 
     * @param date 日期
     * @return 是否为节假日
     */
    public boolean isHoliday(LocalDate date) {
        if (date == null) {
            return false;
        }
        
        HolidayTable holidayTable = holidayTableRepository.findById(date).orElse(null);
        return holidayTable != null && holidayTable.isHoliday();
    }
    
    @Override
    public HolidayTable getById(Integer id) {
        throw new UnsupportedOperationException("HolidayTable uses LocalDate as ID, please use getById(LocalDate id) method instead");
    }
    
    /**
     * 根据LocalDate类型的ID查询实体
     * @param id 实体ID
     * @return 实体对象
     */
    public HolidayTable getById(LocalDate id) {
        if (id == null) {
            return null;
        }
        return holidayTableRepository.findById(id).orElse(null);
    }
    
    @Override
    public HolidayTable save(HolidayTable entity) {
        if (entity == null) {
            return null;
        }
        return holidayTableRepository.save(entity);
    }
    
    @Override
    public void delete(HolidayTable entity) {
        if (entity != null && entity.getId() != null) {
            holidayTableRepository.deleteById(entity.getId());
        }
    }
    
    /**
     * 根据LocalDate类型的ID删除实体
     * @param id 实体ID
     */
    public void deleteById(LocalDate id) {
        if (id != null) {
            holidayTableRepository.deleteById(id);
        }
    }
    
    /**
     * 获取所有节假日
     * @param pageable 分页参数
     * @return 分页结果
     */
    public Page<HolidayTable> findAll(Pageable pageable) {
        return holidayTableRepository.findAll(pageable);
    }
    
    @Override
    public Page<HolidayTable> findAll(Specification<HolidayTable> spec, Pageable pageable) {
        // 由于HolidayTableRepository不支持Specification查询，返回所有节假日
        return findAll(pageable);
    }
    
    @Override
    public Specification<HolidayTable> getSpecification(String searchText) {
        // 实现根据搜索文本构建规格化查询
        return (Root<HolidayTable> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            if (searchText != null && !searchText.trim().isEmpty()) {
                try {
                    // 尝试将搜索文本解析为日期
                    LocalDate date = LocalDate.parse(searchText.trim());
                    predicates.add(criteriaBuilder.equal(root.get("id"), date));
                } catch (DateTimeParseException e) {
                    // 如果不是日期格式，尝试其他搜索方式
                    // 由于HolidayTable只有id和holiday字段，这里无法进行其他字段的模糊搜索
                    log.warn("Search text '{}' is not a valid date format", searchText);
                }
            }
            
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
    }
    
    @Override
    public HolidayTableVo findById(Integer id) {
        throw new UnsupportedOperationException("HolidayTable uses LocalDate as ID, please use findById(Object id) instead");
    }
    
    @Cacheable(key = "#id", unless = "#result == null")
    public HolidayTableVo findById(LocalDate id) {
        HolidayTable entity = getById(id);
        return entity != null ? entity.toVo() : null;
    }
    
    @Override
    public Page<HolidayTableVo> findAll(JsonNode paramsNode, Pageable pageable) {
        // 实现根据JSON参数过滤节假日
        Page<HolidayTable> entityPage;
        
        if (paramsNode == null || paramsNode.isEmpty()) {
            // 如果没有参数，返回所有节假日
            entityPage = findAll(pageable);
        } else {
            // 处理参数过滤
            Boolean isHoliday = null;
            LocalDate startDate = null;
            LocalDate endDate = null;
            
            if (paramsNode.has("isHoliday")) {
                isHoliday = paramsNode.get("isHoliday").asBoolean();
            }
            
            if (paramsNode.has("startDate")) {
                try {
                    startDate = LocalDate.parse(paramsNode.get("startDate").asText());
                } catch (Exception e) {
                    log.warn("Failed to parse startDate: {}", e.getMessage());
                }
            }
            
            if (paramsNode.has("endDate")) {
                try {
                    endDate = LocalDate.parse(paramsNode.get("endDate").asText());
                } catch (Exception e) {
                    log.warn("Failed to parse endDate: {}", e.getMessage());
                }
            }
            
            // 根据参数组合选择合适的查询方法
            if (isHoliday != null && startDate != null && endDate != null) {
                // 组合条件：是否为节假日 + 日期范围
                entityPage = holidayTableRepository.findByHolidayAndIdBetween(isHoliday, startDate, endDate, pageable);
            } else if (isHoliday != null) {
                // 单个条件：是否为节假日
                entityPage = holidayTableRepository.findByHoliday(isHoliday, pageable);
            } else if (startDate != null && endDate != null) {
                // 单个条件：日期范围
                entityPage = holidayTableRepository.findByIdBetween(startDate, endDate, pageable);
            } else {
                // 不满足上述条件，返回所有节假日
                entityPage = findAll(pageable);
            }
        }
        
        return entityPage.map(HolidayTable::toVo);
    }
    
    @Override
    public long count(JsonNode paramsNode) {
        // 简单实现，返回所有节假日数量
        return holidayTableRepository.count();
    }
    
    @Override
    public void updateByVo(HolidayTable model, HolidayTableVo vo) {
        if (model == null || vo == null) {
            return;
        }
        
        // 更新实体属性
        model.setHoliday(vo.isHoliday());
        save(model);
    }
    
    /**
     * 创建节假日
     * 
     * @param vo 节假日VO对象
     * @return 创建后的节假日VO对象
     */
    public HolidayTableVo createByVo(HolidayTableVo vo) {
        if (vo == null || vo.getId() == null) {
            throw new IllegalArgumentException("HolidayTableVo or ID cannot be null");
        }
        
        HolidayTable entity = new HolidayTable();
        entity.setId(vo.getId());
        entity.setHoliday(vo.isHoliday());
        
        HolidayTable savedEntity = save(entity);
        return savedEntity.toVo();
    }
}
