from alembic import op
import sqlalchemy as sa


revision = "0007"
down_revision = "0006"
branch_labels = None
depends_on = None


def upgrade() -> None:
    op.execute("""
                CREATE OR REPLACE FUNCTION v3.v_form1_smeta(p_year integer, p_org_unit_id integer)
                RETURNS TABLE(row_type character varying, depth integer, section_code character varying, name character varying, supp_plan_q1 numeric, supp_plan_q2 numeric, supp_plan_q3 numeric, supp_plan_q4 numeric, supp_plan_year numeric, dev_plan_q1 numeric, dev_plan_q2 numeric, dev_plan_q3 numeric, dev_plan_q4 numeric, dev_plan_year numeric, total_plan_year numeric, supp_appr_q1 numeric, supp_appr_q2 numeric, supp_appr_q3 numeric, supp_appr_q4 numeric, supp_appr_year numeric, dev_appr_q1 numeric, dev_appr_q2 numeric, dev_appr_q3 numeric, dev_appr_q4 numeric, dev_appr_year numeric, total_appr_year numeric, supp_act_q1 numeric, supp_act_q2 numeric, supp_act_q3 numeric, supp_act_q4 numeric, supp_act_year numeric, dev_act_q1 numeric, dev_act_q2 numeric, dev_act_q3 numeric, dev_act_q4 numeric, dev_act_year numeric, total_act_year numeric, supp_corr_q2 numeric, supp_corr_q3 numeric, supp_corr_q4 numeric, dev_corr_q2 numeric, dev_corr_q3 numeric, dev_corr_q4 numeric)
                LANGUAGE plpgsql
                STABLE
                SET search_path TO 'v3', 'pg_catalog'
                AS $function$
                #variable_conflict use_column
                DECLARE
                v_ahr INT; v_cap INT; v_oper INT;
                v_sections TEXT[] := ARRAY['plan','approved','q1','q2','q3','q4'];
                BEGIN
                -- Одна budget_form на лист содержит ОБА направления (budget_line.direction).
                -- Support/Development различаются параметром p_direction, а не отдельной формой.
                WITH ranked AS (
                    SELECT bf.id AS fid, ei.sheet AS sh
                    FROM budget_form bf
                    JOIN budget_line bl ON bl.budget_form_id = bf.id
                    JOIN expense_item ei ON ei.id = bl.expense_item_id
                    WHERE bf.year = p_year AND bf.org_unit_id = p_org_unit_id AND bf.form_type_code = 'FORM_1'
                    GROUP BY bf.id, ei.sheet
                )
                SELECT
                    MAX(CASE WHEN sh='AHR'  THEN fid END),
                    MAX(CASE WHEN sh='CAP'  THEN fid END),
                    MAX(CASE WHEN sh='OPER' THEN fid END)
                INTO v_ahr, v_cap, v_oper
                FROM ranked;

                RETURN QUERY
                WITH
                    ahr_s AS (
                    SELECT col_C_section AS sc, col_F_name AS nm, depth, row_type,
                            col_H_plan_q1 AS pq1, col_I_plan_q2 AS pq2, col_J_plan_q3 AS pq3, col_K_plan_q4 AS pq4, col_L_plan_year AS pyr,
                            col_AM_approved_q1 AS aq1, col_AN_approved_q2 AS aq2, col_AO_approved_q3 AS aq3, col_AP_approved_q4 AS aq4, col_AQ_approved_year AS ayr,
                            col_CS_q1_actual_quarter AS fq1, col_EB_q2_actual_quarter AS fq2, col_FJ_q3_actual_quarter AS fq3,
                            COALESCE(col_GQ_q4_actual_quarter,0) + COALESCE(col_GR_q4_actual_spod,0) AS fq4,
                            col_DH_q2_new_plan AS np2, col_EP_q3_new_plan AS np3, col_FW_q4_new_plan AS np4
                    FROM v_form1_sheet_sections(v_ahr, 'AHR', 'Support', v_sections)
                    WHERE row_type IN ('ROOT','GROUP','ITEM')
                    ),
                    ahr_d AS (
                    SELECT col_C_section AS sc, col_F_name AS nm, depth, row_type,
                            col_H_plan_q1 AS pq1, col_I_plan_q2 AS pq2, col_J_plan_q3 AS pq3, col_K_plan_q4 AS pq4, col_L_plan_year AS pyr,
                            col_AM_approved_q1 AS aq1, col_AN_approved_q2 AS aq2, col_AO_approved_q3 AS aq3, col_AP_approved_q4 AS aq4, col_AQ_approved_year AS ayr,
                            col_CS_q1_actual_quarter AS fq1, col_EB_q2_actual_quarter AS fq2, col_FJ_q3_actual_quarter AS fq3,
                            COALESCE(col_GQ_q4_actual_quarter,0) + COALESCE(col_GR_q4_actual_spod,0) AS fq4,
                            col_DH_q2_new_plan AS np2, col_EP_q3_new_plan AS np3, col_FW_q4_new_plan AS np4
                    FROM v_form1_sheet_sections(v_ahr, 'AHR', 'Development', v_sections)
                    WHERE row_type IN ('ROOT','GROUP','ITEM')
                    ),
                    cap_s AS (
                    SELECT col_C_section AS sc, col_F_name AS nm, depth, row_type,
                            col_H_plan_q1 AS pq1, col_I_plan_q2 AS pq2, col_J_plan_q3 AS pq3, col_K_plan_q4 AS pq4, col_L_plan_year AS pyr,
                            col_AM_approved_q1 AS aq1, col_AN_approved_q2 AS aq2, col_AO_approved_q3 AS aq3, col_AP_approved_q4 AS aq4, col_AQ_approved_year AS ayr,
                            col_CS_q1_actual_quarter AS fq1, col_EB_q2_actual_quarter AS fq2, col_FJ_q3_actual_quarter AS fq3,
                            COALESCE(col_GQ_q4_actual_quarter,0) + COALESCE(col_GR_q4_actual_spod,0) AS fq4,
                            col_DH_q2_new_plan AS np2, col_EP_q3_new_plan AS np3, col_FW_q4_new_plan AS np4
                    FROM v_form1_sheet_sections(v_cap, 'CAP', 'Support', v_sections)
                    WHERE row_type IN ('ROOT','GROUP','ITEM')
                    ),
                    cap_d AS (
                    SELECT col_C_section AS sc, col_F_name AS nm, depth, row_type,
                            col_H_plan_q1 AS pq1, col_I_plan_q2 AS pq2, col_J_plan_q3 AS pq3, col_K_plan_q4 AS pq4, col_L_plan_year AS pyr,
                            col_AM_approved_q1 AS aq1, col_AN_approved_q2 AS aq2, col_AO_approved_q3 AS aq3, col_AP_approved_q4 AS aq4, col_AQ_approved_year AS ayr,
                            col_CS_q1_actual_quarter AS fq1, col_EB_q2_actual_quarter AS fq2, col_FJ_q3_actual_quarter AS fq3,
                            COALESCE(col_GQ_q4_actual_quarter,0) + COALESCE(col_GR_q4_actual_spod,0) AS fq4,
                            col_DH_q2_new_plan AS np2, col_EP_q3_new_plan AS np3, col_FW_q4_new_plan AS np4
                    FROM v_form1_sheet_sections(v_cap, 'CAP', 'Development', v_sections)
                    WHERE row_type IN ('ROOT','GROUP','ITEM')
                    ),
                    oper_s AS (
                    SELECT col_C_section AS sc, col_F_name AS nm, depth, row_type,
                            col_H_plan_q1 AS pq1, col_I_plan_q2 AS pq2, col_J_plan_q3 AS pq3, col_K_plan_q4 AS pq4, col_L_plan_year AS pyr,
                            col_AM_approved_q1 AS aq1, col_AN_approved_q2 AS aq2, col_AO_approved_q3 AS aq3, col_AP_approved_q4 AS aq4, col_AQ_approved_year AS ayr,
                            col_CS_q1_actual_quarter AS fq1, col_EB_q2_actual_quarter AS fq2, col_FJ_q3_actual_quarter AS fq3,
                            COALESCE(col_GQ_q4_actual_quarter,0) + COALESCE(col_GR_q4_actual_spod,0) AS fq4,
                            col_DH_q2_new_plan AS np2, col_EP_q3_new_plan AS np3, col_FW_q4_new_plan AS np4
                    FROM v_form1_sheet_sections(v_oper, 'OPER', 'Support', v_sections)
                    WHERE row_type IN ('ROOT','GROUP','ITEM')
                    ),
                    merged AS (
                    SELECT COALESCE(s.row_type, d.row_type) AS row_type,
                            COALESCE(s.depth, d.depth) AS depth,
                            COALESCE(s.sc, d.sc) AS sc,
                            COALESCE(s.nm, d.nm) AS nm,
                            s.pq1, s.pq2, s.pq3, s.pq4, s.pyr,
                            d.pq1 AS d_pq1, d.pq2 AS d_pq2, d.pq3 AS d_pq3, d.pq4 AS d_pq4, d.pyr AS d_pyr,
                            s.aq1, s.aq2, s.aq3, s.aq4, s.ayr,
                            d.aq1 AS d_aq1, d.aq2 AS d_aq2, d.aq3 AS d_aq3, d.aq4 AS d_aq4, d.ayr AS d_ayr,
                            s.fq1, s.fq2, s.fq3, s.fq4,
                            d.fq1 AS d_fq1, d.fq2 AS d_fq2, d.fq3 AS d_fq3, d.fq4 AS d_fq4,
                            s.np2, s.np3, s.np4,
                            d.np2 AS d_np2, d.np3 AS d_np3, d.np4 AS d_np4
                    FROM ahr_s s FULL OUTER JOIN ahr_d d ON s.sc = d.sc
                    UNION ALL
                    SELECT COALESCE(s.row_type, d.row_type), COALESCE(s.depth, d.depth),
                            COALESCE(s.sc, d.sc), COALESCE(s.nm, d.nm),
                            s.pq1, s.pq2, s.pq3, s.pq4, s.pyr,
                            d.pq1, d.pq2, d.pq3, d.pq4, d.pyr,
                            s.aq1, s.aq2, s.aq3, s.aq4, s.ayr,
                            d.aq1, d.aq2, d.aq3, d.aq4, d.ayr,
                            s.fq1, s.fq2, s.fq3, s.fq4,
                            d.fq1, d.fq2, d.fq3, d.fq4,
                            s.np2, s.np3, s.np4,
                            d.np2, d.np3, d.np4
                    FROM cap_s s FULL OUTER JOIN cap_d d ON s.sc = d.sc
                    UNION ALL
                    SELECT s.row_type, s.depth, s.sc, s.nm,
                            s.pq1, s.pq2, s.pq3, s.pq4, s.pyr,
                            NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC,
                            s.aq1, s.aq2, s.aq3, s.aq4, s.ayr,
                            NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC,
                            s.fq1, s.fq2, s.fq3, s.fq4,
                            NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC,
                            s.np2, s.np3, s.np4,
                            NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC
                    FROM oper_s s
                    )
                SELECT
                    m.row_type, m.depth, m.sc, m.nm,
                    m.pq1, m.pq2, m.pq3, m.pq4, m.pyr,
                    m.d_pq1, m.d_pq2, m.d_pq3, m.d_pq4, m.d_pyr,
                    COALESCE(m.pyr,0) + COALESCE(m.d_pyr,0) AS total_plan_year,
                    m.aq1, m.aq2, m.aq3, m.aq4, m.ayr,
                    m.d_aq1, m.d_aq2, m.d_aq3, m.d_aq4, m.d_ayr,
                    COALESCE(m.ayr,0) + COALESCE(m.d_ayr,0) AS total_appr_year,
                    m.fq1, m.fq2, m.fq3, m.fq4, COALESCE(m.fq1,0)+COALESCE(m.fq2,0)+COALESCE(m.fq3,0)+COALESCE(m.fq4,0),
                    m.d_fq1, m.d_fq2, m.d_fq3, m.d_fq4, COALESCE(m.d_fq1,0)+COALESCE(m.d_fq2,0)+COALESCE(m.d_fq3,0)+COALESCE(m.d_fq4,0),
                    COALESCE(m.fq1,0)+COALESCE(m.fq2,0)+COALESCE(m.fq3,0)+COALESCE(m.fq4,0)
                    + COALESCE(m.d_fq1,0)+COALESCE(m.d_fq2,0)+COALESCE(m.d_fq3,0)+COALESCE(m.d_fq4,0),
                    m.np2, m.np3, m.np4,
                    m.d_np2, m.d_np3, m.d_np4
                FROM merged m
                ORDER BY m.sc;
                END;
                $function$
                ;
    """)
    for t_name in (
        "reserve", "contract_detail", "ckk", "allocation", "sequestration", "contract_summary",
        "collegial_approval", "rent_detail", "utility_detail", "plan", "budget_line_quarter"
    ):
        op.execute(f"""
            delete from v3.{t_name} where line_id in (
            select id from v3.budget_line where budget_form_id not in (select min(fid) from (
                SELECT bf.id AS fid, bf.year as yr, bf.form_type_code as ftc, bf.org_unit_id as oui
                FROM v3.budget_form bf
            ) ranked
            group by yr, ftc, oui));
        """)
    op.execute("""
        delete from v3.budget_line where budget_form_id not in (select min(fid) from (
            SELECT bf.id AS fid, bf.year as yr, bf.form_type_code as ftc, bf.org_unit_id as oui
            FROM v3.budget_form bf
        ) ranked
        group by yr, ftc, oui); 
    """)
    op.execute("""
        delete from v3.budget_form where id not in (select min(fid) from (
            SELECT bf.id AS fid, bf.year as yr, bf.form_type_code as ftc, bf.org_unit_id as oui
            FROM v3.budget_form bf
        ) ranked
        group by yr, ftc, oui);
    """)
    op.execute("ALTER TABLE v3.budget_form ADD CONSTRAINT uq_ftype_org_year UNIQUE (form_type_code, org_unit_id, year)")

def downgrade() -> None:
    pass
