namespace TeleWave.Application.Programming.Templates.Transfer;

/// <summary>
/// Постоянная часть запроса к ИИ: задача, правила и схема ответа. Схема описывает ровно то, что
/// читает <see cref="ImportGridCommandHandler"/>, — держать её рядом с форматом, а не в шаблоне
/// на фронте, значит не разойтись с импортом при первой же правке полей.
/// </summary>
public static class GridPromptText
{
    public const string Task = """
        Ты — программный директор телеканала. Собери недельную сетку вещания и верни её одним
        JSON-документом описанного ниже формата.
        """;

    public const string Rules = """
        Правила, по которым сетку потом разложит планировщик:

        - Сутки вещательные, а не календарные: они начинаются со времени dayStart и заканчиваются
          им же следующего дня. Ночь после полуночи принадлежит предыдущему дню.
        - Слот — это место в сетке, а не конкретная серия: что именно выйдет, выберет планировщик
          из указанной группы. Поэтому группа задаётся именем.
        - Группы можно собирать самому: перечисли их в разделе groups, набрав из шоу библиотеки —
          «Вечерние сериалы», «Детское утро», «Кино 90-х». Тех, что уже есть в списке доступных
          групп, заводить заново не надо: имя оттуда просто ставится в слот. Группы с новым именем
          будут созданы при загрузке файла.
        - Коллекция — это цикл или франшиза («Терминатор», «Пираты Карибского моря»); собирается
          в разделе collections и потом целиком кладётся в группу. Нужна там, где в слот идёт серия
          фильмов, а не отдельное кино.
        - Названия шоу в группах и коллекциях обязаны дословно совпадать с библиотекой ниже. Шоу
          импорт не создаёт: их приносит загрузка медиа, и придуманного названия в эфире не будет.
        - Стыки и заставки придумывать нельзя — только имена из списков ниже.
        - Группы типа «ролик» — это реклама и джинглы для стыков. Ни в слот, ни в fallbackGroup их
          ставить нельзя: в эфир уйдёт полоса роликов, подписанная как программа. Рекламы в списке
          библиотеки нет по той же причине — собирать группы из неё не нужно.
        - Слоты внутри одного слоя не пересекаются. Слоты разных слоёв пересекаться могут: слой
          с большим priority перекрывает меньший (например «Выходные» поверх «Основной сетки»).
        - weekday: 0=воскресенье .. 6=суббота, либо null — слот идёт каждый день. Предпочитай
          «каждый день» там, где содержание не меняется: сетка должна читаться.
        - Полосы суток должны покрывать их целиком, без дыр: незакрытое время в эфире займёт
          аварийный фон, и это видно зрителю.
        - Длина слота — из длительности контента группы, округлённая до четверти часа: программа
          передач состоит из круглых времён, а разницу занимает рекламный шов.
        - isAnchor=true ставится там, где время объявлено зрителю (начало прайма). Не ставь якорь
          на каждый слот подряд.
        - kind: "Content" — обычный слот с группой; "Repeat" — повтор прошлого эфира (нужен блок
          repeat: daysAgo, time, durationMinutes); "SignOff" — конец вещания.
        - blockMode: "Count" — blockValue единиц подряд (серий, фильмов); "FillSlot" — сколько
          влезет; "Duration" — blockValue минут.
        - strategy.type: "Sequential" — по порядку (для сериалов), "Random" или
          "RandomWithCooldown" с cooldownDays — для фильмов и разнобоя.
        - Рейтинг соблюдай: строгое (R, Nc17) — только в ночных полосах, детское — утром и днём.
        """;

    public const string Schema = """
        Схема ответа (комментарии — пояснения, в JSON их быть не должно):

        {
          "format": "telewave.grid",
          "version": 1,
          "rules": {                          // необязательный блок правил канала
            "maxGenreSharePercent": 40,
            "maxBreakMinutesPerHour": 12
          },
          "fallbackGroup": "имя группы",      // чем закрывать паузы
          "defaultJunction": "имя стыка",     // стык между блоками по умолчанию
          "collections": [                    // необязательно: циклы и франшизы из шоу
            { "name": "Терминатор", "shows": ["Терминатор", "Терминатор 2"] }
          ],
          "groups": [                         // необязательно: группы, которых ещё нет
            {
              "name": "Вечерние сериалы",
              "shows": ["Симпсоны", "Футурама"],   // названия дословно из библиотеки
              "collections": ["Терминатор"],       // целиком, если нужен весь цикл
              "description": "чем канал занимает прайм"
            }
          ],
          "layers": [
            {
              "name": "Основная сетка",
              "priority": 10,
              "isEnabled": true,
              "applicability": {              // необязательно: когда слой действует
                "annualRanges": [{ "fromMonth": 12, "fromDay": 25, "toMonth": 1, "toDay": 8 }]
              },
              "slots": [
                {
                  "title": "Утренние мультфильмы",
                  "start": "06:00",
                  "durationMinutes": 120,
                  "daypart": "Morning",        // Morning | Day | Prime | Night
                  "kind": "Content",           // Content | Repeat | SignOff
                  "weekday": null,             // 0..6 либо null
                  "group": "Мультфильмы",      // точное имя из списка доступных
                  "blockMode": "Count",        // Count | FillSlot | Duration
                  "blockValue": 4,
                  "strategy": { "type": "Sequential", "restartOnEnd": true },
                  "isAnchor": false,
                  "snapToMinutes": 15,
                  "junctionAfter": "имя стыка" // необязательно
                }
              ]
            }
          ]
        }
        """;

    public const string Answer = """
        Верни только JSON, без пояснений вокруг него и без markdown-ограждения. Этот файл будет
        загружен кнопкой импорта как есть.
        """;
}
