# -*- coding: utf-8 -*-
"""Український текст для Level 1 A1 — «Бог створює світ».

Рівень 1 не має маркера `Q:` — завдання вплетені в текст історії й набрані
фірмовим кольором. Цитати — Турконяк (УБТ, 2020).
"""
import json
import os
import random

import fitz

TR = {}
POST = []
WIPES = []

HERE = os.path.dirname(os.path.abspath(__file__))
ORANGE = (0.957, 0.600, 0.267)       # #f49944 — фірмовий колір рівня 1
ROUND = '/System/Library/Fonts/SFNSRounded.ttf'
BOLD = '/System/Library/Fonts/Supplemental/Arial Bold.ttf'

with open(os.path.join(HERE, 'work', 'Level1_A1', 'template.json'),
          encoding='utf-8') as _fh:
    _TPL = json.load(_fh)
IDX = {f"p{p['page']}b{b['i']}": b for p in _TPL for b in p['blocks']}


def rows(key, *text_lines, s=0):
    TR[key] = {'lines': [[(t, s)] for t in text_lines]}


def one(key, text, s=0):
    TR[key] = {'lines': [[(text, s)]]}


def head(page, block, big=False, with_name=False):
    lines = []
    if with_name:
        lines.append([("Ім'я:", 0)])
    i = 1 if with_name else 0
    lines.append([('bible', i), ('time', i + 1)])
    if big:
        lines.append([('www.besweb.com', i + 2)])
        lines.append([('Рівень 1 — біблійні історії', i + 3)])
        lines.append([('A1', i + 4)])
    else:
        lines.append([('Рівень 1 — біблійні історії', i + 2)])
        lines.append([('A1', i + 3)])
    TR[f'p{page}b{block}'] = {'lines': lines}


# ═══════════════════════════════════════════════════════════ сторінка 1
# «level N» — білий текст на білому тлі, тобто невидимий (§1.3).
# І перекладати, і **стирати** його не можна: напис повернутий на 90°,
# тож його прямокутник — висока смуга вздовж правого краю, і редагування
# ковтає бокс балів, що стоїть усередині неї. Лишаємо блок недоторканим.
rows('p0b1', 'Впиши тут своє імʼя та адресу.', 'Вік:', "Ім'я:", 'Адреса:')
for _i, _t in ((1, 'Вік:'), (2, "Ім'я:"), (3, 'Адреса:')):
    TR['p0b1']['lines'][_i] = [(_t, 1)]
one('p0b2', 'Учитель:')
head(0, 3, big=True)
one('p0b4', 'Рівень 1')
TR['p0b5'] = {'lines': [
    [('B.E.S.', 0)], [('мудрий друг', 1)],
    [('Q', 0)], [('ставить', 1)], [('запитання', 1)]]}
TR['p0b6'] = {'right': 514.0, 'lines': [
    [('Pause', 0)], [('любить', 1)], [('подумати', 1)]]}
TR['p0b7'] = {'lines': [
    [('Beam', 0)], [('друг, який', 1)], [('підбадьорює', 1)]]}
one('p0b44', 'ІСТОРІЯ 1: Бог створює світ')
one('p0b45', 'Ця історія про те, як Бог створив небо і землю.')
TR['p0b47'] = {'lines': [
    [('ЧИТАЙ:', 0)], [('Буття 1: 1-19', 1)], [('Буття 2: 1-3', 1)]]}
one('p0b48', 'Біблія каже в Бутті 1: 1:')
TR['p0b49'] = {'drop': True}          # пунктирний вірш — малюється в POST
one('p0b50', "З'єднай крапки.")
one('p0b51', "Ось малюнок світу. Познач хрестиком, де ти живеш.")

# ═══════════════════════════════════════════════════════════ сторінка 2
one('p1b1', 'УСЬОГО:')
head(1, 2)
one('p1b3', 'Біблія каже, що Бог такий великий, що для створення світу Йому')
one('p1b4', 'досить було просто сказати! Бог сказав: «Нехай буде світло» — і стало світло!')
one('p1b5', 'Унизу намальовано дні творіння. Розфарбуй їх і домалюй')
one('p1b6', 'щось своє.')
for _b, _t in ((8, 'Світло і темрява'), (10, 'Небо')):
    one(f'p1b{_b}', _t)
rows('p1b12', 'Суша, моря', 'і рослини')
rows('p1b14', 'Сонце, місяць', 'і зорі')
one('p1b16', 'Риби і птахи')
rows('p1b18', 'Тварини', 'і люди')
rows('p1b19', 'Що Бог зробив сьомого дня?', 'Розфарбуй клітинки з крапкою — і дізнаєшся.')
TR['p1b20'] = {'drop': True}          # ряд клітинок — малюється в POST
rows('p1b23', 'Чи Бог стомлюється,', 'як ми? Тому', 'Він відпочив?')
rows('p1b24', 'Ні, Q. Біблія каже в', 'Ісаї 40: 28, що Бог не стомлюється', 'і не знемагає. Він спочив,',
     'бо праця була завершена.')
rows('p1b25', 'А нам відпочинок', 'потрібен, Q. Бог показує нам', 'добрий приклад!')

# ═══════════════════════════════════════════════════════════ сторінка 3
head(2, 1, with_name=True)
one('p2b2', 'ІСТОРІЯ 2: Бог створює тварин і людей')
one('p2b3', 'Ця історія про всіх різних істот, яких створив Бог.')
TR['p2b5'] = {'lines': [
    [('ЧИТАЙ:', 0)], [('Буття', 1)], [('1: 20 — 2: 3', 1)]]}
one('p2b6', 'Бог радів кожній частині світу, яку створив. Він сказав, що')
one('p2b7', 'усе, що Він створив, дуже добре!')
one('p2b8', 'Подивись на малюнок унизу. Спробуй знайти цих істот і')
one('p2b9', 'розфарбуй їх.')
rows('p2b10', 'жирафа — жовтим', 'метелика — червоним', 'жабку — зеленим')
rows('p2b11', 'лева — оранжевим', 'черепаху — бурим', 'пташку — синім')
one('p2b12', "Проведи лінію до того, що сказав Бог.")
one('p2b13', 'Це було погано.')
rows('p2b14', 'Бог сказав:', 'Це було дуже добре.')
one('p2b15', 'Це було зле.')

# ═══════════════════════════════════════════════════════════ сторінка 4
one('p3b1', 'УСЬОГО:')
head(3, 2)
one('p3b3', 'Біблія каже, що Бог створив багато різних')
one('p3b4', 'тварин. Він створив риб, що живуть у морі, птахів,')
one('p3b5', 'що літають у небі, диких звірів і навіть усіх комах,')
one('p3b6', 'що повзають по землі. Він створив усе!')
one('p3b7', 'Дехто любить тримати тварин удома. Чи є в тебе')
one('p3b8', 'улюбленець або хотів би ти його мати? Намалюй у рамці.')
one('p3b9', 'Найкращий улюбленець')
one('p3b10', 'Полічи, скільки істот у кожній групі, і впиши число в рамку.')
one('p3b12', 'Хоча Бог створив уже багато прекрасних істот, лишалося ще одне.')
one('p3b13', 'Це творіння було найособливіше. Він створив чоловіка й жінку.')
one('p3b14', 'Їх звали Адам і Єва.')
rows('p3b29', 'А павуків', 'теж треба було', 'створювати?!')

# ═══════════════════════════════════════════════════════════ сторінка 5
head(4, 1, with_name=True)
one('p4b2', 'ІСТОРІЯ 3: Перші чоловік і жінка')
one('p4b3', 'Ця історія про Адама і Єву.')
TR['p4b5'] = {'lines': [[('ЧИТАЙ:', 0)], [('Буття 2: 4-25', 1)]]}
one('p4b6', 'Як Бог створив людей? Біблія каже, що Він узяв порох із землі')
one('p4b7', 'і створив Адама. А з Адамового ребра створив Єву. Саме Бог')
one('p4b8', 'вдихнув у них життя. Як дивовижно! Адам і Єва жили в прекрасному')
one('p4b9', 'саду, що звався Едем.')
one('p4b10', 'Впиши пропущені слова, взявши правильні з хмаринок унизу.')
one('p4b11', 'Розфарбуй малюнок.')
one('p4b12', 'Адам')
one('p4b14', 'Єва')
one('p4b16', 'Сад')
one('p4b18', 'Едем')
one('p4b19', 'С __ __ Е __ __ __ .')
one('p4b20', 'Бог створив прекрасний світ і побачив, що це дуже добре.')
rows('p4b22', 'А __ __ __', 'Є __ __')

# ═══════════════════════════════════════════════════════════ сторінка 6
one('p5b1', 'УСЬОГО:')
head(5, 2)
one('p5b3', 'Біблія каже, що всі ми створені за Божим образом. Це відрізняє нас')
one('p5b4', 'від інших живих істот. Ми особливі!')
one('p5b5', 'Бог створив мене!')
one('p5b6', 'Намалюй себе в рамці.')
one('p5b7', 'Доповни речення.')
one('p5b8', 'Мені сумно, коли...')
one('p5b9', 'У мене добре виходить...')
one('p5b10', 'Я люблю...')
one('p5b11', 'Я радію, коли...')
rows('p5b12', 'Біблія каже, що ти — частина Божого творіння, і Він радіє тому,',
     'яким тебе створив.')
one('p5b14', 'Бог розуміє')
one('p5b15', 'мене.')
one('p5b16', 'Я особливий')
one('p5b17', 'для Бога.')
one('p5b18', 'Я створений за')
one('p5b19', 'Божим образом.')
one('p5b20', 'Ні в кого')
one('p5b21', 'немає таких')
one('p5b22', 'відбитків.')

# ═══════════════════════════════════════════════════════════ сторінка 7
head(6, 1, with_name=True)
one('p6b2', 'ІСТОРІЯ 4: Божий світ зіпсовано')
one('p6b3', 'Ця історія про те, як гріх увійшов у світ.')
TR['p6b5'] = {'lines': [[('ЧИТАЙ:', 0)], [('Буття 3: 1-24', 1)]]}
one('p6b6', 'Адам і Єва доглядали Едемський сад і дбали про всіх')
one('p6b7', 'тварин. Бог сказав їм, що вони можуть їсти плоди з кожного дерева')
one('p6b8', 'в саду, крім одного. Одного дня в сад прийшов Божий ворог, сатана.')
one('p6b9', 'Він був у подобі змія.')
one('p6b10', 'Напиши ТАК або НІ після кожного твердження.')
one('p6b11', 'Адам і Єва дбали про всіх тварин.')
one('p6b12', 'Адам і Єва могли їсти плоди з усіх дерев.')
one('p6b13', 'Сатана був у подобі змія.')
one('p6b14', 'Сатана був другом Богові.')
one('p6b15', 'Сатана сказав Єві, що коли вона зʼїсть плід із того одного дерева,')
one('p6b16', 'то стане мудрою, як Бог. Сатанина брехня змусила її забути про все')
one('p6b17', 'добре, що дав їй Бог! Єва вирішила не послухатися Бога. Вона взяла')
one('p6b18', 'плід, дала частину Адамові, і обоє зʼїли.')
one('p6b19', 'Впиши літери з крапкою в клітинки внизу — і дізнаєшся, що каже Біблія.')
one('p6b54', '__ __ __  __ __ __ __ __ __  __ __ __ __  __ __ __ __ __ .')

# ═══════════════════════════════════════════════════════════ сторінка 8
TR['p7b0'] = {'lines': [[('Бали', 0), (' (вписує вчитель)', 1)]]}
for _i in range(1, 5):
    one(f'p7b{_i}', f'ІСТОРІЯ {_i}:')
one('p7b5', 'Разом')
one('p7b6', 'Загалом')
rows('p7b7', 'Коментар учителя:', 'Надішли свої уроки на адресу:')
TR['p7b8'] = {'lines': [
    [('©', 0), (' Bible Educational Services. Відвідай ', 1), ('www.besweb.com', 2),
     (' або телефонуй +44 (0) 28 6632 2462.', 1)],
    [('Registered Charity UK CIO 1186004', 1)],
    [('РІВЕНЬ 1 A1', 3)],
    [('01/2025', 4)],
]}
one('p7b9', 'Бог вигнав Адама і Єву із саду. Їхній гріх зіпсував Боже')
one('p7b10', 'творіння і зруйнував їхню дружбу з Ним. Гріх псує і нашу дружбу')
one('p7b11', 'з Богом.')
one('p7b12', 'Але Бог відкрив шлях, щоб цю дружбу відновити. Він послав Свого')
one('p7b13', 'Сина, Ісуса, у світ, щоб Він помер на хресті. Біблія каже, що Ісус поніс')
one('p7b14', 'кару, на яку заслуговує наш гріх. Нам може бути прощено, коли ми')
one('p7b15', 'покладемося на Нього.')
one('p7b16', "Впиши пропущені літери й обведи слова по крапках.")
# Ребус: серце заміняє «полюбив», глобус — «світ», велика «1» — «єдиного».
# Слова у пропусках і два пунктирні слова лишаються завданням дитини.
JOHN_L1 = 'єди __ __ __ __ Сина, щоб кожний, хто '
JOHN_L2 = 'не загинув, але мав '
TR['p7b17'] = {'lines': [
    [('«Бо так', 0)],
    [('по __ __ __ __ Бог', 0)],
]}
one('p7b18', 'с __ __ т, що дав')
TR['p7b19'] = {'lines': [[('Свого', 0), ('1', 1)]]}
# Пунктирні слова малюються окремо (POST), тож у рядку вони місця не займають.
# Хвіст рядка доводиться зсувати явним x, інакше він наїде на слово.
_BOLD_F = fitz.Font(fontfile=BOLD)
_ROUND_F = fitz.Font(fontfile=ROUND)


def _after(x0, before, word, size=26.0, pad=8.0):
    return (x0 + _BOLD_F.text_length(before, fontsize=13)
            + _ROUND_F.text_length(word, fontsize=size) + pad)


# 140, а не 131: велика «1» (56 pt) заходить праворуч до x = 135.
TR['p7b20'] = {'lines': [[(JOHN_L1, 0, 140.0),
                          (' в Нього,', 0, _after(140.0, JOHN_L1, 'вірує'))]]}
TR['p7b21'] = {'lines': [[(JOHN_L2, 0),
                          ('».', 0, _after(127.0, JOHN_L2, 'вічне життя'))]]}
one('p7b22', 'Івана 3: 16')
one('p7b24', 'УСЬОГО:')
rows('p7b52', 'А що означає', 'вірити', 'в Нього?')
rows('p7b53', 'Це означає, Q, що ти', 'віриш: Ісус помер за твій', 'гріх, і ти попросив',
     'у Бога пробачення.')
rows('p7b54', 'Коли Бог прощає,', 'ви друзі назавжди!', 'Хіба це не', 'Добра звістка?')


# ═══════════════════════════════════════════════ головоломки
import fitz                                                   # noqa: E402
from puzzlekit import cover, dotted_text                      # noqa: E402

ALPHABET = 'АБВГДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЮЯ'

# ── пунктирний вірш, стор. 1 ─────────────────────────────────────────────
VERSE = ['«На початку Бог створив', 'небо і землю».']
VERSE_AT = [(62.0, 396.0), (81.0, 438.0)]
VERSE_SIZE = 35.0

# ── ряд клітинок із крапкою, стор. 2 ─────────────────────────────────────
# 13 клітинок, шість позначених складають відповідь.
ROW_ANSWER = 'СПОЧИВ'
ROW_AT = (120.2, 603.0)
ROW_CELL = 27.3
ROW_N = 13

# ── літери з крапкою 17×2, стор. 7 ───────────────────────────────────────
DOT_PHRASE = 'БОГПОСЛАВСИНАІСУСА'          # «Бог послав Сина Ісуса» — 18 літер
DOT_AT = (57.2, 645.3)
DOT_CELL = 27.3
DOT_PITCH = 27.34
DOT_COLS, DOT_ROWS = 17, 2

# ── пунктирні слова в Івана 3: 16, стор. 8 ───────────────────────────────
# x рахується від початку рядка плюс ширина тексту перед словом: український
# текст іншої довжини, тож жорсткі координати оригіналу не годяться.
JOHN_WORDS = [('вірує', 131.0, 343.0, 'JOHN_L1'),
              ('вічне життя', 127.0, 393.0, 'JOHN_L2')]
JOHN_SIZE = 26.0

COVERS = {
    0: [(58, 360, 538, 452)],                       # старий пунктирний вірш
    1: [(116, 598, 480, 634)],                      # ряд клітинок із крапкою
    6: [(54, 641, 525, 704)],                       # сітка 17×2
    7: [(280, 310, 500, 405)],                      # пунктирні слова Івана 3: 16
}


def apply_covers(page):
    rects = COVERS.get(page.number)
    if rects:
        cover(page, rects, WIPES)


def _dot_row(page, origin, cell, n, answer, colour, seed):
    """Ряд клітинок із літерами; позначені крапкою складають відповідь."""
    rnd = random.Random(seed)
    marked = sorted(rnd.sample(range(n), len(answer)))
    it = iter(answer)
    letters = [next(it) if i in marked else rnd.choice(ALPHABET) for i in range(n)]
    font = fitz.Font(fontfile=BOLD)
    ox, oy = origin
    for i, ch in enumerate(letters):
        x = ox + i * cell
        page.draw_rect(fitz.Rect(x, oy, x + cell, oy + cell), color=colour, width=0.9)
        w = font.text_length(ch, fontsize=13)
        page.insert_text((x + (cell - w) / 2, oy + cell * 0.70), ch,
                         fontname='uaB', fontsize=13, color=(0, 0, 0))
        if i in marked:
            page.draw_circle(fitz.Point(x + cell / 2, oy + cell * 0.86), 1.5,
                             color=None, fill=(0, 0, 0))
    return marked


def _draw_puzzles(doc, only=None):
    def want(p):
        return only is None or p in only

    if want(0):
        for line, at in zip(VERSE, VERSE_AT):
            dotted_text(doc[0], at, line, 'uaDot', ROUND, VERSE_SIZE)
    if want(1):
        page = doc[1]
        page.insert_font(fontname='uaB', fontfile=BOLD)
        _dot_row(page, ROW_AT, ROW_CELL, ROW_N, ROW_ANSWER, ORANGE, seed=5)
        print(f'  стор. 2: ряд клітинок — {len(ROW_ANSWER)} із {ROW_N}')
    if want(6):
        page = doc[6]
        page.insert_font(fontname='uaB', fontfile=BOLD)
        font = fitz.Font(fontfile=BOLD)
        n = DOT_COLS * DOT_ROWS
        rnd = random.Random(7)
        marked = sorted(rnd.sample(range(n), len(DOT_PHRASE)))
        it = iter(DOT_PHRASE)
        letters = [next(it) if i in marked else rnd.choice(ALPHABET) for i in range(n)]
        ox, oy = DOT_AT
        for i, ch in enumerate(letters):
            r, c = divmod(i, DOT_COLS)
            x, y = ox + c * DOT_PITCH, oy + r * DOT_PITCH
            page.draw_rect(fitz.Rect(x, y, x + DOT_CELL, y + DOT_CELL),
                           color=ORANGE, width=0.9)
            w = font.text_length(ch, fontsize=13)
            page.insert_text((x + (DOT_CELL - w) / 2, y + DOT_CELL * 0.70), ch,
                             fontname='uaB', fontsize=13, color=(0, 0, 0))
            if i in marked:
                page.draw_circle(fitz.Point(x + DOT_CELL / 2, y + DOT_CELL * 0.86),
                                 1.5, color=None, fill=(0, 0, 0))
        print(f'  стор. 7: клітинки з крапкою — {len(DOT_PHRASE)} із {n}')
    if want(7):
        lead = fitz.Font(fontfile=BOLD)
        for word, x0, y, src in JOHN_WORDS:
            before = globals()[src]
            x = x0 + lead.text_length(before, fontsize=13) + 4
            ok = dotted_text(doc[7], (x, y), word, 'uaDot', ROUND, JOHN_SIZE)
            if not ok:
                print(f'  !! пунктир не застосовано до {word!r}')


POST.append(_draw_puzzles)

# ── праві межі абзаців (§2.4, правило 1) ─────────────────────────────────
for _k, _v in TR.items():
    if 'flow' in _v and 'right' not in _v:
        _r = IDX[_k]['bbox'][2]
        if _r < 480:
            _v['right'] = _r + 2.0
