package de.votian.services.service;

import de.votian.services.entity.Address;
import de.votian.services.entity.Company;
import de.votian.services.entity.Headquarters;
import de.votian.services.repository.AddressRepository;
import de.votian.services.repository.CompanyRepository;
import de.votian.services.repository.HeadquartersRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

@Service
@Transactional(readOnly = true)
public class HeadquartersService {

    private final HeadquartersRepository headquartersRepository;
    private final CompanyRepository companyRepository;
    private final AddressRepository addressRepository;
    private final ParameterService parameterService;

    public HeadquartersService(HeadquartersRepository headquartersRepository,
                               CompanyRepository companyRepository,
                               AddressRepository addressRepository,
                               ParameterService parameterService) {
        this.headquartersRepository = headquartersRepository;
        this.companyRepository = companyRepository;
        this.addressRepository = addressRepository;
        this.parameterService = parameterService;
    }

    public Optional<Headquarters> findById(Long id) {
        return headquartersRepository.findById(Objects.requireNonNull(id));
    }

    public List<Headquarters> findAll() {
        return headquartersRepository.findAll();
    }

    public Optional<Company> getCompany(Long hqId) {
        return headquartersRepository.findById(Objects.requireNonNull(hqId))
                .flatMap(hq -> companyRepository.findById(Objects.requireNonNull(hq.getCompanyId())));
    }

    @Transactional
    public Headquarters updateHeadquarters(Long id,
                                           Headquarters hqUpdates,
                                           Company companyUpdates,
                                           Address addressUpdates,
                                           String bwvPhone,
                                           String gln,
                                           String duns) {
        Headquarters headquarters = headquartersRepository.findById(Objects.requireNonNull(id))
                .orElseThrow(() -> new RuntimeException("Headquarters not found: " + id));

        if (hqUpdates != null) {
            if (hqUpdates.getMnemonic() != null) {
                headquarters.setMnemonic(hqUpdates.getMnemonic());
            }
            if (hqUpdates.getName() != null) {
                headquarters.setName(hqUpdates.getName());
            }
            if (hqUpdates.getWorkmode() != null) {
                headquarters.setWorkmode(hqUpdates.getWorkmode());
            }
        }

        headquartersRepository.save(Objects.requireNonNull(headquarters));

        companyRepository.findById(Objects.requireNonNull(headquarters.getCompanyId())).ifPresent(company -> {
            if (companyUpdates != null) {
                if (companyUpdates.getComp() != null) {
                    company.setComp(companyUpdates.getComp());
                }
                if (companyUpdates.getComp2() != null) {
                    company.setComp2(companyUpdates.getComp2());
                }
                if (companyUpdates.getComp3() != null) {
                    company.setComp3(companyUpdates.getComp3());
                }
                if (companyUpdates.getComp4() != null) {
                    company.setComp4(companyUpdates.getComp4());
                }
                if (companyUpdates.getHsno() != null) {
                    company.setHsno(companyUpdates.getHsno());
                }
            }

            Long addressId = company.getAddressId();
            Address address = addressId != null
                    ? addressRepository.findById(addressId).orElseGet(Address::new)
                    : new Address();
            if (addressUpdates != null) {
                if (addressUpdates.getStreet() != null) {
                    address.setStreet(addressUpdates.getStreet());
                }
                if (addressUpdates.getZipcode() != null) {
                    address.setZipcode(addressUpdates.getZipcode());
                }
                if (addressUpdates.getCity() != null) {
                    address.setCity(addressUpdates.getCity());
                }
                if (addressUpdates.getCountry() != null) {
                    address.setCountry(addressUpdates.getCountry());
                } else if (address.getCountry() == null) {
                    address.setCountry("DE");
                }
            }
            Address savedAddress = addressRepository.save(Objects.requireNonNull(address));
            company.setAddressId(savedAddress.getId());
            companyRepository.save(company);
        });

        if (bwvPhone != null) {
            parameterService.setParameterValue("BWV_PHONE_NO", bwvPhone, id, 0L);
        }
        if (gln != null) {
            parameterService.setParameterValue("GLN_HQ_ALL", gln, 0L, 0L);
        }
        if (duns != null) {
            parameterService.setParameterValue("DUNS_HQ_ALL", duns, 0L, 0L);
        }

        return headquarters;
    }
}
