/*
 *******************************************************************************
 * 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.BadRequestException;
import org.eclipse.openk.contactbasedata.exceptions.NotFoundException;
import org.eclipse.openk.contactbasedata.exceptions.OperationDeniedException;
import org.eclipse.openk.contactbasedata.mapper.AddressMapper;
import org.eclipse.openk.contactbasedata.model.TblAddress;
import org.eclipse.openk.contactbasedata.model.TblContact;
import org.eclipse.openk.contactbasedata.repository.AddressRepository;
import org.eclipse.openk.contactbasedata.repository.AddressTypeRepository;
import org.eclipse.openk.contactbasedata.repository.ContactRepository;
import org.eclipse.openk.contactbasedata.viewmodel.AddressDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Log4j2
@Service
public class AddressService {
    @Autowired
    private AddressRepository addressRepository;

    @Autowired
    private AddressTypeRepository addressTypeRepository;

    @Autowired
    private ContactRepository contactRepository;

    @Autowired
    AddressMapper addressMapper;


    public List<AddressDto> getAddressesByContactUuid(UUID contactUuid) {
        List<TblAddress> tblAddressList = addressRepository
                .findByTblContactUuid(contactUuid);

        return tblAddressList.stream().map(addressMapper::toAddressDto).collect(Collectors.toList());
    }


    public AddressDto getAddress(UUID contactUuid, UUID addressUuid){
        TblAddress tblAddress = addressRepository.findByUuid(addressUuid)
                .orElseThrow( () -> new NotFoundException(Constants.ADDRESS_UUID_NOT_EXISTING));
        if(!tblAddress.getTblContact().getUuid().equals(contactUuid)) {
            throw new BadRequestException("invalid.uuid.path.object");
        }
        return addressMapper.toAddressDto(tblAddress);
    }

    @Transactional
    public AddressDto insertAddress(UUID contactUuid, AddressDto addressDto) {

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

        TblAddress addressToSave = addressMapper.toTblAddress(addressDto);
        addressToSave.setUuid(UUID.randomUUID());
        addressToSave.setTblContact(tblContact);

        if (addressDto.getIsMainAddress()!=null && addressDto.getIsMainAddress() && !checkUniqueMainAddressForContactForInsert(tblContact.getId())) {
            throw new OperationDeniedException(OperationType.INSERT, "main.address.already.existing");
        }

        setFromAddressDto(addressToSave, addressDto);

        TblAddress savedAddress = addressRepository.save(addressToSave);
        return addressMapper.toAddressDto(savedAddress);
    }

    @Transactional
    public AddressDto updateAddress(UUID contactUuid, AddressDto addressDto) {

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

        TblAddress address = addressRepository.findByUuid(addressDto.getUuid())
                .orElseThrow(() -> new NotFoundException(Constants.ADDRESS_UUID_NOT_EXISTING));

        TblAddress addressToSave = addressMapper.toTblAddress(addressDto);
        addressToSave.setTblContact(contact);
        addressToSave.setId(address.getId());

        if (addressDto.getIsMainAddress()!=null && addressDto.getIsMainAddress() && !checkUniqueMainAddressForContactForUpdate(contact.getId(), addressDto.getUuid())) {
            throw new OperationDeniedException(OperationType.UPDATE, "main.address.already.existing");
        }

        setFromAddressDto(addressToSave, addressDto);
        TblAddress savedAddress = addressRepository.save(addressToSave);
        return addressMapper.toAddressDto(savedAddress);
    }

    @Transactional
    public void deleteAddress(UUID contactUuid, UUID addressUuid) {
        TblContact tblContact = contactRepository.findByUuid(contactUuid)
                .orElseThrow(() -> new NotFoundException(Constants.CONTACT_UUID_NOT_EXISTING));
        TblAddress tblAddress = addressRepository.findByTblContactAndUuid(tblContact, addressUuid)
                .orElseThrow(() -> new NotFoundException(Constants.ADDRESS_UUID_NOT_EXISTING));

        addressRepository.delete(tblAddress);
    }

    private boolean checkUniqueMainAddressForContactForInsert(Long contactId){
        return addressRepository.countByContactIdAndIsMainAddress(contactId, true) == 0;
    }

    private boolean checkUniqueMainAddressForContactForUpdate( Long contactId, UUID addressUuid){
       Long result = addressRepository.countByContactIdAndMainAddressIsNotSame(contactId,true, addressUuid) ;
       return result==0;
    }

    private void setFromAddressDto( TblAddress destTblAddress, AddressDto sourceDto ) {

        if( sourceDto.getAddressTypeUuid() != null ) {
            destTblAddress.setRefAddressType( addressTypeRepository
                    .findByUuid(sourceDto.getAddressTypeUuid())
                    .orElseThrow(() -> new NotFoundException("address.type.uuid.not.existing")));
        }
        else {
            destTblAddress.setRefAddressType(null);
        }
    }

}
