-- noqa: disable=all
-- This sql was autogenerated as a reference example using the library
-- CLI. Its format is tied to the specific database it was run against,
-- and it may not be correct for all databases. Use the CLI's build 
-- option to derive the best SQL for your dataset.

-- ###########################################################

CREATE TABLE core__encounter_dn_type AS (
    WITH

    flattened_rows AS (
        SELECT DISTINCT
            t.id AS id,
            ROW_NUMBER() OVER (PARTITION BY id) AS row,
            r."type"
        FROM
            encounter AS t,
            UNNEST(t."type") AS r ("type")
    ),

    system_type_0 AS (
        SELECT DISTINCT
            s.id AS id,
            s.row,
            '0' AS priority,
            u.coding.code,
            u.coding.display,
            u.coding.system,
            u.coding.userSelected
        FROM
            flattened_rows AS s,
            UNNEST(s.type.coding) AS u (coding)
        WHERE
            REGEXP_LIKE(u.coding.system, '^http://terminology\.hl7\.org/CodeSystem/encounter-type$')
    ), --noqa: LT07

    system_type_1 AS (
        SELECT DISTINCT
            s.id AS id,
            s.row,
            '1' AS priority,
            u.coding.code,
            u.coding.display,
            u.coding.system,
            u.coding.userSelected
        FROM
            flattened_rows AS s,
            UNNEST(s.type.coding) AS u (coding)
        WHERE
            REGEXP_LIKE(u.coding.system, '^http://terminology\.hl7\.org/CodeSystem/v2-0004$')
    ), --noqa: LT07

    system_type_2 AS (
        SELECT DISTINCT
            s.id AS id,
            s.row,
            '2' AS priority,
            u.coding.code,
            u.coding.display,
            u.coding.system,
            u.coding.userSelected
        FROM
            flattened_rows AS s,
            UNNEST(s.type.coding) AS u (coding)
        WHERE
            REGEXP_LIKE(u.coding.system, '^urn:oid:2\.16\.840\.1\.113883\.4\.642\.3\.248$')
    ), --noqa: LT07

    system_type_3 AS (
        SELECT DISTINCT
            s.id AS id,
            s.row,
            '3' AS priority,
            u.coding.code,
            u.coding.display,
            u.coding.system,
            u.coding.userSelected
        FROM
            flattened_rows AS s,
            UNNEST(s.type.coding) AS u (coding)
        WHERE
            REGEXP_LIKE(u.coding.system, '^http://snomed\.info/sct$')
    ), --noqa: LT07

    system_type_4 AS (
        SELECT DISTINCT
            s.id AS id,
            s.row,
            '4' AS priority,
            u.coding.code,
            u.coding.display,
            u.coding.system,
            u.coding.userSelected
        FROM
            flattened_rows AS s,
            UNNEST(s.type.coding) AS u (coding)
        WHERE
            REGEXP_LIKE(u.coding.system, '^https://fhir\.cerner\.com/.*/codeSet/71$')
    ), --noqa: LT07

    system_type_5 AS (
        SELECT DISTINCT
            s.id AS id,
            s.row,
            '5' AS priority,
            u.coding.code,
            u.coding.display,
            u.coding.system,
            u.coding.userSelected
        FROM
            flattened_rows AS s,
            UNNEST(s.type.coding) AS u (coding)
        WHERE
            REGEXP_LIKE(u.coding.system, '^urn:oid:1\.2\.840\.114350\.1\.13\.71\.2\.7\.10\.698084\.10110$')
    ), --noqa: LT07

    system_type_6 AS (
        SELECT DISTINCT
            s.id AS id,
            s.row,
            '6' AS priority,
            u.coding.code,
            u.coding.display,
            u.coding.system,
            u.coding.userSelected
        FROM
            flattened_rows AS s,
            UNNEST(s.type.coding) AS u (coding)
        WHERE
            REGEXP_LIKE(u.coding.system, '^urn:oid:1\.2\.840\.114350\.1\.13\.71\.2\.7\.10\.698084\.18875$')
    ), --noqa: LT07

    system_type_7 AS (
        SELECT DISTINCT
            s.id AS id,
            s.row,
            '7' AS priority,
            u.coding.code,
            u.coding.display,
            u.coding.system,
            u.coding.userSelected
        FROM
            flattened_rows AS s,
            UNNEST(s.type.coding) AS u (coding)
        WHERE
            REGEXP_LIKE(u.coding.system, '^urn:oid:1\.2\.840\.114350\.1\.13\.71\.2\.7\.10\.698084\.30$')
    ), --noqa: LT07

    system_type_8 AS (
        SELECT DISTINCT
            s.id AS id,
            s.row,
            '8' AS priority,
            u.coding.code,
            u.coding.display,
            u.coding.system,
            u.coding.userSelected
        FROM
            flattened_rows AS s,
            UNNEST(s.type.coding) AS u (coding)
        WHERE
            REGEXP_LIKE(u.coding.system, '^urn:oid:1\.2\.840\.114350\.1\.13\.71\.2\.7\.2\.808267$')
    ), --noqa: LT07

    union_table AS (
        SELECT
            id,
            row,
            priority,
            system,
            code,
            display,
            userSelected
        FROM system_type_0
        UNION
        SELECT
            id,
            row,
            priority,
            system,
            code,
            display,
            userSelected
        FROM system_type_1
        UNION
        SELECT
            id,
            row,
            priority,
            system,
            code,
            display,
            userSelected
        FROM system_type_2
        UNION
        SELECT
            id,
            row,
            priority,
            system,
            code,
            display,
            userSelected
        FROM system_type_3
        UNION
        SELECT
            id,
            row,
            priority,
            system,
            code,
            display,
            userSelected
        FROM system_type_4
        UNION
        SELECT
            id,
            row,
            priority,
            system,
            code,
            display,
            userSelected
        FROM system_type_5
        UNION
        SELECT
            id,
            row,
            priority,
            system,
            code,
            display,
            userSelected
        FROM system_type_6
        UNION
        SELECT
            id,
            row,
            priority,
            system,
            code,
            display,
            userSelected
        FROM system_type_7
        UNION
        SELECT
            id,
            row,
            priority,
            system,
            code,
            display,
            userSelected
        FROM system_type_8
        
    ),

    partitioned_table AS (
        SELECT
            id,
            row,
            code,
            system,
            display,
            userSelected,
            priority,
            ROW_NUMBER()
                OVER (
                    PARTITION BY id
                    ORDER BY priority ASC, code ASC
                ) AS available_priority
        FROM union_table
        GROUP BY
            id, row, priority, system, code, display, userSelected
    )

    SELECT
        id,
        row,
        code,
        system,
        display,
        userSelected
    FROM partitioned_table
    WHERE available_priority = 1
);


-- ###########################################################

CREATE TABLE IF NOT EXISTS "main"."core__encounter_dn_servicetype"
AS (
    SELECT * FROM (
        VALUES
        (cast(NULL AS varchar),cast(NULL AS bigint),cast(NULL AS varchar),cast(NULL AS varchar),cast(NULL AS varchar),cast(NULL AS boolean))
    )
        AS t ("id","row","code","system","display","userSelected")
    WHERE 1 = 0 -- ensure empty table
);

-- ###########################################################

CREATE TABLE IF NOT EXISTS "main"."core__encounter_dn_priority"
AS (
    SELECT * FROM (
        VALUES
        (cast(NULL AS varchar),cast(NULL AS bigint),cast(NULL AS varchar),cast(NULL AS varchar),cast(NULL AS varchar),cast(NULL AS boolean))
    )
        AS t ("id","row","code","system","display","userSelected")
    WHERE 1 = 0 -- ensure empty table
);

-- ###########################################################

CREATE TABLE core__encounter_dn_reasoncode AS (
    WITH

    flattened_rows AS (
        SELECT DISTINCT
            t.id AS id,
            ROW_NUMBER() OVER (PARTITION BY id) AS row,
            r."reasoncode"
        FROM
            encounter AS t,
            UNNEST(t."reasoncode") AS r ("reasoncode")
    ),

    system_reasoncode_0 AS (
        SELECT DISTINCT
            s.id AS id,
            s.row,
            '0' AS priority,
            u.coding.code,
            u.coding.display,
            u.coding.system,
            u.coding.userSelected
        FROM
            flattened_rows AS s,
            UNNEST(s.reasoncode.coding) AS u (coding)
        WHERE
            REGEXP_LIKE(u.coding.system, '^http://terminology\.hl7\.org/CodeSystem/v3-ActPriority$')
    ), --noqa: LT07

    system_reasoncode_1 AS (
        SELECT DISTINCT
            s.id AS id,
            s.row,
            '1' AS priority,
            u.coding.code,
            u.coding.display,
            u.coding.system,
            u.coding.userSelected
        FROM
            flattened_rows AS s,
            UNNEST(s.reasoncode.coding) AS u (coding)
        WHERE
            REGEXP_LIKE(u.coding.system, '^http://snomed\.info/sct$')
    ), --noqa: LT07

    system_reasoncode_2 AS (
        SELECT DISTINCT
            s.id AS id,
            s.row,
            '2' AS priority,
            u.coding.code,
            u.coding.display,
            u.coding.system,
            u.coding.userSelected
        FROM
            flattened_rows AS s,
            UNNEST(s.reasoncode.coding) AS u (coding)
        WHERE
            REGEXP_LIKE(u.coding.system, '^http://hl7\.org/fhir/sid/icd-10-cm$')
    ), --noqa: LT07

    system_reasoncode_3 AS (
        SELECT DISTINCT
            s.id AS id,
            s.row,
            '3' AS priority,
            u.coding.code,
            u.coding.display,
            u.coding.system,
            u.coding.userSelected
        FROM
            flattened_rows AS s,
            UNNEST(s.reasoncode.coding) AS u (coding)
        WHERE
            REGEXP_LIKE(u.coding.system, '^http://hl7\.org/fhir/sid/icd-9-cm$')
    ), --noqa: LT07

    system_reasoncode_4 AS (
        SELECT DISTINCT
            s.id AS id,
            s.row,
            '4' AS priority,
            u.coding.code,
            u.coding.display,
            u.coding.system,
            u.coding.userSelected
        FROM
            flattened_rows AS s,
            UNNEST(s.reasoncode.coding) AS u (coding)
        WHERE
            REGEXP_LIKE(u.coding.system, '^https://fhir\.cerner\.com/.*/nomenclature$')
    ), --noqa: LT07

    system_reasoncode_5 AS (
        SELECT DISTINCT
            s.id AS id,
            s.row,
            '5' AS priority,
            u.coding.code,
            u.coding.display,
            u.coding.system,
            u.coding.userSelected
        FROM
            flattened_rows AS s,
            UNNEST(s.reasoncode.coding) AS u (coding)
        WHERE
            REGEXP_LIKE(u.coding.system, '^urn:oid:1\.2\.840\.114350\.1\.13\.71\.2\.7\.2\.728286$')
    ), --noqa: LT07

    union_table AS (
        SELECT
            id,
            row,
            priority,
            system,
            code,
            display,
            userSelected
        FROM system_reasoncode_0
        UNION
        SELECT
            id,
            row,
            priority,
            system,
            code,
            display,
            userSelected
        FROM system_reasoncode_1
        UNION
        SELECT
            id,
            row,
            priority,
            system,
            code,
            display,
            userSelected
        FROM system_reasoncode_2
        UNION
        SELECT
            id,
            row,
            priority,
            system,
            code,
            display,
            userSelected
        FROM system_reasoncode_3
        UNION
        SELECT
            id,
            row,
            priority,
            system,
            code,
            display,
            userSelected
        FROM system_reasoncode_4
        UNION
        SELECT
            id,
            row,
            priority,
            system,
            code,
            display,
            userSelected
        FROM system_reasoncode_5
        
    ),

    partitioned_table AS (
        SELECT
            id,
            row,
            code,
            system,
            display,
            userSelected,
            priority,
            ROW_NUMBER()
                OVER (
                    PARTITION BY id
                    ORDER BY priority ASC, code ASC
                ) AS available_priority
        FROM union_table
        GROUP BY
            id, row, priority, system, code, display, userSelected
    )

    SELECT
        id,
        row,
        code,
        system,
        display,
        userSelected
    FROM partitioned_table
    WHERE available_priority = 1
);


-- ###########################################################

CREATE TABLE core__encounter_dn_dischargedisposition AS (
    WITH

    system_dischargedisposition_0 AS (
        SELECT DISTINCT
            s.id AS id,
            0 AS row,
            u.coding.code,
            u.coding.display,
            u.coding.system,
            u.coding.userSelected
        FROM
            encounter AS s,
            UNNEST(s.hospitalization.dischargedisposition.coding) AS u (coding)
    ), --noqa: LT07

    union_table AS (
        SELECT
            id,
            row,
            system,
            code,
            display,
            userSelected
        FROM system_dischargedisposition_0
        
    )
    SELECT
        id,
        code,
        system,
        display,
        userSelected
    FROM union_table
);


-- ###########################################################


CREATE TABLE core__encounter AS
WITH

temp_encounter_completion AS (
    WITH
    -- Start by grabbing group names and exports times for each Encounter.
    temp_completion_times AS (
        SELECT
            ece.encounter_id,
            -- note that we don't chop the export time down to a DATE,
            -- as is typical in the core study
            min(from_iso8601_timestamp(ece.export_time)) AS earliest_export
        FROM etl__completion_encounters AS ece
        GROUP BY ece.encounter_id
    ),

    -- Then examine all tables that are at least as recently loaded as the
    -- Encounter. (This is meant to detect Conditions that maybe aren't
    -- loaded into Athena yet for the Encounter.)
    -- Make sure that we have all the tables we care about.
    temp_completed_tables AS (
        SELECT
            ece.encounter_id,
            (
                BOOL_OR(ec.table_name = 'allergyintolerance')
                AND BOOL_OR(ec.table_name = 'condition')
                AND BOOL_OR(ec.table_name = 'diagnosticreport')
                AND BOOL_OR(ec.table_name = 'documentreference')
                AND BOOL_OR(ec.table_name = 'medicationrequest')
                AND BOOL_OR(ec.table_name = 'observation')
            ) AS is_complete
        FROM etl__completion_encounters AS ece
        INNER JOIN temp_completion_times AS tct ON tct.encounter_id = ece.encounter_id
        INNER JOIN etl__completion AS ec ON ec.group_name = ece.group_name
        WHERE tct.earliest_export <= from_iso8601_timestamp(ec.export_time)
        GROUP BY ece.encounter_id
    )

    -- Left join back with main completion_encounters table,
    -- to catch rows that are completion-tracked but not in
    -- temp_completed_tables.
    SELECT
        ece.encounter_id AS id,
        (is_complete IS NOT NULL AND is_complete) AS is_complete
    FROM etl__completion_encounters AS ece
    LEFT JOIN temp_completed_tables AS tct ON tct.encounter_id = ece.encounter_id
),

temp_encounter_nullable AS (
    SELECT DISTINCT
        e.id,
        e.status,
        e.class.code AS class_code,
        e.class.system AS class_system,
        e.subject.reference AS subject_ref,
        date(from_iso8601_timestamp(e.period.start)) AS period_start,
        date_trunc('day', date(from_iso8601_timestamp(e."period"."end")))
            AS period_end_day,
        date_trunc('day', date(from_iso8601_timestamp(e."period"."start")))
            AS period_start_day,
        date_trunc('week', date(from_iso8601_timestamp(e."period"."start")))
            AS period_start_week,
        date_trunc('month', date(from_iso8601_timestamp(e."period"."start")))
            AS period_start_month,
        date_trunc('year', date(from_iso8601_timestamp(e."period"."start")))
            AS period_start_year
    FROM encounter AS e
    LEFT JOIN temp_encounter_completion AS tec ON tec.id = e.id
    WHERE (
        -- NULL completion just means it's a row that isn't completion-tracked
        -- (likely a legacy row), so allow it in.
        tec.is_complete IS NULL OR tec.is_complete
    )
),

temp_encounter AS (
    SELECT DISTINCT
        e.id,
        e.status,
        e.class_code,
        e.class_system,
        e.subject_ref,
        e.period_start,
        e.period_start_day,
        e.period_end_day,
        e.period_start_week,
        e.period_start_month,
        e.period_start_year,
        edt.code AS type_code,
        edt.system AS type_system,
        edt.display AS type_display,
        eds.code AS serviceType_code,
        eds.system AS serviceType_system,
        eds.display AS serviceType_display,
        edp.code AS priority_code,
        edp.system AS priority_system,
        edp.display AS priority_display,
        edr.code AS reasonCode_code,
        edr.system AS reasonCode_system,
        edr.display AS reasonCode_display,
        edd.code AS dischargeDisposition_code,
        edd.system AS dischargeDisposition_system,
        edd.display AS dischargeDisposition_display

    FROM temp_encounter_nullable AS e
    LEFT JOIN core__encounter_dn_type AS edt ON e.id = edt.id
    LEFT JOIN core__encounter_dn_servicetype AS eds ON e.id = eds.id
    LEFT JOIN core__encounter_dn_priority AS edp ON e.id = edp.id
    LEFT JOIN core__encounter_dn_reasoncode AS edr ON e.id = edr.id
    LEFT JOIN core__encounter_dn_dischargedisposition AS edd ON e.id = edd.id
)

SELECT DISTINCT
    e.id,
    e.status,
    ac.code AS class_code,
    ac.display AS class_display,
    e.type_code,
    e.type_system,
    e.type_display,
    e.serviceType_code,
    e.serviceType_system,
    e.serviceType_display,
    e.priority_code,
    e.priority_system,
    e.priority_display,
    e.reasonCode_code,
    e.reasonCode_system,
    e.reasonCode_display,
    e.dischargeDisposition_code,
    e.dischargeDisposition_system,
    e.dischargeDisposition_display,
    date_diff('year', date(p.birthdate), e.period_start_day) AS age_at_visit,
    p.gender,
    p.race_display,
    p.ethnicity_display,
    p.postalcode_3,
    e.period_start_day,
    coalesce(e.period_end_day, e.period_start_day) AS period_end_day,
    e.period_start_week AS period_start_week,
    e.period_start_month AS period_start_month,
    e.period_start_year AS period_start_year,
    e.subject_ref,
    concat('Encounter/', e.id) AS encounter_ref
FROM temp_encounter AS e
LEFT JOIN core__fhir_mapping_expected_act_encounter_code_v3 AS eac
    ON e.class_code = eac.found
LEFT JOIN core__fhir_act_encounter_code_v3 AS ac ON eac.expected = ac.code
INNER JOIN core__patient AS p ON e.subject_ref = p.subject_ref;

-- ###########################################################


CREATE TABLE core__incomplete_encounter AS
WITH
temp_encounter_completion AS (
    WITH
    -- Start by grabbing group names and exports times for each Encounter.
    temp_completion_times AS (
        SELECT
            ece.encounter_id,
            -- note that we don't chop the export time down to a DATE,
            -- as is typical in the core study
            min(from_iso8601_timestamp(ece.export_time)) AS earliest_export
        FROM etl__completion_encounters AS ece
        GROUP BY ece.encounter_id
    ),

    -- Then examine all tables that are at least as recently loaded as the
    -- Encounter. (This is meant to detect Conditions that maybe aren't
    -- loaded into Athena yet for the Encounter.)
    -- Make sure that we have all the tables we care about.
    temp_completed_tables AS (
        SELECT
            ece.encounter_id,
            (
                BOOL_OR(ec.table_name = 'allergyintolerance')
                AND BOOL_OR(ec.table_name = 'condition')
                AND BOOL_OR(ec.table_name = 'diagnosticreport')
                AND BOOL_OR(ec.table_name = 'documentreference')
                AND BOOL_OR(ec.table_name = 'medicationrequest')
                AND BOOL_OR(ec.table_name = 'observation')
            ) AS is_complete
        FROM etl__completion_encounters AS ece
        INNER JOIN temp_completion_times AS tct ON tct.encounter_id = ece.encounter_id
        INNER JOIN etl__completion AS ec ON ec.group_name = ece.group_name
        WHERE tct.earliest_export <= from_iso8601_timestamp(ec.export_time)
        GROUP BY ece.encounter_id
    )

    -- Left join back with main completion_encounters table,
    -- to catch rows that are completion-tracked but not in
    -- temp_completed_tables.
    SELECT
        ece.encounter_id AS id,
        (is_complete IS NOT NULL AND is_complete) AS is_complete
    FROM etl__completion_encounters AS ece
    LEFT JOIN temp_completed_tables AS tct ON tct.encounter_id = ece.encounter_id
)

SELECT DISTINCT tec.id
FROM temp_encounter_completion AS tec
WHERE NOT tec.is_complete
