from patch.include import *
from tqdm import tqdm
from transliterate import translit


@app_context(commit=True)
def patch():
    with cmfutil.disable_acl(), cmfutil.disable_notify():
        print('Шаг 1: при наличии совпадающих префиксов, заменяем один из них')
        for project in tqdm(models.CmfProject.list(fields=['task_code_prefix'],
                                                   include_deleted=True)):
            if not project.task_code_prefix:
                continue
            i = 1
            old_prefix = project.task_code_prefix.value
            while models.CmfProject.sget(
                    filter=[['task_code_prefix', '=', project.task_code_prefix], ['id', '!=', project.id]]
            ):
                project.task_code_prefix = f'{old_prefix}{i}'
                i += 1
                project.save(only_data=True)
            print(f'Для проекта {project} сменили префикс на уникальный: {project.task_code_prefix}')
        commit_with_event()

        print('Шаг 2: выставляем обязательное поле task_code_prefix проектам, у которых оно не выставлено')
        for project in tqdm(models.CmfProject.list(filter=['task_code_prefix', '=', None],
                                                   fields=['name'],
                                                   include_deleted=True)):

            code = translit(project.name.value or 'TSK', language_code='ru', reversed=True)
            code_list = [c for c in re.findall(r'(?:\b|_)([A-Za-z0-9]{1,4})', code) if c][:4]
            if len(code_list) == 1:
                code = code_list[0][:4]
            else:
                code = ''.join(c[0] for c in code_list)
            code = code.upper()
            i = ''
            while models.CmfProject.sget(
                    filter=[['task_code_prefix', '=', f'{code}{i}'], ['id', '!=', project.id]]
            ):
                if not i:
                    i = 0
                i += 1
            project.task_code_prefix = f'{code}{i}'
            project.save(only_data=True)
            print(f'Для проекта {project.name} сгенерировали уникальный префикс: {project.task_code_prefix}')
        commit_with_event()

        print('Шаг 3: выявляем задачи с пересечением кодов и перегенерируем им код')
        for task in tqdm(models.CmfTask.list(fields=['code', 'name', 'root_parent'], filter=['root_parent', '!=', None],
                                             include_deleted=True)):
            if not isinstance(task.root_parent.value, models.CmfProject):
                continue
            code_numbers = task.code.value.split('-')[-1]
            if models.CmfTask.sget(filter=[['id', '!=', task.id], ['code', 'LIKE', f'%-{code_numbers}']], include_deleted=True):
                print(f'Сбрасываем код задаче: {task}')
                if not models.CmfTaskCodeHistory.sget(filter=['code', '=', task.code.value]):
                    code_history = models.CmfTaskCodeHistory(code=task.code.value, task=task,
                                                             project=task.root_parent)
                    code_history.save()
                task.code = None
                task._calc_code()
                task.save(only_data=True)
        commit_with_event()

        print('Шаг 4: пересчитываем префиксы у задач в проектах')
        for project in tqdm(models.CmfProject.list(include_deleted=True)):
            models.CmfTask._recalculate_codes(project.id)

if __name__ == "__main__":
    patch()
