package com.example.cezenPBX.DAO;

import com.example.cezenPBX.DTO.ReturnStatus;
import com.example.cezenPBX.entity.*;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import jakarta.persistence.TypedQuery;
import jakarta.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.UnexpectedRollbackException;

@Repository
public class BasicAsteriskOpsDAO implements CezenPbxOpsDAO {


    @Autowired
    private EntityManager entityManager;

    // find end point details by id
    private PsEndPoints findEndPontById(String id) {

        return this.entityManager.find(PsEndPoints.class, id);
    }

    // takes the required data from the service class and persists the entity to the database
    // returns true if operation was carried out without an exception
    @Override
    @Transactional
    public boolean addNewEndPoint(PsEndPoints psEndPoints) {

        // if there is an exception in the transaction
        try{
            this.entityManager.persist(psEndPoints);
        }catch (Exception e){
            return false;
        }
        return true;
    }

    // Save an extension
    @Override
    @Transactional
    public ReturnStatus saveAnExtension(ExtensionsTable extensionsTable) {

        int priorityNumber = getTheHighestPriorityNumberByEndpoint(extensionsTable.getExtension());

        // it's the first entry set priority to 1
        if(priorityNumber == 0) extensionsTable.setPriority(1);

        //save only if endpoint exists
        return persistOnlyIfEndpointExists(extensionsTable);
    }

    // the method persists
    @Override
    @Transactional
    public ReturnStatus setThePasswordForSipEndpoint(PsAuths psAuths) {

        //save only if endpoint exists
        return persistOnlyIfEndpointExists(psAuths);
    }

    @Override
    @Transactional
    public ReturnStatus setTheAorsForTheEndPoint(PsAors psAors) {

        //save only if endpoint exists
        return persistOnlyIfEndpointExists(psAors);
    }

    private ReturnStatus persistOnlyIfEndpointExists(PBXentiry pbXentiry){

        String endpoint = pbXentiry.getExtension();

        // check if the endpoint exists
        if(findEndPontById(endpoint) == null){
            return new ReturnStatus(false, "Create Endpoint for " + endpoint, " ");
        }
        // then persist
        this.entityManager.persist(pbXentiry);
        return new ReturnStatus(true, endpoint + " Persisted ", "");
    }


    // this gets the
    @Override
    public int getTheHighestPriorityNumberByEndpoint(String endpoint) {

        // fetches the highest priority
        String query = "SELECT MAX(e.priority) FROM ExtensionsTable AS e WHERE e.extension = :endpoint";

        //get the highest priority
        try{
            TypedQuery<Integer> queryResult = this.entityManager.createQuery(query, Integer.class);
            queryResult.setParameter("endpoint", endpoint);
            return queryResult.getSingleResult();

        }catch (Exception e){
            // that means endpoint doesnt exist yet
            return 0;
        }
    }

    // delete extension by endoint
    @Override
    @Transactional
    public boolean deleteAnExtensionPoint(String endpoint) {

        Query query = this.entityManager.createQuery("DELETE FROM ExtensionsTable e WHERE e.extension = :extension");

        query.setParameter("extension", endpoint);

        return query.executeUpdate() == 1;
    }

    @Override
    public ReturnStatus saveAnExtensionByCharacters(ExtensionsTable extensionsTable) {
        try {
            this.doPersist(extensionsTable); // calls @Transactional method
            return new ReturnStatus(true,
                    extensionsTable.getExtension() +" configured as "+ extensionsTable.getContext() +" added",
                    "");
        } catch (Exception e) {
            return new ReturnStatus(false,
                    extensionsTable.getExtension() +" configured as "+ extensionsTable.getContext() +" Already exists",
                    e.toString());
        }
    }

    @Transactional
    public void doPersist(ExtensionsTable extensionsTable) {
        entityManager.persist(extensionsTable);
    }
}
