-- 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__observation AS
WITH temp_observation AS (
    SELECT
        o.id,
        o.status,
        o.encounter.reference AS encounter_ref,
        o.subject.reference AS subject_ref,
        o.valueString,
        o.valueQuantity.value AS valueQuantity_value,
        o.valueQuantity.comparator AS valueQuantity_comparator,
        o.valueQuantity.unit AS valueQuantity_unit,
        o.valueQuantity.system AS valueQuantity_system,
        o.valueQuantity.code AS valueQuantity_code,
        date_trunc('day', cast(from_iso8601_timestamp(o."effectiveDateTime") AS date))
            AS effectiveDateTime_day,
        date_trunc('week', cast(from_iso8601_timestamp(o."effectiveDateTime") AS date))
            AS effectiveDateTime_week,
        date_trunc('month', cast(from_iso8601_timestamp(o."effectiveDateTime") AS date))
            AS effectiveDateTime_month,
        date_trunc('year', cast(from_iso8601_timestamp(o."effectiveDateTime") AS date))
            AS effectiveDateTime_year,
        odc.code AS observation_code,
        odc.system AS observation_system,
        odcat.code AS category_code,
        odcat.system AS category_system,
        odi.code AS interpretation_code,
        odi.system AS interpretation_system,
        odi.display AS interpretation_display,
        odvcc.code AS valueCodeableConcept_code,
        odvcc.system AS valueCodeableConcept_system,
        odvcc.display AS valueCodeableConcept_display,
        odda.code AS dataAbsentReason_code,
        odda.system AS dataAbsentReason_system,
        odda.display AS dataAbsentReason_display
    FROM observation AS o
    LEFT JOIN core__observation_dn_category AS odcat ON o.id = odcat.id
    LEFT JOIN core__observation_dn_code AS odc ON o.id = odc.id
    LEFT JOIN core__observation_dn_interpretation AS odi ON o.id = odi.id
    LEFT JOIN core__observation_dn_valuecodeableconcept AS odvcc ON o.id = odvcc.id
    LEFT JOIN core__observation_dn_dataabsentreason AS odda ON o.id = odda.id
)

SELECT
    id,
    category_code,
    category_system,
    status,
    observation_code,
    observation_system,
    interpretation_code,
    interpretation_system,
    interpretation_display,
    effectiveDateTime_day,
    effectiveDateTime_week,
    effectiveDateTime_month,
    effectiveDateTime_year,
    valueCodeableConcept_code,
    valueCodeableConcept_system,
    valueCodeableConcept_display,
    valueQuantity_value,
    valueQuantity_comparator,
    valueQuantity_unit,
    valueQuantity_system,
    valueQuantity_code,
    valueString,
    dataAbsentReason_code,
    dataAbsentReason_system,
    dataAbsentReason_display,
    subject_ref,
    encounter_ref,
    concat('Observation/', id) AS observation_ref
FROM temp_observation;

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




CREATE TABLE core__observation_component_valuequantity AS (
    WITH

    flattened_rows AS (
        WITH
        data_and_row_num AS (
            SELECT
                t.id AS id,
                generate_subscripts(t."component", 1) AS row,
                UNNEST(t."component") AS "component" -- must unnest in SELECT here
            FROM observation AS t
        )
        SELECT
            id,
            row,
            "component"
        FROM data_and_row_num
    ),

    flattened_quantities AS (
        SELECT
            f.id,
            f.row,
        f.component.valueQuantity.value AS value,
        cast(NULL as varchar) AS comparator,
        f.component.valueQuantity.unit AS unit,
        f.component.valueQuantity.system AS system,
        f.component.valueQuantity.code AS code
        FROM flattened_rows AS f
        WHERE f.component.valueQuantity IS NOT NULL
    )

    SELECT
        f.id,
        f.row,
        -- We ensure value is a double, because nullable_cols() above will cast
        -- as varchar if value isn't in the schema.
        CAST(f.value AS DOUBLE) AS value, -- noqa: disable=L029
        f.comparator,
        f.unit,
        f.system,
        f.code
    FROM flattened_quantities AS f
);
