<?php

require_once __DIR__ . '/../config/Database.php';

class CandidatoModel {

    private $conn;

    public function __construct() {
        $this->conn = Database::getInstance();
    }

    /**
     * Registra la información de un candidato y su fecha de salida
     *
     * @param int $id_candidato ID del candidato
     * @param int $id_pais ID del país
     * @param int|null $id_estado ID del estado
     * @param int|null $id_municipio ID del municipio
     * @param int|null $id_colonia ID de la colonia
     * @param int $id_nivel ID del nivel
     * @param int $id_giro ID del giro
     * @param string $nombre_empresa_institucion Nombre de la empresa o institución
     * @param int $motivo_examen Motivo del examen
     * @param string|null $motivo_op Motivo personalizado (opcional)
     * @param int $calificacion_servicio Calificación del servicio
     * @param int $consentimiento_pub Consentimiento de publicación
     * @param string $fecha_salida Fecha de salida
     * @return array Retorna un array asociativo con las claves "estado" y "mensaje"
     */
    public function registrarInfoCandidatos(
        $id_candidato,
        $id_pais,
        $id_estado,
        $id_municipio,
        $id_colonia,
        $id_nivel,
        $id_giro,
        $nombre_empresa_institucion,
        $motivo_examen,
        $motivo_op,
        $calificacion_servicio,
        $consentimiento_pub,
        $fecha_salida
    ) {
        try {
            $id_pais = (int)$id_pais;
            // Si el país no es México (ID 1), se asignan valores nulos a los campos de ubicación
            if ($id_pais !== 1) {
                $id_estado = null;
                $id_municipio = null;
                $id_colonia = null;
            } else {
                $id_estado = (int)$id_estado;
                $id_municipio = (int)$id_municipio;
                $id_colonia = (int)$id_colonia;
            }

            // Validar motivo_op: si está vacío o contiene solo espacios, asignar NULL
            if (empty($motivo_op) || trim($motivo_op) === '') {
                $motivo_op = null;
            }

            $sql = "INSERT INTO info_candidatos (
            id_candidato, id_pais, id_estado, id_municipio, id_colonia,
            id_nivel, id_giro, nombre_empresa_institucion, id_motivo_examen,
            calificacion_servicio, consentimiento_pub,  motivo_op
        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

            $stmt = $this->conn->prepare($sql);
            if ($stmt === false) {
                return [
                    "estado" => "error",
                    "mensaje" => "Error en la preparación de la consulta: " . $this->conn->error
                ];
            }

            $stmt->bind_param(
                "iiiiiiisiiis",
                $id_candidato,
                $id_pais,
                $id_estado,
                $id_municipio,
                $id_colonia,
                $id_nivel,
                $id_giro,
                $nombre_empresa_institucion,
                $motivo_examen,
                $calificacion_servicio,
                $consentimiento_pub,
                $motivo_op
            );

            if (!$stmt->execute()) {
                return [
                    "estado" => "error",
                    "mensaje" => "Error al insertar datos del candidato: " . $stmt->error
                ];
            }

            $stmt->close();

            // Registrar fecha de salida
            $resultadoFecha = $this->registrarFechaSalida($id_candidato, $fecha_salida);
            if (isset($resultadoFecha["estado"]) && $resultadoFecha["estado"] === "error") {
                return $resultadoFecha; // Propagar el error desde registrarFechaSalida
            }

            // Retornar éxito
            return [
                "estado" => "exitoso",
                "mensaje" => $id_candidato
            ];

        } catch (Exception $e) {
            return [
                "estado" => "error",
                "mensaje" => "Error en el registro: " . $e->getMessage()
            ];
        }
    }

    /**
     * Registra la fecha de salida de un candidato
     *
     * @param int $id_candidato ID del candidato
     * @param string $fecha_salida Fecha de salida
     * @return array Retorna un array asociativo con las claves "estado" y "mensaje"
     */
    private function registrarFechaSalida($id_candidato, $fecha_salida) {
        try {
            // Si no hay fecha de salida, retornar éxito sin hacer nada
            if (empty($fecha_salida)) {
                return [
                    "estado" => "exitoso",
                    "mensaje" => "No se registró fecha de salida"
                ];
            }

            // Consulta update
            $sql = "UPDATE candidato SET fecha_salida = ? WHERE id_candidato = ?";
            $stmt = $this->conn->prepare($sql);

            if ($stmt === false) {
                return [
                    "estado" => "error",
                    "mensaje" => "Error en la preparación de la consulta de fecha: " . $this->conn->error
                ];
            }

            $stmt->bind_param("si",$fecha_salida,$id_candidato);

            if (!$stmt->execute()) {
                return [
                    "estado" => "error",
                    "mensaje" => "Error al registrar fecha de salida: " . $stmt->error
                ];
            }

            $stmt->close();

            return [
                "estado" => "exitoso",
                "mensaje" => "Fecha de salida registrada correctamente"
            ];

        } catch (Exception $e) {
            return [
                "estado" => "error",
                "mensaje" => "Error al registrar fecha de salida: " . $e->getMessage()
            ];
        }
    }

    /**
     * Insertar un nuevo candidato en la base de datos.
     * @param string $nombres Nombres del candidato.
     * @param string $primer_apellido Primer apellido del candidato.
     * @param string $segundo_apellido Segundo apellido del candidato.
     * @param string $correo Correo electrónico del candidato.
     * @param string $telefono Teléfono del candidato.
     * @param int $id_examen ID del examen asociado al candidato.
     * @param int $id_tipo_id ID del tipo de identificación del candidato.
     * @param int $id_rango_edad ID del rango de edad del candidato.
     * @param int $id_genero ID del género del candidato.
     */
    public function registrarCandidato(
        $nombres,
        $primer_apellido,
        $segundo_apellido,
        $correo,
        $telefono,
        $id_examen,
        $id_tipo_id,
        $id_rango_edad,
        $id_genero
    ) {
        $sql = "INSERT INTO candidato (nombres, primer_apellido, segundo_apellido, correo, telefono, id_examen, id_tipo_id, id_rango_edad, id_genero) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
        $stmt = $this->conn->prepare($sql);
        if ($stmt === false) {
            throw new Exception("Error en la preparación de la consulta: " . $this->conn->error);
        }
        $stmt->bind_param(
            "sssssiiii",
            $nombres,
            $primer_apellido,
            $segundo_apellido,
            $correo,
            $telefono,
            $id_examen,
            $id_tipo_id,
            $id_rango_edad,
            $id_genero
        );
        if (!$stmt->execute()) {
            throw new Exception("Error al insertar candidato: " . $stmt->error);
        }
        $insertId = $stmt->insert_id;
        $stmt->close();
        return $insertId;
    }


    /**
     * Verificar si ya existe un registro de información del candidato en la base de datos.
     * @param int $id_candidato ID del candidato.
     * @return bool true si existe un registro, false en caso contrario.
     */
    public function verificarRegistroInfoCandidato($id_candidato) {
        $sql = "SELECT COUNT(*) as count FROM info_candidatos WHERE id_candidato = ?";
        $stmt = $this->conn->prepare($sql);
        if ($stmt === false) {
            throw new Exception("Error en la preparación de la consulta: " . $this->conn->error);
        }
        $stmt->bind_param("i", $id_candidato);
        if (!$stmt->execute()) {
            throw new Exception("Error al ejecutar la consulta: " . $stmt->error);
        }
        $result = $stmt->get_result();
        $row = $result->fetch_assoc();
        $stmt->close();
        return $row['count'] > 0;
    }

    public function existeIdCandidato($id_candidato) {
        try {
            $sql = "SELECT COUNT(*) as count FROM candidato WHERE id_candidato = ?";

            $stmt = $this->conn->prepare($sql);
            if ($stmt === false) {
                return [
                    "estado" => "error",
                    "mensaje" => "Error en la preparación de la consulta: " . $this->conn->error
                ];
            }

            $stmt->bind_param("i", $id_candidato);

            if (!$stmt->execute()) {
                return [
                    "estado" => "error",
                    "mensaje" => "Error al ejecutar la consulta: " . $stmt->error
                ];
            }

            $result = $stmt->get_result();
            $stmt->close();
            $row = $result->fetch_assoc();

            if($row['count'] > 0){
                return  [
                    "estado" => "exitoso",
                    "mensaje" => "ID de candidato existe"
                ];
            } else {
                return [
                    "estado" => "error",
                    "mensaje" => "ID de candidato no existe"
                ];
            }

        } catch (Exception $e) {
            return [
                "estado" => "error",
                "mensaje" => "Error al verificar ID de candidato: " . $e->getMessage()
            ];
        }
    }

    public function obtenerCandidatoPorId($id_candidato) {
        $sql = "SELECT * FROM candidato WHERE id_candidato = ?";
        $stmt = $this->conn->prepare($sql);
        if ($stmt === false) {
            throw new Exception("Error en la preparación de la consulta: " . $this->conn->error);
        }
        $stmt->bind_param("i", $id_candidato);
        if (!$stmt->execute()) {
            throw new Exception("Error al ejecutar la consulta: " . $stmt->error);
        }
        $result = $stmt->get_result();
        $candidato = $result->fetch_assoc();
        $stmt->close();
        return $candidato;
    }

    public function obtenerInfoCandidatoPorId($id_candidato) {
        $sql = "SELECT * FROM info_candidatos WHERE id_candidato = ?";
        $stmt = $this->conn->prepare($sql);
        if ($stmt === false) {
            throw new Exception("Error en la preparación de la consulta: " . $this->conn->error);
        }
        $stmt->bind_param("i", $id_candidato);
        if (!$stmt->execute()) {
            throw new Exception("Error al ejecutar la consulta: " . $stmt->error);
        }
        $result = $stmt->get_result();
        $info = $result->fetch_assoc();
        $stmt->close();
        return $info;
    }

    /**
     * Obtiene información de los candidatos que no han llenado el segundo formulario
     * @return array
     */
    public function obtenerCandidatosSinFechaSalida(){
        $sql = "SELECT id_candidato, nombres, primer_apellido, segundo_apellido, fecha_entrada FROM candidato WHERE fecha_salida IS NULL ORDER BY fecha_entrada";
        try {
            $result = $this->conn->query($sql);
        } catch (Exception $e) {
            return [
                "estado" => "error",
                "mensaje" => $e->getMessage()
            ];
        }
        // Si no hay registros pendientes
        if($result->num_rows == 0){
            return [
                "estado" => "exitoso",
                "mensaje" => "No hay registros pendientes"
            ];
        } else {
            return $result->fetch_all(MYSQLI_ASSOC);
        }
    }

    public function eliminarCandidato($id_candidato){
        $sql = "DELETE FROM candidato WHERE id_candidato = ?";
        $stmt = $this->conn->prepare($sql);
        if ($stmt === false) {
            return [
                "estado" => "error",
                "mensaje" => "Error en la preparación de la consulta: " . $this->conn->error
            ];
        }
        $stmt->bind_param("i", $id_candidato);
        if (!$stmt->execute()) {
            return [
                "estado" => "error",
                "mensaje" => "Error al eliminar el candidato: " . $stmt->error
            ];
        }
        $stmt->close();
        return [
            "estado" => "exitoso",
            "mensaje" => "Candidato eliminado correctamente."
        ];
    }

}

?>