package com.iqser.red.service.persistence.management.v1.processor.service;

import java.nio.charset.StandardCharsets;

import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import com.iqser.red.service.persistence.management.v1.processor.client.pdftronredactionservice.PDFTronClient;
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.DigitalSignatureEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.DigitalSignatureKmsEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DigitalSignatureKmsRepository;
import com.iqser.red.service.persistence.service.v1.api.shared.model.DigitalSignatureKms;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.DigitalSignatureType;
import com.knecon.fforesight.tenantcommons.EncryptionDecryptionService;

import feign.FeignException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@RequiredArgsConstructor
public class DigitalSignatureKmsService {

    private final EncryptionDecryptionService encryptionDecryptionService;
    private final DigitalSignatureKmsRepository digitalSignatureKmsRepository;
    private final DigitalSignatureTypeService digitalSignatureTypeService;
    private final PDFTronClient pdfTronRedactionClient;


    public DigitalSignatureKmsEntity saveDigitalSignature(DigitalSignatureKms digitalSignatureKms) {

        log.info("Validate digital KMS signature before saving");
        try {
            pdfTronRedactionClient.testDigitalSignatureKms(digitalSignatureKms);
        } catch (FeignException e) {
            if (e.status() == HttpStatus.BAD_REQUEST.value()) {
                throw new BadRequestException(e.getMessage(), e);
            }
            throw new BadRequestException("Could not validate digital KMS signature", e);
        }
        log.info("Digital KMS signature is valid");
        DigitalSignatureKmsEntity digitalSignature = convert(digitalSignatureKms);

        encrypt(digitalSignature);
        var saved = digitalSignatureKmsRepository.save(digitalSignature);

        DigitalSignatureKmsEntity result = new DigitalSignatureKmsEntity();
        BeanUtils.copyProperties(saved, result);
        digitalSignatureTypeService.setActiveDigitalSignatureType(DigitalSignatureType.KMS);
        decrypt(result);
        return result;
    }


    private void encrypt(DigitalSignatureKmsEntity digitalSignature) {

        digitalSignature.setCertificate(encryptionDecryptionService.encrypt(digitalSignature.getCertificate()));
        digitalSignature.setKmsKeyId(encryptionDecryptionService.encrypt(digitalSignature.getKmsKeyId()));
        digitalSignature.setKmsAccessKey(encryptionDecryptionService.encrypt(digitalSignature.getKmsAccessKey()));
        digitalSignature.setKmsSecretKey(encryptionDecryptionService.encrypt(digitalSignature.getKmsSecretKey()));
    }


    private void decrypt(DigitalSignatureKmsEntity digitalSignature) {

        digitalSignature.setCertificate(encryptionDecryptionService.decrypt(digitalSignature.getCertificate()));
        digitalSignature.setKmsKeyId(encryptionDecryptionService.decrypt(digitalSignature.getKmsKeyId()));
        digitalSignature.setKmsAccessKey(encryptionDecryptionService.decrypt(digitalSignature.getKmsAccessKey()));
        digitalSignature.setKmsSecretKey(encryptionDecryptionService.decrypt(digitalSignature.getKmsSecretKey()));
    }


    public DigitalSignatureKmsEntity getDigitalSignature() {

        return digitalSignatureKmsRepository.findById(DigitalSignatureKmsEntity.ID).map(digitalSignature -> {

            DigitalSignatureKmsEntity result = new DigitalSignatureKmsEntity();
            BeanUtils.copyProperties(digitalSignature, result);
            decrypt(result);
            return result;
        }).orElseThrow(() -> new NotFoundException("Digital KMS Signature Not found"));
    }


    public void deleteDigitalSignature() {

        digitalSignatureKmsRepository.deleteById(DigitalSignatureEntity.ID);
        digitalSignatureTypeService.deleteDigitalSignatureType();
    }

    public DigitalSignatureKms convert(DigitalSignatureKmsEntity digitalSignatureKmsEntity) {

        return DigitalSignatureKms.builder()
                .certificate(new String(digitalSignatureKmsEntity.getCertificate()))
                .kmsAccessKey(digitalSignatureKmsEntity.getKmsAccessKey())
                .kmsKeyId(digitalSignatureKmsEntity.getKmsKeyId())
                .kmsRegion(digitalSignatureKmsEntity.getKmsRegion())
                .kmsSecretKey(digitalSignatureKmsEntity.getKmsSecretKey())
                .kmsServiceEndpoint(digitalSignatureKmsEntity.getKmsServiceEndpoint())
                .certificateName(digitalSignatureKmsEntity.getCertificateName())
                .build();
    }

    private DigitalSignatureKmsEntity convert(DigitalSignatureKms digitalSignatureKms) {

        return DigitalSignatureKmsEntity.builder()
                .certificate(digitalSignatureKms.getCertificate().getBytes(StandardCharsets.UTF_8))
                .kmsAccessKey(digitalSignatureKms.getKmsAccessKey())
                .kmsKeyId(digitalSignatureKms.getKmsKeyId())
                .kmsRegion(digitalSignatureKms.getKmsRegion())
                .kmsSecretKey(digitalSignatureKms.getKmsSecretKey())
                .kmsServiceEndpoint(digitalSignatureKms.getKmsServiceEndpoint())
                .certificateName(digitalSignatureKms.getCertificateName())
                .build();
    }



}
