/*
 *******************************************************************************
 * Copyright (c) 2019 Contributors to the Eclipse Foundation
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *******************************************************************************
 */
package org.eclipse.openk.contactbasedata.service;

import lombok.extern.log4j.Log4j2;
import org.eclipse.openk.contactbasedata.constants.Constants;
import org.eclipse.openk.contactbasedata.enums.OperationType;
import org.eclipse.openk.contactbasedata.exceptions.NotFoundException;
import org.eclipse.openk.contactbasedata.exceptions.OperationDeniedException;
import org.eclipse.openk.contactbasedata.mapper.AssignmentModulContactMapper;
import org.eclipse.openk.contactbasedata.model.TblAssignmentModulContact;
import org.eclipse.openk.contactbasedata.model.TblContact;
import org.eclipse.openk.contactbasedata.repository.AssignmentModulContactRepository;
import org.eclipse.openk.contactbasedata.repository.ContactRepository;
import org.eclipse.openk.contactbasedata.viewmodel.AssignmentModulContactDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Log4j2
@Service
public class AssignmentModulContactService {
    @Autowired
    private AssignmentModulContactRepository assignmentModulContactRepository;

    @Autowired
    private ContactRepository contactRepository;

    @Autowired
    AssignmentModulContactMapper assignmentModulContactMapper;

    public List<AssignmentModulContactDto> getAssignments(UUID contactUuid) {
        List<TblAssignmentModulContact> tblAssignmentsList = assignmentModulContactRepository
                .findByTblContactUuid(contactUuid);

        return tblAssignmentsList.stream().map(assignmentModulContactMapper::toAssignmentModulContactDto).collect(Collectors.toList());
    }

    public AssignmentModulContactDto getAssignment(UUID contactUuid, UUID assignmentUuid ) {

        TblAssignmentModulContact tblAssign = assignmentModulContactRepository.findByUuid(assignmentUuid)
                    .orElseThrow(() -> new NotFoundException(Constants.MODULE_ASSIGNMENT_UUID_NOT_EXISTING));

        if(!tblAssign.getTblContact().getUuid().equals(contactUuid)) {
            throw new NotFoundException(Constants.CONTACT_UUID_NOT_EXISTING);
        }
        return assignmentModulContactMapper.toAssignmentModulContactDto(tblAssign);
    }

    @Transactional
    public AssignmentModulContactDto insertAssignment(UUID contactUuid, AssignmentModulContactDto assignmentDto) {

        TblContact tblContact = contactRepository
                                .findByUuid(contactUuid)
                                .orElseThrow(() -> new NotFoundException(Constants.CONTACT_UUID_NOT_EXISTING));

        TblAssignmentModulContact assignmentToSave = assignmentModulContactMapper.toTblAssignmentModulContact(assignmentDto);
        assignmentToSave.setUuid(UUID.randomUUID());
        assignmentToSave.setTblContact(tblContact);
        assignmentToSave.setAssignmentDate(Date.from(Instant.now()));

        if ( !checkUniqueAssignmentForContactAndModuleForInsert(tblContact.getId(), assignmentDto.getModulName())) {
            throw new OperationDeniedException(OperationType.INSERT, "assignment.already.existing");
        }

        TblAssignmentModulContact savedAssignment = assignmentModulContactRepository.save(assignmentToSave);
        return assignmentModulContactMapper.toAssignmentModulContactDto(savedAssignment);
    }

    @Transactional
    public AssignmentModulContactDto updateAssignment(UUID contactUuid, AssignmentModulContactDto assignmentDto) {

        TblContact contact = contactRepository.findByUuid(contactUuid)
                .orElseThrow(() -> new NotFoundException(Constants.CONTACT_UUID_NOT_EXISTING));

        TblAssignmentModulContact tblAssignment = assignmentModulContactRepository.findByUuid(assignmentDto.getUuid())
                .orElseThrow(() -> new NotFoundException("assignment.uuid.not.existing"));

        TblAssignmentModulContact assignmentToSave = assignmentModulContactMapper.toTblAssignmentModulContact(assignmentDto);
        assignmentToSave.setTblContact(contact);
        assignmentToSave.setId(tblAssignment.getId());

        if ( !checkUniqueAssignmentForContactAndModuleForUpdate(contact.getId(), assignmentDto.getUuid(), assignmentDto.getModulName())) {
            throw new OperationDeniedException(OperationType.UPDATE, "assignment.already.existing");
        }

        TblAssignmentModulContact savedAssignment = assignmentModulContactRepository.save(assignmentToSave);
        return assignmentModulContactMapper.toAssignmentModulContactDto(savedAssignment);
    }


    @Transactional
    public void deleteAssignment(UUID contactUuid, UUID assignmentUuid) {
        TblContact tblContact = contactRepository.findByUuid(contactUuid)
                .orElseThrow(() -> new NotFoundException(Constants.CONTACT_UUID_NOT_EXISTING));
        TblAssignmentModulContact tblAssignment = assignmentModulContactRepository.findByTblContactAndUuid(tblContact, assignmentUuid)
                .orElseThrow(() -> new NotFoundException("assignment.uuid.not.existing"));

        assignmentModulContactRepository.delete(tblAssignment);
    }

    private boolean checkUniqueAssignmentForContactAndModuleForInsert(Long contactId, String modulName){
        return assignmentModulContactRepository.countByContactIdAndModuleName(contactId, modulName) == 0;
    }

    private boolean checkUniqueAssignmentForContactAndModuleForUpdate( Long contactId, UUID assignmentUuid, String modulName){
       Long result = assignmentModulContactRepository.countByContactIdAndUuidAndModulNameIsNotSame(contactId, assignmentUuid, modulName) ;
       return result==0;
    }




}
