
#---------------------------------------trigers ---------------------
DELIMITER $$

USE `rnia`$$

DROP TRIGGER /*!50032 IF EXISTS */ `existencias_animal_update`$$

CREATE
    /*!50017 DEFINER = `apps`@`localhost` */
    TRIGGER `existencias_animal_update` AFTER UPDATE ON `animais` 
    FOR EACH ROW BEGIN
	CALL rnia.`gera_existencias`(NEW.id);
    END;
$$

DELIMITER ;





DELIMITER $$

USE `rnia`$$

DROP TRIGGER /*!50032 IF EXISTS */ `existencias_animal_delete`$$

CREATE
    /*!50017 DEFINER = `apps`@`localhost` */
    TRIGGER `existencias_animal_delete` AFTER DELETE ON `animais` 
    FOR EACH ROW BEGIN
	CALL rnia.`gera_existencias`(OLD.id);
    END;
$$

DELIMITER ;




DELIMITER $$

USE `rnia`$$

DROP TRIGGER /*!50032 IF EXISTS */ `existencias_animal_insert`$$

CREATE
    /*!50017 DEFINER = `apps`@`localhost` */
    TRIGGER `existencias_animal_insert` AFTER INSERT ON `animais` 
    FOR EACH ROW BEGIN
	CALL rnia.`gera_existencias`(NEW.id);
    END;
$$

DELIMITER ;


DELIMITER $$

USE `rnia`$$

DROP TRIGGER /*!50032 IF EXISTS */ `update_animais_delete`$$

CREATE
    /*!50017 DEFINER = 'apps'@'localhost' */
    TRIGGER `update_animais_delete` AFTER DELETE ON `movimentos_animais` 
    FOR EACH ROW BEGIN
	CALL update_animais_movimentos(OLD.id_animal);
END;
$$

DELIMITER ;


DELIMITER $$

USE `rnia`$$

DROP TRIGGER /*!50032 IF EXISTS */ `update_animais_insert`$$

CREATE
    /*!50017 DEFINER = 'apps'@'localhost' */
    TRIGGER `update_animais_insert` AFTER INSERT ON `movimentos_animais` 
    FOR EACH ROW BEGIN
	CALL update_animais_movimentos(NEW.id_animal);
END;
$$

DELIMITER ;


DELIMITER $$

USE `rnia`$$

DROP TRIGGER /*!50032 IF EXISTS */ `update_animais_loop`$$

CREATE
    /*!50017 DEFINER = 'apps'@'localhost' */
    TRIGGER `update_animais_loop` AFTER INSERT ON `movimentos_animais` 
    FOR EACH ROW BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE animal_id INT;
    
   	DECLARE cur CURSOR FOR 
        SELECT id_animal 
        FROM movimentos_animais 
        WHERE id_movimento = NEW.id;
       
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN cur;
    
    read_loop: LOOP
        FETCH cur INTO animal_id;
        IF done THEN
            LEAVE read_loop;
        END IF;
        
        CALL update_animais_movimentos(animal_id);
    END LOOP;
    
    CLOSE cur;
END;
$$

DELIMITER ;


DELIMITER $$

USE `rnia`$$

DROP TRIGGER /*!50032 IF EXISTS */ `update_animais_loop_delete`$$

CREATE
    /*!50017 DEFINER = `apps`@`localhost` */
    TRIGGER `update_animais_loop_delete` AFTER DELETE ON `movimentos` 
    FOR EACH ROW BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE animal_id INT;
    DECLARE cur CURSOR FOR 
        SELECT id_animal 
        FROM movimentos_animais 
        WHERE id_movimento = OLD.id;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN cur;
    
    read_loop: LOOP
        FETCH cur INTO animal_id;
        IF done THEN
            LEAVE read_loop;
        END IF;
        
        CALL update_animais_movimentos(animal_id);
    END LOOP;
    
    CLOSE cur;
   
   DELETE FROM movimentos_animais WHERE id_movimento = OLD.id;
END;
$$

DELIMITER ;



DELIMITER $$

USE `rnia`$$

DROP TRIGGER /*!50032 IF EXISTS */ `update_animais_loop_insert`$$

CREATE
    /*!50017 DEFINER = `apps`@`localhost` */
    TRIGGER `update_animais_loop_insert` AFTER INSERT ON `movimentos` 
    FOR EACH ROW BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE animal_id INT;
    DECLARE cur CURSOR FOR 
        SELECT id_animal 
        FROM movimentos_animais 
        WHERE id_movimento = NEW.id;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN cur;
    
    read_loop: LOOP
        FETCH cur INTO animal_id;
        IF done THEN
            LEAVE read_loop;
        END IF;
        
        CALL update_animais_movimentos(animal_id);
    END LOOP;
    
    CLOSE cur;
END;
$$

DELIMITER ;



DELIMITER $$

USE `rnia`$$

DROP TRIGGER /*!50032 IF EXISTS */ `update_animais_loop_update`$$

CREATE
    /*!50017 DEFINER = `apps`@`localhost` */
    TRIGGER `update_animais_loop_update` AFTER UPDATE ON `movimentos` 
    FOR EACH ROW BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE animal_id INT;
    
   	DECLARE cur CURSOR FOR 
        SELECT id_animal 
        FROM movimentos_animais 
        WHERE id_movimento = NEW.id;
       
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN cur;
    
    read_loop: LOOP
        FETCH cur INTO animal_id;
        IF done THEN
            LEAVE read_loop;
        END IF;
        
        CALL update_animais_movimentos(animal_id);
    END LOOP;
    
    CLOSE cur;
END;
$$

DELIMITER ;



DELIMITER $$

USE `rnia`$$

DROP TRIGGER /*!50032 IF EXISTS */ `update_animais_update`$$

CREATE
    /*!50017 DEFINER = 'apps'@'localhost' */
    TRIGGER `update_animais_update` AFTER UPDATE ON `movimentos_animais` 
    FOR EACH ROW BEGIN 
	CALL update_animais_movimentos(NEW.id_animal);
	CALL update_animais_movimentos(OLD.id_animal);
END;
$$

DELIMITER ;

#------------------------procedures


DELIMITER $$

USE `rnia`$$

DROP PROCEDURE IF EXISTS `update_animais_movimentos`$$

CREATE DEFINER=`apps`@`localhost` PROCEDURE `update_animais_movimentos`(IN animal_id INT)
BEGIN

   UPDATE animais
    LEFT JOIN (
        SELECT ma.id_movimento, m.data_saida, m.id_entidade_destino, m.id_exploracao_destino, m.id, m.data_destino
        FROM movimentos_animais AS ma 
        INNER JOIN movimentos AS m ON ma.id_movimento=m.id
        WHERE ma.id_animal=animal_id
        ORDER BY m.data_saida DESC LIMIT 1
    ) AS mov 
    ON 1=1
    SET 
    id_entidade_pre = IF(mov.id_entidade_destino IS NULL, animais.id_entidade_ori, IF(data_destino IS NULL OR data_destino='0000-00-00', 2, mov.id_entidade_destino)), 
    id_exploracao_pre = IF(mov.id_exploracao_destino IS NULL, animais.id_exploracao_ori, IF(data_destino IS NULL OR data_destino='0000-00-00', NULL, mov.id_exploracao_destino)), 
    id_ult_mov = IF(mov.id IS NULL, NULL, mov.id),
    data_entrada=IF(mov.id IS NULL, data_nasc, IF(data_destino IS NULL OR data_destino='0000-00-00', mov.data_saida, mov.data_destino)),
    causa_entrada = IF(mov.id IS NULL, causa_entrada, 4)    
    
    WHERE animais.id=animal_id;
    
    CALL rnia.`gera_existencias`(animal_id);
    
END$$

DELIMITER ;


DELIMITER $$

USE `rnia`$$

DROP PROCEDURE IF EXISTS `gera_existencias`$$

CREATE DEFINER=`apps`@`localhost` PROCEDURE `gera_existencias`(p_animal_id BIGINT)
BEGIN   
     
    #DECLARE _EXEC_EXISTENCIAS TINYINT;
    
    IF (p_animal_id IS NOT NULL) THEN
        IF (p_animal_id = '-1') THEN
            DELETE FROM existencias; 
            #ALTER TABLE existencias AUTO_INCREMENT = 1;
            
            SET p_animal_id = NULL;
            
        ELSE
            
            DELETE FROM existencias WHERE id_animal = p_animal_id;
            
        END IF;
        
        INSERT INTO rnia.existencias(`tipo`, `n_rnia`, `id_animal`, `data_entrada`, `id_entidade`, `id_exploracao`, `data_saida`, `id_mov_entrada`, `id_mov_saida`)
	
	SELECT 'nasc', `a`.`n_rnia` AS `n_rnia`,`a`.`id` AS `id_animal`,`a`.`data_nasc` AS `data_entrada`,`a`.`id_entidade_ori` AS `id_entidade`,`a`.`id_exploracao_ori` AS `id_exploracao`,
	IF(`m`.`data_saida` IS NULL,`a`.`data_morte`,MIN(`m`.`data_saida`)) AS `data_saida` 
	, NULL, m.id
	FROM `animais` `a` 
	LEFT JOIN `movimentos_animais` `ma` ON `ma`.`id_animal` = `a`.`id` 
	LEFT JOIN `movimentos` `m` ON `m`.`id` = `ma`.`id_movimento` 
	#WHERE n_rnia='AO2CB400102021'
	WHERE (p_animal_id IS NULL OR a.id=p_animal_id)
	GROUP BY `a`.`id`;
        
        
         
        INSERT INTO rnia.existencias(`tipo`, `n_rnia`, `id_animal`, `data_entrada`, `id_entidade`, `id_exploracao`, `data_saida`, `id_mov_entrada`, `id_mov_saida`)  
        SELECT 'movs', `a`.`n_rnia` AS `n_rnia`,`a`.`id` AS `id_animal`,`m`.`data_destino` AS `data_entrada`,`m`.`id_entidade_destino` AS `id_entidade`
        ,`m`.`id_exploracao_destino` AS `id_exploracao`,
	IF(`m2`.`data_saida`,`m2`.`data_saida`,`a`.`data_morte`) AS `data_saida` 
	, m.id, m2.id 
	
	FROM `animais` `a` 
	
	INNER JOIN `movimentos` `m` ON a.id IN (SELECT id_animal FROM movimentos_animais WHERE id_movimento = m.id)
	
		LEFT JOIN `movimentos` `m2` ON  `m2`.`data_saida` > `m`.`data_saida` AND a.id IN (SELECT id_animal FROM movimentos_animais WHERE id_movimento = m2.id)

		LEFT JOIN `movimentos` `m3` ON  `m2`.`data_saida` > `m2`.`data_saida` AND a.id IN (SELECT id_animal FROM movimentos_animais WHERE id_movimento = m3.id)
		
	WHERE `m`.`data_destino` <> 0 AND m3.id IS NULL
	AND (p_animal_id IS NULL OR a.id=p_animal_id)
	#AND n_rnia='AO2CB400102021'
	
	GROUP BY `a`.`id`,`m`.`id`;
	    
            
        
    END IF;
END$$

DELIMITER ;



DELIMITER $$
USE `rnia`$$
DROP TRIGGER /*!50032 IF EXISTS */ `meios_identificacao_perdas_after_update`$$
CREATE
    TRIGGER `meios_identificacao_perdas_after_update` AFTER UPDATE ON `meios_identificacao_perdas` 
    FOR EACH ROW BEGIN
	-- Campos diferentes ( <=> faz comparacao de null e tudo )
	IF NOT (OLD.brinco_posterior <=> NEW.brinco_posterior) THEN
		CALL processaPerdaTrocaBrinco(NEW.id);
	END IF;
    END;
$$
DELIMITER ;

DELIMITER $$
USE `rnia`$$
DROP TRIGGER /*!50032 IF EXISTS */ `meios_identificacao_perdas_after_delete`$$
CREATE

    TRIGGER `meios_identificacao_perdas_after_delete` AFTER DELETE ON `meios_identificacao_perdas` 
    FOR EACH ROW BEGIN
	-- Se nao houve troca, não é preciso reverter nada
	IF (NULLIF(OLD.brinco_anterior,'') IS NOT NULL AND NULLIF(OLD.brinco_posterior,'') IS NOT NULL) THEN
		CALL processaPerdaTrocaBrinco_delete(OLD.id_animal, OLD.brinco_anterior, OLD.brinco_posterior);
	END IF;
    END;
$$
DELIMITER ;


DELIMITER $$
DROP PROCEDURE IF EXISTS `processaPerdaTrocaBrinco`$$
CREATE
    /*[DEFINER = { user | CURRENT_USER }]*/
    PROCEDURE `rnia`.`processaPerdaTrocaBrinco`(p_id_mov_perda INT)
    /*LANGUAGE SQL
    | [NOT] DETERMINISTIC
    | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
    | SQL SECURITY { DEFINER | INVOKER }
    | COMMENT 'string'*/
	BEGIN
		DECLARE t_trocas_posteriores TINYINT;
		DECLARE t_existe_novo_brinco TINYINT;
		DECLARE n_rnia_actual VARCHAR(20);
		DECLARE n_rnia_novo VARCHAR(20);
		DECLARE user_alteracao VARCHAR(200);
		DECLARE id_animal BIGINT;
		
		SELECT 
		a.n_rnia n_rnia_actual
		, a.id id_animal
		, (SELECT COUNT(*) FROM `meios_identificacao_perdas` WHERE id_animal = mip.id_animal AND id NOT IN (mip.id) AND data_reaplicacao > mip.data_reaplicacao) t_trocas_posteriores
		, (SELECT COUNT(*) FROM animais WHERE n_rnia = mip.brinco_posterior) t_existe_novo_brinco
		, mip.brinco_posterior n_rnia_novo
		, mip.user
		INTO n_rnia_actual, id_animal, t_trocas_posteriores, t_existe_novo_brinco, n_rnia_novo, user_alteracao
		FROM `meios_identificacao_perdas` mip
		JOIN animais a ON a.id = mip.id_animal 
		WHERE mip.id = p_id_mov_perda;
		
		-- Nexiste 1 animal com o novo n_rnia + não ha trocas posteriores + o animal existe para levar update
		IF (t_existe_novo_brinco = 0 AND t_trocas_posteriores = 0 AND id_animal > 0 AND NULLIF(n_rnia_novo, '') IS NOT NULL) THEN
		
			INSERT IGNORE INTO animais_h SELECT * FROM animais WHERE id = id_animal LIMIT 1;
			
			UPDATE animais
			SET n_rnia = n_rnia_novo, fonte = 'processaPerdaTrocaBrinco', `data` = NOW(), `user` = user_alteracao
			WHERE id = id_animal;
			
		END IF;
	END$$

DELIMITER ;


DELIMITER $$
DROP PROCEDURE IF EXISTS `processaPerdaTrocaBrinco_delete`$$
CREATE
    /*[DEFINER = { user | CURRENT_USER }]*/
    PROCEDURE `rnia`.`processaPerdaTrocaBrinco_delete`(p_id_animal BIGINT, p_brinco_anterior VARCHAR(20), p_brinco_posterior VARCHAR(20))
    /*LANGUAGE SQL
    | [NOT] DETERMINISTIC
    | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
    | SQL SECURITY { DEFINER | INVOKER }
    | COMMENT 'string'*/
	BEGIN
		DECLARE t_existe TINYINT;
		DECLARE id_animal BIGINT;
		
		SELECT a.id AS id_animal
		, (SELECT COUNT(*) FROM animais WHERE n_rnia = p_brinco_anterior) t_existe
		INTO id_animal, t_existe
		FROM animais a
		WHERE a.id = p_id_animal AND n_rnia = p_brinco_posterior;
		
		-- Nexiste 1 animal com o anterior n_rnia que agora vai ser actual
		IF (t_existe = 0 AND id_animal > 0 AND NULLIF(p_brinco_posterior, '') IS NOT NULL) THEN
		
			INSERT IGNORE INTO animais_h SELECT * FROM animais WHERE id = p_id_animal LIMIT 1;
			
			UPDATE animais
			SET n_rnia = p_brinco_anterior, fonte = 'processaPerdaTrocaBrinco_delete', `data` = NOW()
			WHERE id = p_id_animal;
			
		END IF;
	END$$

DELIMITER ;


DELIMITER $$

CREATE FUNCTION rnia.isInteger(val VARCHAR(255))
RETURNS BOOLEAN
DETERMINISTIC
BEGIN
    RETURN val REGEXP '^[0-9]+$';
END$$

DELIMITER ;