import os

from maps.wikimap.stat.arm_dump_to_yt.dump import dump_to_yt
from maps.wikimap.stat.arm_dump_to_yt.logger import logger


def dump_actions(yt_client, db_engine, yt_path, complete_data_date):
    yt_table_schema = [
        {"name": "object_id", "type": "uint64", "required": True},
        {"name": "object_type", "type": "string", "required": True},
        {"name": "version", "type": "uint64", "required": True},
        {"name": "modified_at", "type": "uint64", "required": True},
        {"name": "operation_type", "type": "string", "required": True},
        {"name": "user_role", "type": "string", "required": True},
        {"name": "user_login", "type": "string", "required": True},
        {"name": "next_version_at", "type": "uint64", "required": False},
        {"name": "start_at", "type": "uint64", "required": False},
        {"name": "end_at", "type": "uint64", "required": False},

        {"name": "geometry", "type": "string", "required": False},
        {"name": "geometry_text", "type": "string", "required": False},
        {"name": "geometry_len_meters", "type": "double", "required": True},

        {"name": "modified_at_text", "type": "string", "required": True},
        {"name": "next_version_at_text", "type": "string", "required": False},
        {"name": "start_at_text", "type": "string", "required": False},
        {"name": "end_at_text", "type": "string", "required": False},
    ]

    query = """

    WITH version_for_dump AS (
        (
            SELECT
                closure_id AS object_id,
                'closure'::TEXT AS object_type,
                closure_version AS version,
                operation_type,
                modified_at,
                modified_by,
                start_time,
                end_time,
                geometry
            FROM arm2.closure_version
        )
        UNION ALL
        (
            SELECT
                closure_template_id AS object_id,
                'closure_template'::TEXT AS object_type,
                closure_template_version AS version,
                operation_type,
                modified_at,
                modified_by,
                NULL AS start_time,
                NULL AS end_time,
                geometry
            FROM arm2.closure_template_version
        )
    )
    SELECT
        v.object_id,
        v.object_type,
        v.version,
        v.operation_type,
        EXTRACT(EPOCH FROM v.modified_at)::BIGINT AS modified_at,
        v.modified_at::TEXT AS modified_at_text,
        EXTRACT(EPOCH FROM next_v.modified_at)::BIGINT AS next_version_at,
        next_v.modified_at::TEXT AS next_version_at_text,
        u.role AS user_role,
        u.login AS user_login,
        EXTRACT(EPOCH FROM v.start_time)::BIGINT AS start_at,
        v.start_time::TEXT AS start_at_text,
        EXTRACT(EPOCH FROM v.end_time)::BIGINT AS end_at,
        v.end_time::TEXT AS end_at_text,
        v.geometry as geometry,
        CASE WHEN v.geometry IS NOT NULL
            THEN ST_AsText(ST_Transform(v.geometry, 4326))
            ELSE ''
        END AS geometry_text,
        CASE WHEN v.geometry IS NOT NULL
            THEN ABS(ST_LENGTH(v.geometry)
                * COS(RADIANS(ST_Y(ST_POINTN(ST_TRANSFORM(v.geometry, 4326), 1)))))
            ELSE 0
        END AS geometry_len_meters
    FROM version_for_dump AS v
    JOIN arm2.user AS u ON (v.modified_by = u.uid)
    LEFT JOIN version_for_dump AS next_v
        ON (v.object_id, v.object_type, v.version + 1) = (next_v.object_id, next_v.object_type, next_v.version)
    """

    yt_table_name = os.path.join(
        yt_path,
        'actions_' + complete_data_date.strftime('%Y-%m-%d')
    )

    logger.info('Dumping actions')
    dump_to_yt(yt_client, db_engine, yt_table_name, query, yt_table_schema)
