import json

from patch.include import *
from tqdm import tqdm


def convert_operator(operator):
    if operator in ('LIKE', 'ILIKE'):
        return '~'
    elif operator in ('NOT LIKE', 'NOT ILIKE'):
        return '!~'
    elif operator in ('MEMBER_OF'):
        return 'in'
    elif operator == '==':
        return '='
    else:
        return operator.lower()


def convert_bql(bql, depth=0):
    if not isinstance(bql, list):
        return None

    if len(bql) == 3 and isinstance(bql[0], str) and not bql[0] in ('OR', 'AND'):
        field = 'project' if bql[0] == 'parent' else bql[0]
        operator = bql[1]
        value = bql[2]

        if operator == 'EXISTS':
            return None

        operator = convert_operator(operator)

        if isinstance(value, list):
            values = ', '.join(f'"{v}"' for v in value)
            value = f'({values})'
        elif isinstance(value, str):
            value = value.replace('now()', '')
            value = f'"{value.strip()}"'

        return f'{field} {operator} {value}'

    queryset = []
    operator = 'and'
    for item in bql:
        if item in ('OR', 'AND'):
            operator = item.lower()
            continue
        else:
            jql = convert_bql(item, depth + 1)
            if jql:
                queryset.append(jql)
    query = f' {operator} '.join(queryset)
    if query:
        return f'({query})' if depth > 0 else query

@app_context(commit=True)
def fitlers_from_gantt_to_gantt_2():
    """
    Для тестирования патча: ( cd /opt/eva-app; python3 -m patch.202403051344_fitlers_from_gantt_to_gantt_2 )
    Здесь можно работать с моделями через models.CmfTask и т.д.
    Для прогрессбара используйте:
    for task in tqdm(models.CmfTask.list()):
        ...
    """
    print('Запуск патча fitlers_from_gantt_to_gantt_2')
    step = 100
    i = 0
    _fields = ['tmp_filter', 'tmp_filter.bql']
    roadmaps = models.CmfRoadmap.list(slice=[i, i + step], fields=_fields)
    while roadmaps:
        for roadmap in roadmaps:
            if roadmap.tmp_filter:
                task_filter = roadmap.tmp_filter
                if task_filter.bql != '[]':
                    try:
                        bql = json.loads(str(task_filter.bql))
                        task_filter.ubql2 = convert_bql(bql).replace('responsible = None', 'responsible = empty')
                        task_filter.parent = roadmap
                        task_filter.save(only_data=True, emit=False, notify=False)
                    except:
                        print(f'Не удалось конвертировать bql в ubql2. Некорректные данные в bql: "{task_filter.bql}"')
        commit_all_ds()
        i += step
        roadmaps = models.CmfRoadmap.list(slice=[i, i + step], fields=_fields)

if __name__ == "__main__":
    fitlers_from_gantt_to_gantt_2()
