package com.cos.repository;

import com.cos.entity.CertificateOfSponsorship;
import com.cos.service.EntityManagerProducer;

import javax.enterprise.context.ApplicationScoped;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.TypedQuery;
import java.util.List;
import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Repository / DAO for CertificateOfSponsorship entity.
 * Uses static EntityManagerFactory for plain Tomcat compatibility.
 * Each method manages its own EntityManager lifecycle.
 */
@ApplicationScoped
public class CosRepository {

    private static final Logger LOGGER = Logger.getLogger(CosRepository.class.getName());

    /**
     * Persist or merge a CoS record.
     */
    public CertificateOfSponsorship save(CertificateOfSponsorship cos) {
        EntityManager em = EntityManagerProducer.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            CertificateOfSponsorship result;
            if (cos.getId() == null) {
                em.persist(cos);
                result = cos;
            } else {
                result = em.merge(cos);
            }
            tx.commit();
            LOGGER.info("Saved CoS: " + result.getCertificateNumber());
            return result;
        } catch (Exception e) {
            if (tx.isActive()) tx.rollback();
            LOGGER.log(Level.SEVERE, "Error saving CoS", e);
            throw e;
        } finally {
            em.close();
        }
    }

    /**
     * Delete a CoS record by ID.
     */
    public void delete(Long id) {
        EntityManager em = EntityManagerProducer.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            CertificateOfSponsorship cos = em.find(CertificateOfSponsorship.class, id);
            if (cos != null) {
                em.remove(cos);
                LOGGER.info("Deleted CoS with ID: " + id);
            }
            tx.commit();
        } catch (Exception e) {
            if (tx.isActive()) tx.rollback();
            LOGGER.log(Level.SEVERE, "Error deleting CoS with ID: " + id, e);
            throw e;
        } finally {
            em.close();
        }
    }

    /**
     * Find a CoS record by primary key.
     */
    public Optional<CertificateOfSponsorship> findById(Long id) {
        EntityManager em = EntityManagerProducer.createEntityManager();
        try {
            CertificateOfSponsorship cos = em.find(CertificateOfSponsorship.class, id);
            return Optional.ofNullable(cos);
        } finally {
            em.close();
        }
    }

    /**
     * Find a CoS record by certificate number.
     */
    public Optional<CertificateOfSponsorship> findByCertificateNumber(String certNumber) {
        EntityManager em = EntityManagerProducer.createEntityManager();
        try {
            TypedQuery<CertificateOfSponsorship> query = em.createNamedQuery(
                    "CertificateOfSponsorship.findByCertNumber", CertificateOfSponsorship.class);
            query.setParameter("certNumber", certNumber);
            List<CertificateOfSponsorship> results = query.getResultList();
            return results.isEmpty() ? Optional.empty() : Optional.of(results.get(0));
        } finally {
            em.close();
        }
    }

    /**
     * Retrieve all CoS records ordered by creation date descending.
     */
    public List<CertificateOfSponsorship> findAll() {
        EntityManager em = EntityManagerProducer.createEntityManager();
        try {
            TypedQuery<CertificateOfSponsorship> query = em.createNamedQuery(
                    "CertificateOfSponsorship.findAll", CertificateOfSponsorship.class);
            return query.getResultList();
        } finally {
            em.close();
        }
    }

    /**
     * Find CoS records by sponsor licence number.
     */
    public List<CertificateOfSponsorship> findBySponsorLicence(String licenceNumber) {
        EntityManager em = EntityManagerProducer.createEntityManager();
        try {
            TypedQuery<CertificateOfSponsorship> query = em.createNamedQuery(
                    "CertificateOfSponsorship.findBySponsorLicence", CertificateOfSponsorship.class);
            query.setParameter("licenceNumber", licenceNumber);
            return query.getResultList();
        } finally {
            em.close();
        }
    }

    /**
     * Count total number of CoS records.
     */
    public long count() {
        EntityManager em = EntityManagerProducer.createEntityManager();
        try {
            return em.createQuery("SELECT COUNT(c) FROM CertificateOfSponsorship c", Long.class)
                     .getSingleResult();
        } finally {
            em.close();
        }
    }
}