# flake8: noqa
from langchain_core.prompts import PromptTemplate

SONG_DATA_SOURCE = """\
```json
{{
    "content": "Текст песни",
    "attributes": {{
        "artist": {{
            "type": "string",
            "description": "Имя исполнителя песни"
        }},
        "length": {{
            "type": "integer",
            "description": "Длительность песни в секундах"
        }},
        "genre": {{
            "type": "string",
            "description": "Жанр песни, один из \"pop\", \"rock\" или \"rap\""
        }}
    }}
}}
```\
"""

FULL_ANSWER = """\
```json
{{
    "query": "teenager love",
    "filter": "and(or(eq(\\"artist\\", \\"Taylor Swift\\"), eq(\\"artist\\", \\"Katy Perry\\")), lt(\\"length\\", 180), eq(\\"genre\\", \\"pop\\"))"
}}
```\
"""

NO_FILTER_ANSWER = """\
```json
{{
    "query": "",
    "filter": "NO_FILTER"
}}
```\
"""

WITH_LIMIT_ANSWER = """\
```json
{{
    "query": "love",
    "filter": "NO_FILTER",
    "limit": 2
}}
```\
"""

DEFAULT_EXAMPLES = [
    {
        "i": 1,
        "data_source": SONG_DATA_SOURCE,
        "user_query": "Какие песни Тейлор Свифт или Кэти Перри о подростковой любви длительностью менее 3 минут в жанре поп?",
        "structured_request": FULL_ANSWER,
    },
    {
        "i": 2,
        "data_source": SONG_DATA_SOURCE,
        "user_query": "Какие песни не были опубликованы на Spotify",
        "structured_request": NO_FILTER_ANSWER,
    },
]

EXAMPLES_WITH_LIMIT = [
    {
        "i": 1,
        "data_source": SONG_DATA_SOURCE,
        "user_query": "Какие песни Тейлор Свифт или Кэти Перри о подростковой любви длительностью менее 3 минут в жанре поп?",
        "structured_request": FULL_ANSWER,
    },
    {
        "i": 2,
        "data_source": SONG_DATA_SOURCE,
        "user_query": "Какие песни не были опубликованы на Spotify",
        "structured_request": NO_FILTER_ANSWER,
    },
    {
        "i": 3,
        "data_source": SONG_DATA_SOURCE,
        "user_query": "Какие три песни о любви",
        "structured_request": WITH_LIMIT_ANSWER,
    },
]

EXAMPLE_PROMPT_TEMPLATE = """\
<< Пример {i}. >>
Источник данных:
{data_source}

Запрос пользователя:
{user_query}

Структурированный запрос:
{structured_request}
"""

EXAMPLE_PROMPT = PromptTemplate.from_template(EXAMPLE_PROMPT_TEMPLATE)

USER_SPECIFIED_EXAMPLE_PROMPT = PromptTemplate.from_template(
    """\
<< Example {i}. >>
User Query:
{user_query}

Structured Request:
```json
{structured_request}
```
"""
)

DEFAULT_SCHEMA = """\
<< Схема структурированного запроса >>
При ответе используйте фрагмент кода markdown с объектом JSON, отформатированным по следующей схеме:

```json
{{{{
    "query": string \\ текстовая строка для сравнения с содержимым документа
    "filter": string \\ логическое условие для фильтрации документов
}}}}
```

Строка запроса должна содержать только текст, который ожидается в содержимом документов. Любые условия в фильтре не должны упоминаться в запросе.

Логическое условие состоит из одного или нескольких операторов сравнения и логических операций.

Оператор сравнения имеет форму: `comp(attr, val)`:
- `comp` ({allowed_comparators}): оператор сравнения
- `attr` (string):  имя атрибута, к которому применяется сравнение
- `val` (string): значение для сравнения

Логическая операция имеет форму `op(statement1, statement2, ...)`:
- `op` ({allowed_operators}): логический оператор
- `statement1`, `statement2`, ... (операторы сравнения или логические операции): одно или несколько утверждений, к которым применяется операция

Убедитесь, что вы используете только перечисленные выше операторы сравнения и логические операторы и никакие другие.
Убедитесь, что фильтры относятся только к атрибутам, которые существуют в источнике данных.
Убедитесь, что фильтры используют только имена атрибутов с их именами функций, если на них применяются функции.
Убедитесь, что фильтры используют только формат `YYYY-MM-DD` при обработке значений типа данных временной метки.
Убедитесь, что фильтры учитывают описания атрибутов и делают только те сравнения, которые возможны с учетом типа хранимых данных.
Убедитесь, что фильтры используются только по мере необходимости. Если нет фильтров, которые следует применить, верните "NO_FILTER" для значения фильтра.\
"""
DEFAULT_SCHEMA_PROMPT = PromptTemplate.from_template(DEFAULT_SCHEMA)

SCHEMA_WITH_LIMIT = """\
<< Схема структурированного запроса >>
При ответе используйте фрагмент кода markdown с объектом JSON, отформатированным по следующей схеме:

```json
{{{{
    "query": string \\ текстовая строка для сравнения с содержимым документа
    "filter": string \\ логическое условие для фильтрации документов
    "limit": int \\ количество документов для извлечения
}}}}
```

Строка запроса должна содержать только текст, который ожидается в содержимом документов. Любые условия в фильтре не должны упоминаться в запросе.

Логическое условие состоит из одного или нескольких операторов сравнения и логических операций.

Оператор сравнения имеет форму: `comp(attr, val)`:
- `comp` ({allowed_comparators}): оператор сравнения
- `attr` (string):  имя атрибута, к которому применяется сравнение
- `val` (string): значение для сравнения

Логическая операция имеет форму `op(statement1, statement2, ...)`:
- `op` ({allowed_operators}): логический оператор
- `statement1`, `statement2`, ... (операторы сравнения или логические операции): одно или несколько утверждений, к которым применяется операция

Убедитесь, что вы используете только перечисленные выше операторы сравнения и логические операторы и никакие другие.
Убедитесь, что фильтры относятся только к атрибутам, которые существуют в источнике данных.
Убедитесь, что фильтры используют только имена атрибутов с их именами функций, если на них применяются функции.
Убедитесь, что фильтры используют только формат `YYYY-MM-DD` при обработке значений типа данных временной метки.
Убедитесь, что фильтры учитывают описания атрибутов и делают только те сравнения, которые возможны с учетом типа хранимых данных.
Убедитесь, что фильтры используются только по мере необходимости. Если нет фильтров, которые следует применить, верните "NO_FILTER" для значения фильтра.
Убедитесь, что `limit` всегда является целым числом. Это необязательный параметр, поэтому оставьте его пустым, если он не имеет смысла.
"""
SCHEMA_WITH_LIMIT_PROMPT = PromptTemplate.from_template(SCHEMA_WITH_LIMIT)

DEFAULT_PREFIX = """\
Твоя задача - структурировать запрос пользователя, чтобы он соответствовал схеме запроса, представленной ниже.

{schema}\
"""

PREFIX_WITH_DATA_SOURCE = (
    DEFAULT_PREFIX
    + """

<< Data Source >>
```json
{{{{
    "content": "{content}",
    "attributes": {attributes}
}}}}
```
"""
)

DEFAULT_SUFFIX = """\
<< Пример {i}. >>
Источник данных:
```json
{{{{
    "content": "{content}",
    "attributes": {attributes}
}}}}
```

Запрос пользователя:
{{query}}

Структурированный запрос:
"""

SUFFIX_WITHOUT_DATA_SOURCE = """\
<< Пример {i}. >>
Запрос пользователя:
{{query}}

Структурированный запрос:
"""
