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

import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import jakarta.transaction.Transactional;

import org.springframework.stereotype.Service;

import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.download.DownloadStatusEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DownloadStatusRepository;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.FileRepository;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.ReportTemplateRepository;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DownloadFileType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.download.DownloadStatusValue;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class DownloadStatusPersistenceService {

    private final DownloadStatusRepository downloadStatusRepository;
    private final FileRepository fileRepository;
    private final ReportTemplateRepository reportTemplateRepository;


    // use this to create a status for export dossier template.
    public void createStatus(String userId, String storageId, String filename, String mimeType) {

        this.createStatus(userId, storageId, null, filename, mimeType, null, null, null, null);
    }


    public void createStatus(String userId,
                             String storageId,
                             DossierEntity dossier,
                             String filename,
                             String mimeType,
                             List<String> fileIds,
                             Set<DownloadFileType> downloadFileTypes,
                             List<String> reportTemplateIds,
                             String redactionPreviewColor) {

        DownloadStatusEntity downloadStatus = new DownloadStatusEntity();
        downloadStatus.setUserId(userId);
        downloadStatus.setStorageId(storageId);
        downloadStatus.setFilename(filename);
        downloadStatus.setMimeType(mimeType);
        downloadStatus.setDossier(dossier);
        downloadStatus.setCreationDate(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
        downloadStatus.setFiles(fileIds != null ? fileRepository.findAllById(fileIds) : new ArrayList<>());
        downloadStatus.setDownloadFileTypes(downloadFileTypes != null ? new HashSet<>(downloadFileTypes) : new HashSet<>());
        downloadStatus.setReports(reportTemplateIds != null ? reportTemplateRepository.findAllById(reportTemplateIds) : new ArrayList<>());
        downloadStatus.setRedactionPreviewColor(redactionPreviewColor);

        downloadStatusRepository.save(downloadStatus);
    }


    @Transactional
    public void updateStatus(String storageId, DownloadStatusValue status) {

        downloadStatusRepository.updateStatus(storageId, status);

    }


    @Transactional
    public void updateStatus(DownloadStatusEntity entity, DownloadStatusValue statusValue, long fileSize) {

        entity.setStatus(statusValue);
        entity.setFileSize(fileSize);
        downloadStatusRepository.save(entity);
    }


    @Transactional
    public void updateLastDownload(String storageId) {

        downloadStatusRepository.updateLastDownload(storageId, OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
    }


    @Transactional
    public void deleteStatus(String storageId) {

        downloadStatusRepository.deleteById(storageId);
    }


    public DownloadStatusEntity getStatus(String storageId) {

        return downloadStatusRepository.findById(storageId).orElseThrow(() -> new NotFoundException(String.format("DownloadStatus not found for storageId: %s", storageId)));

    }


    public void updateStatusEntity(DownloadStatusEntity downloadStatusEntity) {

        downloadStatusRepository.save(downloadStatusEntity);
    }


    public List<DownloadStatusEntity> getStatusesByUser(String userId) {

        return downloadStatusRepository.findAllByUserId(userId);

    }


    public List<DownloadStatusEntity> getStatus() {

        return downloadStatusRepository.findAll();
    }

}
