from patch.include import *
from tqdm import tqdm
from sqlalchemy import func


@app_context(commit=True)
def fix_same_gantt_task():
    """
    Для тестирования патча: ( cd /opt/eva-app; python3 -m patch.202410170728_fix_same_gantt_task )
    Здесь можно работать с моделями через models.CmfTask и т.д.
    Для прогрессбара используйте:
    for task in tqdm(models.CmfTask.list()):
        ...
    """
    print('Запуск патча fix_same_gantt_task')

    dp_task = models.CmfTask.dp_model
    session = models.CmfTask.dp.data_driver.Session()

    # Считаем сколько CmfTask с одинаковым op_gantt_task
    task_count_subquery = session.query(
        dp_task.op_gantt_task_id,
        func.count(dp_task.id).label('task_count')
    ).group_by(dp_task.op_gantt_task_id).subquery()

    # Запрашиваем и группируем id CmfTask с одним op_gantt_task
    grouped_task_ids = session.query(
        dp_task.op_gantt_task_id,
        func.array_agg(dp_task.id).label('task_ids')
    ).join(
        task_count_subquery, task_count_subquery.c.op_gantt_task_id == dp_task.op_gantt_task_id
    ).filter(task_count_subquery.c.task_count > 1).group_by(dp_task.op_gantt_task_id).all()


    for _op_gantt_task, task_ids in grouped_task_ids:
        first_task = models.CmfTask.get(filter=['id', 'IN', task_ids], order_by=['cmf_created_at'], include_deleted=True, include_system=True, include_archived=True)
        orig_gantt_task = first_task.op_gantt_task.load(fields=['**'])

        for task_id in task_ids:
            if task_id == first_task.id.value:
                continue

            task = models.CmfTask.get(id=task_id, fields=['op_gantt_task', 'parent_task'], include_deleted=True, include_system=True, include_archived=True)

            cloned_gantt_task = orig_gantt_task.clone()
            cloned_gantt_task.task = task
            cloned_gantt_task.parent_task = task.parent_task
            cloned_gantt_task.save(only_data=True, emit=False, notify=False)

            task.op_gantt_task = cloned_gantt_task
            task.save(only_data=True, emit=False, notify=False)

if __name__ == "__main__":
    fix_same_gantt_task()

