package org.egl_cepgl.pm.service;

import lombok.extern.slf4j.Slf4j;
import org.egl_cepgl.pm.dto.EnterpriseDto;
import org.egl_cepgl.pm.dto.FileDto;
import org.egl_cepgl.pm.exception.EntityNotFoundException;
import org.egl_cepgl.pm.model.Enterprise;
import org.egl_cepgl.pm.model.EnterpriseQualification;
import org.egl_cepgl.pm.model.Procurement;
import org.egl_cepgl.pm.repository.EnterpriseRepository;
import org.egl_cepgl.pm.repository.ProcurementRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class EnterpriseService
{
    private EnterpriseRepository enterpriseRepository;
    private ProcurementRepository procurementRepository;

    @Autowired
    public EnterpriseService(EnterpriseRepository enterpriseRepository, ProcurementRepository procurementRepository) {
        this.enterpriseRepository = enterpriseRepository;
        this.procurementRepository= procurementRepository;
    }

    public Enterprise save(Enterprise obj, Long procurement_id)
    {
        Enterprise enterprise= this.enterpriseRepository.save(obj);
        if(procurement_id != null){
            Procurement procurement_s= this.procurementRepository.findById(procurement_id).get();
            procurement_s.getEnterprises().add(enterprise);
            this.procurementRepository.save(procurement_s);
        }
        return enterpriseRepository.save(enterprise);
    }

    public Page<Enterprise> findAll(String search, int page, int size, Boolean dateRange, Date bdate, Date edate)
    {
        Pageable paging = PageRequest.of(page, size);
        Page<Enterprise> objs;
        if (search == null && bdate == null) {
            objs = this.enterpriseRepository.findAll(paging);
        } else {
            SimpleDateFormat fd= new SimpleDateFormat("YYYY-MM-dd");
            if(dateRange == null)
                objs = this.enterpriseRepository.findAllByFilters(search, paging);
            else{
                if(edate == null)
                    objs = this.enterpriseRepository.findAllByFilters2(search, paging, fd.format(bdate));
                else
                    objs = this.enterpriseRepository.findAllByFilters3(search, paging, fd.format(bdate), fd.format(edate));
            }
        }
        return objs;
    }

    public List<Map<String, Object>> findAllEnterpriseNames(Long procurement_id)
    {
        if(procurement_id != 0){
            return this.enterpriseRepository.findAllEnterpriseNamesByProcurement(procurement_id);
        }
        return this.enterpriseRepository.findAllEnterpriseNames();
    }

    public Optional<EnterpriseDto> findEnterpriseById(Long id)
    {
        return Optional.ofNullable(EnterpriseDto.fromEntity(this.enterpriseRepository.findById(id).orElseThrow(() -> {
            throw new EntityNotFoundException("L'Enterprise avec cet ID est introuvableé");
        })));
    }

    public Optional<EnterpriseDto> findEnterpriseByEmail(String email)
    {
        return Optional.ofNullable(EnterpriseDto.fromEntity(this.enterpriseRepository.findByEmail(email).orElseThrow(() -> {
            throw new EntityNotFoundException("L'Enterprise avec cet email est introuvableé");
        })));
    }

    public List<FileDto> findAllFilesByEnterpriseId(Long id)
    {
        List<FileDto> files = new ArrayList<>();
        Optional<Enterprise> enterprise= enterpriseRepository.findById(id);
        if(enterprise.isPresent()){
            files= enterprise.get().getFiles().stream().map(FileDto::fromEntity).collect(Collectors.toList());
        }
        return files;
    }

    public Enterprise update(Enterprise obj)
    {
        return this.enterpriseRepository.save(obj);
    }

    public void delete(Long id)
    {
        if(id == null){
            log.error("ID est null");
            return;
        }
        enterpriseRepository.deleteById(id);
    }

    public Boolean existsByCode(String email)
    {
        if(enterpriseRepository.existsByEmail(email)){
            return true;
        }
        return false;
    }

    public Enterprise changeStatus(Enterprise obj)
    {
        return enterpriseRepository.changeStatus(obj.getId(), obj.getStatus());
    }
}
