-- +goose Up
-- +goose StatementBegin
CREATE OR REPLACE PROCEDURE VITRUVIO.PRC_FLASH_CARGA_RESUMO_PERDA (
    p_data_inicial IN DATE,
    p_data_final   IN DATE
) AS
    v_dt_ini DATE := TRUNC(p_data_inicial);
    v_dt_fim DATE := TRUNC(p_data_final) + 1;
BEGIN
    DELETE FROM TB_FLASH_NODO_RESUMO_PERDA
     WHERE data_referencia >= v_dt_ini
       AND data_referencia <  v_dt_fim;

    INSERT /*+ APPEND */ INTO TB_FLASH_NODO_RESUMO_PERDA (
        id_resumo, id_nodo, data_referencia, ano_referencia, mes_referencia, dia_referencia,
        valor_venda, valor_meta_propria, valor_meta_filhos, valor_meta_efetiva,
        percentual_meta_propria, percentual_meta_filhos, percentual_meta_efetiva,
        desvio, percentual_atingimento, data_apuracao, nro_segmento, nome_segmento
    )
    WITH
    hierarquia AS (
        SELECT /*+ MATERIALIZE */
               CONNECT_BY_ROOT n.id_nodo AS id_nodo_ancestral,
               n.id_nodo                 AS id_nodo_descendente
          FROM TB_FLASH_NODO n
        CONNECT BY PRIOR n.id_nodo = n.id_nodo_pai
    ),
    venda_direta AS (
        SELECT f.id_nodo,
               TRUNC(f.data_referencia)                     AS data_referencia,
               EXTRACT(YEAR  FROM TRUNC(f.data_referencia)) AS ano_referencia,
               EXTRACT(MONTH FROM TRUNC(f.data_referencia)) AS mes_referencia,
               EXTRACT(DAY   FROM TRUNC(f.data_referencia)) AS dia_referencia,
               SUM(f.vlr_perda)                             AS valor_venda,
               MAX(f.nrosegmento)                           AS nro_segmento,
               MAX(f.nome_segmento)                         AS nome_segmento
          FROM TB_FLASH_FATO_PERDA f
         WHERE f.data_referencia >= v_dt_ini
           AND f.data_referencia <  v_dt_fim
         GROUP BY f.id_nodo, TRUNC(f.data_referencia)
    ),
    venda_hierarquia AS (
        SELECT h.id_nodo_ancestral AS id_nodo,
               vd.data_referencia, vd.ano_referencia, vd.mes_referencia, vd.dia_referencia,
               SUM(vd.valor_venda) AS valor_venda
          FROM hierarquia h
          JOIN venda_direta vd ON vd.id_nodo = h.id_nodo_descendente
         GROUP BY h.id_nodo_ancestral, vd.data_referencia, vd.ano_referencia, vd.mes_referencia, vd.dia_referencia
    ),
    meta_propria_diaria AS (
        SELECT /*+ MATERIALIZE */
               m.id_nodo,
               TRUNC(m.data_referencia)                     AS data_referencia,
               EXTRACT(YEAR  FROM TRUNC(m.data_referencia)) AS ano_referencia,
               EXTRACT(MONTH FROM TRUNC(m.data_referencia)) AS mes_referencia,
               EXTRACT(DAY   FROM TRUNC(m.data_referencia)) AS dia_referencia,
               MAX(m.percentual_meta)                       AS percentual_meta_propria,
               SUM(m.valor_meta)                            AS valor_meta_propria
          FROM TB_FLASH_META_PERDA m
         WHERE m.data_referencia >= v_dt_ini
           AND m.data_referencia <  v_dt_fim
         GROUP BY m.id_nodo, TRUNC(m.data_referencia)
    ),
    meta_filhos_diaria AS (
        SELECT pai.id_nodo,
               mpd.data_referencia, mpd.ano_referencia, mpd.mes_referencia, mpd.dia_referencia,
               SUM(mpd.valor_meta_propria) AS valor_meta_filhos
          FROM TB_FLASH_NODO pai
          JOIN TB_FLASH_NODO filho ON filho.id_nodo_pai = pai.id_nodo
          JOIN meta_propria_diaria mpd ON mpd.id_nodo = filho.id_nodo
         GROUP BY pai.id_nodo, mpd.data_referencia, mpd.ano_referencia, mpd.mes_referencia, mpd.dia_referencia
    ),
    combinado AS (
        SELECT
            COALESCE(vh.id_nodo,         mpd.id_nodo,         mfd.id_nodo)         AS id_nodo,
            COALESCE(vh.data_referencia, mpd.data_referencia, mfd.data_referencia) AS data_referencia,
            COALESCE(vh.ano_referencia,  mpd.ano_referencia,  mfd.ano_referencia)  AS ano_referencia,
            COALESCE(vh.mes_referencia,  mpd.mes_referencia,  mfd.mes_referencia)  AS mes_referencia,
            COALESCE(vh.dia_referencia,  mpd.dia_referencia,  mfd.dia_referencia)  AS dia_referencia,
            NVL(vh.valor_venda, 0)                                                 AS valor_venda,
            mpd.valor_meta_propria,
            mpd.percentual_meta_propria,
            mfd.valor_meta_filhos,
            CASE WHEN mpd.valor_meta_propria IS NOT NULL THEN mpd.valor_meta_propria ELSE mfd.valor_meta_filhos END AS valor_meta_efetiva
          FROM venda_hierarquia vh
          FULL OUTER JOIN meta_propria_diaria mpd
            ON  mpd.id_nodo         = vh.id_nodo
            AND mpd.data_referencia = vh.data_referencia
          FULL OUTER JOIN meta_filhos_diaria mfd
            ON  mfd.id_nodo         = COALESCE(vh.id_nodo,         mpd.id_nodo)
            AND mfd.data_referencia = COALESCE(vh.data_referencia, mpd.data_referencia)
    )
    SELECT SEQ_TB_FLASH_NODO_RESUMO_PERDA.NEXTVAL,
           c.id_nodo, c.data_referencia, c.ano_referencia, c.mes_referencia, c.dia_referencia,
           c.valor_venda,
           c.valor_meta_propria,
           c.valor_meta_filhos,
           c.valor_meta_efetiva,
           c.percentual_meta_propria,
           CAST(NULL AS NUMBER(10,4))                    AS percentual_meta_filhos,
           c.percentual_meta_propria                    AS percentual_meta_efetiva,
           c.valor_venda - NVL(c.valor_meta_efetiva, 0) AS desvio,
           CASE WHEN NVL(c.valor_meta_efetiva, 0) = 0 THEN NULL ELSE c.valor_venda / c.valor_meta_efetiva * 100 END AS percentual_atingimento,
           SYSDATE,
           vd.nro_segmento,
           vd.nome_segmento
      FROM combinado c
      LEFT JOIN venda_direta vd ON vd.id_nodo = c.id_nodo AND vd.data_referencia = c.data_referencia;

    COMMIT;
END;
-- +goose StatementEnd

-- +goose Down
-- +goose StatementBegin
DECLARE
    v_count NUMBER;
BEGIN
    SELECT COUNT(*) INTO v_count FROM user_objects WHERE object_name = 'PRC_FLASH_CARGA_RESUMO_PERDA' AND object_type = 'PROCEDURE';
    IF v_count > 0 THEN
        EXECUTE IMMEDIATE 'DROP PROCEDURE PRC_FLASH_CARGA_RESUMO_PERDA';
    END IF;
END;
-- +goose StatementEnd
