package com.eactive.httpmockserver.client.service;

import com.eactive.httpmockserver.client.entity.ApiCollection;
import com.eactive.httpmockserver.client.entity.ApiRequestInfo;
import com.eactive.httpmockserver.client.repository.ApiCollectionRepository;
import com.eactive.httpmockserver.client.repository.ApiRequestRepository;
import com.eactive.httpmockserver.common.exception.NotFoundException;
import com.eactive.httpmockserver.user.entity.StaffUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thymeleaf.util.StringUtils;

import javax.transaction.Transactional;
import java.util.List;
import java.util.UUID;

@Service
@Transactional
public class ApiRequestMgmtService {

    private static final String API_COLLECTION_NOT_FOUND = "api collection[%s] not found";

    private static final String API_NOT_FOUND = "api collection[%s] not found";

    @Autowired
    ApiCollectionRepository apiCollectionRepository;

    @Autowired
    ApiRequestRepository apiRequestRepository;


    public List<ApiCollection> getMyApis(StaffUser user) {
        return apiCollectionRepository.findAllByOwner(user);
    }

    public void deleteApiCollection(String id) {
        ApiCollection collection = apiCollectionRepository.findById(id).orElseThrow(() -> new NotFoundException(String.format(API_COLLECTION_NOT_FOUND, id)));

        if (!collection.getApis().isEmpty()) {
            throw new RuntimeException("api collection[" + id + "] is not empty");
        }
        apiCollectionRepository.deleteById(id);
    }

    public void createNewApiCollection(ApiCollection collection) {
        collection.setId(UUID.randomUUID().toString());
        apiCollectionRepository.save(collection);
    }

    public void updateApiCollectionName(String id, ApiCollection updated) {
        ApiCollection collection = apiCollectionRepository.findById(id).orElseThrow(() -> new NotFoundException(String.format(API_COLLECTION_NOT_FOUND, id)));
        collection.setName(updated.getName());
        apiCollectionRepository.save(collection);
    }

    public String saveApiToCollection(String id, ApiRequestInfo api) {
        ApiCollection collection = apiCollectionRepository.findById(id).orElseThrow(() -> new NotFoundException(String.format(API_COLLECTION_NOT_FOUND, id)));

        if (StringUtils.isEmpty(api.getId())) {
            api.setId(UUID.randomUUID().toString());
            apiRequestRepository.save(api);
        } else {
            String apiId = api.getId();
            ApiRequestInfo existing = apiRequestRepository.findById(apiId).orElseThrow(() -> new NotFoundException(String.format(API_NOT_FOUND, apiId)));
            existing.setName(api.getName());
            existing.setMethod(api.getMethod());
            existing.setPath(api.getPath());
            existing.setHeaders(api.getHeaders());
            existing.setQueryParams(api.getQueryParams());
            existing.setVariables(api.getVariables());
            existing.setServer(api.getServer());
            existing.setRequestBody(api.getRequestBody());
            apiRequestRepository.save(existing);
            api = existing;
        }


        if (!collection.getApis().contains(api)) {
            collection.getApis().add(api);
            apiCollectionRepository.save(collection);
        }

        return api.getId();
    }

    public void removeApiFromCollection(String id, String apiId) {
        ApiCollection collection = apiCollectionRepository.findById(id).orElseThrow(() -> new NotFoundException(String.format(API_COLLECTION_NOT_FOUND, id)));
        ApiRequestInfo api = apiRequestRepository.findById(apiId).orElseThrow(() -> new NotFoundException(String.format(API_NOT_FOUND, apiId)));

        collection.getApis().remove(api);
        apiCollectionRepository.save(collection);
        apiRequestRepository.deleteById(apiId);

    }
}
