from __future__ import annotations

import logging
from datetime import datetime, timedelta

from airflow.operators.python import PythonOperator
from helpers.greenplum import (
    assert_orders_have_rows,
    assert_orders_no_duplicates,
    assert_orders_schema,
    assert_orders_table_exists,
    get_gp_conn,
)

from airflow import DAG


def _run_check(check_callable):
    """
    Оборачивает проверку качества данных в контекст подключения к Greenplum.

    Этот DAG предназначен для автоматической проверки качества данных
    после CSV-пайплайна в таблице public.orders:
    1. Проверяет существование таблицы
    2. Проверяет соответствие схемы
    3. Проверяет наличие данных
    4. Проверяет отсутствие дубликатов

    Args:
        check_callable: Функция проверки, принимающая подключение к БД
    """
    # Получаем имя функции для логов
    check_name = check_callable.__name__.replace("assert_", "")
    logging.info("🚀 Запуск проверки: %s", check_name)

    with get_gp_conn() as conn:
        check_callable(conn)

    logging.info("✅ Проверка пройдена: %s", check_name)


def _log_dq_summary():
    """
    Логирует итоговую сводку по качеству данных.
    Эта задача выполняется после всех проверок и показывает общий результат.
    """
    logging.info("🎉 Все проверки качества данных пройдены успешно!")
    logging.info("📊 Качество данных в таблице orders соответствует требованиям.")


default_args = {"owner": "airflow", "retries": 1, "retry_delay": timedelta(seconds=30)}

with DAG(
    dag_id="csv_to_greenplum_dq",
    start_date=datetime(2024, 1, 1),
    schedule=None,
    catchup=False,
    default_args=default_args,
    tags=["demo", "greenplum", "quality", "csv", "dq"],
    description="Проверки качества данных после CSV → public.orders в Greenplum",
) as dag:
    # Задача 1: Проверка существования таблицы
    check_exists = PythonOperator(
        task_id="check_orders_table_exists",
        python_callable=_run_check,
        op_args=[assert_orders_table_exists],
    )

    # Задача 2: Проверка соответствия схемы таблицы
    check_schema = PythonOperator(
        task_id="check_orders_schema",
        python_callable=_run_check,
        op_args=[assert_orders_schema],
    )

    # Задача 3: Проверка наличия данных
    check_has_rows = PythonOperator(
        task_id="check_orders_has_rows",
        python_callable=_run_check,
        op_args=[assert_orders_have_rows],
    )

    # Задача 4: Проверка отсутствия дубликатов
    check_no_duplicates = PythonOperator(
        task_id="check_order_duplicates",
        python_callable=_run_check,
        op_args=[assert_orders_no_duplicates],
    )

    # Задача 5: Итоговая сводка
    dq_summary = PythonOperator(
        task_id="data_quality_summary",
        python_callable=_log_dq_summary,
    )

    # Определяем последовательность выполнения задач
    check_exists >> check_schema >> check_has_rows >> check_no_duplicates >> dq_summary
