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

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
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.SpringApp;
import com.ecep.contract.constant.ServiceConstant;
import com.ecep.contract.ds.customer.service.CompanyCustomerEvaluationFormFileService;
import com.ecep.contract.ds.other.service.EmployeeService;
import com.ecep.contract.ds.project.repository.ProjectQuotationRepository;
import com.ecep.contract.model.Employee;
import com.ecep.contract.ds.project.model.Project;
import com.ecep.contract.ds.project.model.ProjectQuotation;
import com.ecep.contract.service.ServiceException;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.util.SpecificationUtils;
import com.ecep.contract.vo.ProjectQuotationVo;
import com.fasterxml.jackson.databind.JsonNode;

@Lazy
@Service
@CacheConfig(cacheNames = "project-quotation")
public class ProjectQuotationService implements IEntityService<ProjectQuotation>, QueryService<ProjectQuotationVo>,
        VoableService<ProjectQuotation, ProjectQuotationVo> {
    private static final Logger logger = LoggerFactory.getLogger(ProjectQuotationService.class);

    @Lazy
    @Autowired
    private ProjectQuotationRepository repository;

    @Override
    public ProjectQuotation getById(Integer id) {
        return repository.findById(id).orElse(null);
    }

    @Cacheable(key = "#p0")
    public ProjectQuotationVo findById(Integer id) {
        ProjectQuotation entity = getById(id);
        if (entity != null) {
            return entity.toVo();
        }
        return null;
    }

    // 实现QueryService接口的findAll方法
    @Override
    public Page<ProjectQuotationVo> findAll(JsonNode paramsNode, Pageable pageable) {
        Specification<ProjectQuotation> spec = null;
        if (paramsNode.has(ServiceConstant.KEY_SEARCH_TEXT)) {
            spec = getSpecification(paramsNode.get(ServiceConstant.KEY_SEARCH_TEXT).asText());
        }
        // field
        spec = SpecificationUtils.andParam(spec, paramsNode, "project", "applicant", "authorizer");
        return findAll(spec, pageable).map(ProjectQuotation::toVo);
    }

    // 实现IEntityService接口的findAll方法
    @Override
    public Page<ProjectQuotation> findAll(Specification<ProjectQuotation> spec, Pageable pageable) {
        return repository.findAll(spec, pageable);
    }

    public List<ProjectQuotation> findAllByProject(Project project) {
        return repository.findAllByProject(project);
    }

    public ProjectQuotation save(ProjectQuotation approval) {
        return repository.save(approval);
    }

    @Override
    public Specification<ProjectQuotation> getSpecification(String searchText) {
        return null;
    }

    public void delete(ProjectQuotation approval) {
        repository.delete(approval);
    }

    public ProjectQuotation newInstanceByProject(Project project) {
        ProjectQuotation approval = new ProjectQuotation();
        approval.setProject(project);
        approval.setApplyTime(LocalDateTime.now());
        approval.setLevel(1);
        approval.setEvaluationFile(null);
        return approval;
    }

    public List<ProjectQuotation> findAll(Specification<ProjectQuotation> spec, Sort sort) {
        return repository.findAll(spec, sort);
    }

    @Override
    public void updateByVo(ProjectQuotation entity, ProjectQuotationVo vo) {
        if (entity == null) {
            throw new ServiceException("ProjectQuotation is null");
        }
        if (vo == null) {
            throw new ServiceException("ProjectQuotationVo is null");
        }

        entity.setLevel(vo.getLevel());
        entity.setStandardPayWay(vo.isStandardPayWay());
        entity.setNoStandardPayWayText(vo.getNoStandardPayWayText());
        entity.setAmount(vo.getAmount());
        entity.setApplyTime(vo.getApplyTime());
        entity.setAuthorizationTime(vo.getAuthorizationTime());
        entity.setDescription(vo.getDescription());

        // 处理关联实体
        if (vo.getProject() != null) {
            if (entity.getProject() == null || !entity.getProject().getId().equals(vo.getProject())) {
                ProjectService projectService = SpringApp.getBean(ProjectService.class);
                entity.setProject(projectService.getById(vo.getProject()));
            }
        } else {
            entity.setProject(null);
        }

        EmployeeService employeeService = SpringApp.getBean(EmployeeService.class);
        if (vo.getApplicantId() != null) {
            if (entity.getApplicant() == null || !entity.getApplicant().getId().equals(vo.getApplicantId())) {
                Employee applicant = employeeService.getById(vo.getApplicantId());
                entity.setApplicant(applicant);
            }
        } else {
            entity.setApplicant(null);
        }

        if (vo.getAuthorizerId() != null) {
            if (entity.getAuthorizer() == null || !entity.getAuthorizer().getId().equals(vo.getAuthorizerId())) {
                Employee authorizer = employeeService.getById(vo.getAuthorizerId());
                entity.setAuthorizer(authorizer);
            }
        } else {
            entity.setAuthorizer(null);
        }
        if (vo.getEvaluationFileId() != null) {
            if (entity.getEvaluationFile() == null
                    || !entity.getEvaluationFile().getId().equals(vo.getEvaluationFileId())) {
                CompanyCustomerEvaluationFormFileService evaluationFileService = SpringApp
                        .getBean(CompanyCustomerEvaluationFormFileService.class);
                entity.setEvaluationFile(evaluationFileService.getById(vo.getEvaluationFileId()));
            }
        } else {
            entity.setEvaluationFile(null);
        }
    }
}
