package com.bytesw.bytebot.service;

import com.bytesw.bytebot.http.FileValidationResponse;
import com.bytesw.bytebot.http.FileValidationResult;
import com.bytesw.bytebot.http.enums.ValidationStatusEnum;
import com.bytesw.bytebot.model.BdcControl;
import com.bytesw.bytebot.model.QuestionFile;
import com.bytesw.bytebot.model.enums.FrequentQuestionStatusEnum;
import com.bytesw.bytebot.model.enums.StatusBcdEnum;
import com.bytesw.bytebot.repository.BdcControlRepository;
import com.bytesw.bytebot.repository.QuestionFileRepository;
import com.bytesw.xdf.exception.NotFoundException;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.Optional;

@Service
@Transactional
@Log4j2
public class OrquestadorService {

    @Autowired
    private FileManagementService fileManagementService;

    @Autowired
    private BucketService bucketService;

    @Autowired
    private BdcControlRepository bdcControlRepository;

    @Autowired
    private QuestionFileRepository questionFileRepository;

    @Autowired
    private  KnowledgeService knowledgeService;

    @Autowired
    private BusinessParameterService businessParameterService;

    @Value("${application.bucket.deployment}")
    private String parameter;

    public FileValidationResponse executeGenerateBCD(String uuid, MultipartFile file) {
        BdcControl model = new BdcControl();
        FileValidationResponse response = new FileValidationResponse();
        boolean step = false;
        try{
            //Modo de despliegue
            String modeDeployment = businessParameterService.getBusinessParameterForKey(parameter);
            if (modeDeployment == null) {
                response.setMessage("NOT.FOUND.BUSINESS.PARAMETER");
                throw new NotFoundException();
            }

            //Valida y guarda en base de datos
            response = fileManagementService.saveFile(uuid, file);
            if(response.getFileValidationResult().getStatus().getName() != ValidationStatusEnum.OK.getName()) {
                response.setStatus(FrequentQuestionStatusEnum.ERROR.getName());
                return response;
            }

            model.setUuid(response.getUuid());
            model.setFileId(response.getId());
            model.setFileName(response.getFileName());
            model.setDate(response.getUploadDate());
            model.setStatus(StatusBcdEnum.CARGADO.getName());
            model = bdcControlRepository.save(model);

            if (modeDeployment.equalsIgnoreCase("onCloud")) {
                //Carga archivo a bucket
                step = bucketService.generate(file.getBytes(), response);
                if (!step) {
                    response.setMessage("NOT.FOUND.BUCKET");
                    throw new NotFoundException();
                }
                step = false;
                model.setStatus(StatusBcdEnum.INDEXANDO.getName());
                model = bdcControlRepository.save(model);
            }

            //Generacion del modelo
            step = knowledgeService.generate(response);
            if (!step) {
                response.setMessage("NOT.FOUND.KNOWLEDGE");
                throw new NotFoundException();
            }
            response.setStatus(FrequentQuestionStatusEnum.CORRECTO.getName());
            model.setStatus(StatusBcdEnum.INDEXADO.getName());
            model = bdcControlRepository.save(model);
        }catch (Exception e) {
            if (response.getMessage() == null) {
                response.setMessage("ERROR.UPLOAD");
            }
            response.setStatus(FrequentQuestionStatusEnum.ERROR.getName());
        }
        return response;
    }

    public FileValidationResponse retry(String uuid) {

        Optional<BdcControl> modelBdc = bdcControlRepository.findByUuid(uuid);
        if (!modelBdc.isPresent()) {
            throw new NotFoundException("NOT.FOUND.DATA.CONTROL");
        }

        boolean step = false;
        BdcControl model = modelBdc.get();
        FileValidationResponse response = modelToFileValidation(model);
        try {
            String modeDeployment = businessParameterService.getBusinessParameterForKey(parameter);
            if (modeDeployment == null) {
                response.setMessage("NOT.FOUND.BUSINESS.PARAMETER");
                throw new NotFoundException();
            }

            if (model.getStatus().equals(StatusBcdEnum.CARGADO.getName())) {
                Optional<QuestionFile> questionFile = questionFileRepository.findByUuid(uuid);
                if (!questionFile.isPresent()) {
                    response.setMessage("NOT.FOUND.DATA");
                    throw new NotFoundException();
                }
                if (modeDeployment.equalsIgnoreCase("onCloud")) {
                    step = bucketService.generate(questionFile.get().getData(), response);
                    if (!step) {
                        response.setMessage("NOT.FOUND.BUCKET");
                        throw new NotFoundException();
                    }
                }
                model.setStatus(StatusBcdEnum.INDEXANDO.getName());
                model = bdcControlRepository.save(model);
                step = false;
            }
            if (model.getStatus().equals(StatusBcdEnum.INDEXANDO.getName())) {
                step = knowledgeService.generate(response);
                if (!step) {
                    response.setMessage("NOT.FOUND.KNOWLEDGE");
                    throw new NotFoundException();
                }
            }
            model.setStatus(StatusBcdEnum.INDEXADO.getName());
            model = bdcControlRepository.save(model);
            response.setStatus(FrequentQuestionStatusEnum.CORRECTO.getName());
        } catch (Exception e) {
            if (response.getMessage() == null) {
                response.setMessage("ERROR.UPLOAD");
            }
            response.setStatus(FrequentQuestionStatusEnum.ERROR.getName());
        }
        return response;
    }

    public void deleteBcd(String uuid) {
        Optional<BdcControl> bdcControl = bdcControlRepository.findByUuid(uuid);
        if (!bdcControl.isPresent()) {
            throw new NotFoundException();
        }
        BdcControl model = bdcControl.get();
        if (model.getStatus().equals(StatusBcdEnum.INDEXADO.getName())) {
            boolean step = knowledgeService.delete(uuid);
            if (!step) {
                throw new NotFoundException();
            }
            model.setStatus(StatusBcdEnum.INDEXANDO.getName());
            model = bdcControlRepository.save(model);
        }
        if (model.getStatus().equals(StatusBcdEnum.INDEXANDO.getName())) {
            bucketService.delete(uuid);
            model.setStatus(StatusBcdEnum.CARGADO.getName());
            model = bdcControlRepository.save(model);
        }
        Optional<QuestionFile> questionFile = questionFileRepository.findByUuid(uuid);
        if (questionFile.isPresent()) {
            questionFileRepository.deleteById(bdcControl.get().getFileId());
        }
        bdcControlRepository.delete(model);
    }

    private FileValidationResponse modelToFileValidation(BdcControl model){
        FileValidationResponse response = new FileValidationResponse();
        response.setId(model.getId());
        response.setStatus(model.getStatus());
        response.setUuid(model.getUuid());
        response.setFileName(model.getFileName());
        response.setUploadDate(model.getDate());
        FileValidationResult result = new FileValidationResult();
        result.setStatus(ValidationStatusEnum.OK);
        response.setFileValidationResult(result);
        return response;
    }

}
