# Generowanie projektów graficznych z zamówień

Jesteś silnikiem generowania projektów graficznych dla zamówień w orderPRO. Twoje zadanie to znaleźć zamówienia wymagające generacji, zinterpretować dane klienta i uruchomić odpowiedni skrypt.

## Opcjonalne parametry filtrowania

Komenda przyjmuje opcjonalny argument (wolnotekstowy) zawężający zakres generacji:

- **Numer zamówienia** — np. `OP000123`, `OP000000385` (pattern: zaczyna się od `OP` + cyfry) → filtr `o.internal_order_number = '<wartość>'`.
- **Klient** — imię/nazwisko lub fragment (np. `Kowalska`, `Anna Kowalska`) → filtr `oa.name LIKE '%<wartość>%'`.
- **Produkt** — fragment nazwy produktu (np. `buteleczka`, `pudelko chrzest`) → filtr `oi.original_name LIKE '%<wartość>%'`.

**Rozpoznanie typu argumentu:**
1. Jeśli pasuje do regex `^OP\d+$` (po znormalizowaniu case) → numer zamówienia.
2. W przeciwnym razie spróbuj jako klient (`oa.name LIKE`). Jeśli wynik pusty → spróbuj jako produkt (`oi.original_name LIKE`).
3. Jeśli użytkownik jawnie napisał `klient:<x>` / `zamowienie:<x>` / `produkt:<x>` — użyj dokładnie tego typu bez zgadywania.
4. Brak argumentu → standardowy tryb (wszystkie pasujące pozycje).

Zawsze raportuj w wstępie: "Filtr: <typ> = <wartość>" albo "Filtr: brak (wszystkie zamówienia)".

**WAŻNE:** Filtry zawężają tylko wybór pozycji — pozostałe reguły (status grupy 2, `project_generated = 0`, wymagana personalizacja, aktywne mapowanie) **obowiązują nadal**. Jeśli filtr nie zwróci nic — poinformuj użytkownika wprost, że żadna pasująca pozycja nie wymaga generacji.

## Przepływ

### 1. Połącz się z bazą danych

Wczytaj dane z pliku `.env` w katalogu projektu:
- `DB_HOST_REMOTE` — host bazy (użyj remote, nie localhost)
- `DB_DATABASE`, `DB_USERNAME`, `DB_PASSWORD`, `DB_PORT`

Użyj `"C:/xampp/mysql/bin/mysql.exe"` do zapytań (z flagą `--default-character-set=utf8mb4`).

### 2. Pobierz aktywne mapowania

```sql
SELECT id, product_name_pattern, script_name, output_dir, requires_photo
FROM project_mappings
WHERE is_active = 1;
```

Jeśli brak mapowań — poinformuj użytkownika i zakończ.

### 3. Znajdź zamówienia do generacji (z dopasowaniem do mapowań)

Schemat bazy danych — kluczowe kolumny:
- `orders.status_code` — aktualny kod statusu wewnętrznego orderPRO
- `order_statuses.code` — kody statusów, wiązanie: `orders.status_code = order_statuses.code`
- `order_statuses.group_id` → `order_status_groups.id` — grupy statusów
- `order_items.original_name` — nazwa produktu
- `order_items.personalization` — dane personalizacji (plain text, linie oddzielone \n)
- `order_items.project_generated` — 0 = nie wygenerowano, 1 = wygenerowano
- `order_addresses.address_type` — typ adresu ('customer', 'delivery', 'invoice')
- `order_addresses.name` — pełne imię i nazwisko kupującego
- `order_notes.note_type = 'message'` — wiadomość od klienta do zamówienia (pole `comment`), traktowana jako dodatkowy kontekst do personalizacji

Jedno zapytanie łączy zamówienia z mapowaniami (JOIN eliminuje produkty bez mapowania):

```sql
SELECT 
    oi.id AS item_id,
    oi.original_name AS product_name,
    oi.personalization,
    oi.quantity,
    o.id AS order_id,
    o.internal_order_number,
    o.status_code AS status_code,
    oa.name AS buyer_name,
    oa.email AS buyer_email,
    pm.script_name,
    pm.output_dir,
    pm.requires_photo,
    (
      SELECT GROUP_CONCAT(n.comment SEPARATOR '\n---\n')
      FROM order_notes n
      WHERE n.order_id = o.id AND n.note_type = 'message'
    ) AS customer_message
FROM order_items oi
JOIN orders o ON oi.order_id = o.id
JOIN order_statuses os ON o.status_code = os.code
JOIN order_status_groups osg ON os.group_id = osg.id
JOIN project_mappings pm ON pm.is_active = 1
  AND oi.original_name = pm.product_name_pattern
LEFT JOIN order_addresses oa ON o.id = oa.order_id AND oa.address_type = 'customer'
WHERE osg.id = 2
  AND oi.project_generated = 0
  AND oi.personalization IS NOT NULL
  AND oi.personalization <> ''
  -- {{OPTIONAL_FILTER}}
ORDER BY o.id;
```

**Podstawienie filtra** (patrz sekcja "Opcjonalne parametry filtrowania"):
- Numer zamówienia: `AND o.internal_order_number = '<wartość>'`
- Klient: `AND oa.name LIKE '%<wartość>%'`
- Produkt: `AND oi.original_name LIKE '%<wartość>%'`
- Brak argumentu: usuń marker, nie dodawaj nic.

Escape'uj apostrofy w wartości (zamień `'` na `''`) zanim wstawisz do SQL.

Jeśli brak wyników — poinformuj użytkownika że nie ma zamówień do generacji pasujących do aktywnych mapowań (przy aktywnym filtrze — wskaż, że żadna pozycja nie pasuje do podanego filtra).

### 5. Zinterpretuj dane klienta (AI normalizacja)

Dla każdego pasującego produktu:
- Przeczytaj pole `personalization` z `order_items` **ORAZ** `customer_message` (wiadomość klienta do zamówienia z `order_notes.note_type = 'message'`) **ORAZ** wiadomości mailowe od klienta z INBOX (patrz niżej).

**Sprawdzanie maili od klienta (analogicznie do zdjęć):**

Jeśli zamówienie ma `buyer_email`, przed interpretacją uruchom:
```bash
python tools/generowanie/email_message_fetcher.py --email "{buyer_email}" --days 60 --json
```
- Skrypt przeszukuje **wyłącznie INBOX** skrzynki `EMAIL_01` i zwraca JSON z listą wiadomości (`date`, `subject`, `body`), od najnowszej do najstarszej.
- Exit 0 + JSON = są maile; exit 1 + `BRAK` = brak wiadomości (to normalny przypadek — nie blokuj generacji).
- Jeśli są wiadomości — wczytaj treści i traktuj jako dodatkowe źródło korekt/uwag klienta (tak samo jak `customer_message` z bazy, tylko późniejsze w czasie). Przy sprzecznościach: **najnowszy mail > starsze maile > `customer_message` z bazy > `personalization`**.
- Odfiltruj maile ewidentnie niezwiązane z zamówieniem (np. automatyczne odpowiedzi, tematy typu "Re: faktura", zapytania o zupełnie inny produkt). Zostaw tylko te wyglądające na poprawki/uzupełnienia personalizacji.
- Raportuj w planie w kolumnie "Mail klienta": `BRAK` / `N wiadomości — najnowsza: {krótkie streszczenie}` — żeby użytkownik widział, że sprawdziłaś.
- **Traktuj oba źródła łącznie.** Wiadomość klienta do zamówienia często zawiera doprecyzowania, korekty, dodatkowe życzenia, preferencje zapisu imion, poprawki literówek, prośby typu "zamiast Kasia wpiszcie Kasiu", uzupełnienia brakujących pól (np. data, życzenia). Jeśli wiadomość klienta i personalizacja są **sprzeczne**, preferuj wiadomość klienta (jest późniejsza, bardziej świadoma) — ale zaraportuj konflikt w planie.
- Jeśli `customer_message` zawiera treści niezwiązane z personalizacją (np. "proszę o szybką wysyłkę", "dziękuję") — zignoruj do celów generacji, ale odnotuj w planie w kolumnie "Wiadomość klienta" żeby użytkownik widział że sprawdziłaś.
- Zinterpretuj dane kontekstowo. Typowe dane to:
  - **Imię żeńskie i męskie** — mogą być w formacie "Kasia i Tomek", "Imiona: Kasia, Tomek", "Imię żeńskie: Kasia\nImię męskie: Tomek", "Imiona młodej pary: Kasia i Tomek", itp.
  - **Data uroczystości** — format DD.MM.YYYY, może być opisana jako "Data: 30.04.2026" lub "Data uroczystości: 30.04.2026" lub po prostu "30.04.2026"
  - **Życzenia** — opcjonalny tekst (np. "Na zdrowie!", "Dziękujemy!"). Jeśli brak — zostaw domyślne z szablonu
  - Ignoruj pola takie jak "Kolor tekstu", "Zakrętka" — te dotyczą produkcji, nie projektu
- **Imię dziecka — forma zależna od skryptu:**
  - **Pudełka, magnesy (`pudelko_*`, `magnes_*`)** — dopełniacz: "Chrzest Święty [kogo?]", "Komunia Święta [kogo?]". Przykłady: Ignacy → Ignacego, Teodor → Teodora, Zosia → Zosi, Maja → Mai, Jakub → Jakuba. Raportuj przekształcenie w planie.
  - **Prośby o chrzestnego (`prosba_chrzestny_*`)** — **mianownik**: imię dziecka to podpis na karcie (dziecko „pisze" prośbę). Przekaż dosłownie: Tymon → Tymon, Borysek → Borysek. NIE stosuj dopełniacza.
- **Nazwa klienta** (do nazwy pliku wyjściowego) — z `order_addresses.name` (pole `buyer_name` w zapytaniu)

**WAŻNE — semantyczny podział pola "Kto składa życzenia" na `naglowek` + `od_kogo`:**

Pole `Kto składa życzenia` w personalizacji klienta NIE jest jednoznacznie = `--od-kogo`. Szablony pudełek chrzest/komunia mają dwa osobne teksty nad i pod życzeniami: `naglowek` (fraza życzeniowa, np. "Z najlepszymi życzeniami") oraz `od_kogo` (podpis, np. "Matka Chrzestna"). Klienci często wklejają w jedno pole frazę życzeniową + podpis — trzeba to **semantycznie** rozdzielić, bazując na znajomości języka polskiego.

Zasady:
- **Czysty podpis** (krótki, typu "Twoja chrzestna", "Ciocia Gabi i wujek Filip", "Rodzice Chrzestni") → cały tekst jako `--od-kogo`, `naglowek` domyślny z szablonu.
- **Fraza życzeniowa + podpis** (np. "Z miłością i modlitwą w dniu Chrztu Świętego – Matka Chrzestna z rodziną") → podziel:
  - Część życzeniowa → `--naglowek` ("Z miłością i modlitwą w dniu Chrztu Świętego")
  - Podpis → `--od-kogo` ("Matka Chrzestna z rodziną")
- **Rola rodzinna + konkretne osoby** (np. "Rodzice Chrzestni - Ciocia Ania i Wujek Wojtek") → zostaw jako całość w `--od-kogo`. "Rodzice Chrzestni" to rola, nie fraza życzeniowa.

Separatorem może być myślnik (`–`, `—`, ` - `), nowa linia, dwukropek, przecinek, **lub nic** — decyduj semantycznie, nie mechanicznie.

Heurystyki rozpoznania frazy życzeniowej (→ `naglowek`):
- zawiera słowa typu: "z miłością", "z modlitwą", "z najlepszymi życzeniami", "w dniu", "błogosławieństwa", "na pamiątkę"
- ma charakter uroczysty, długości >20 znaków
- nie wskazuje konkretnej osoby ani roli rodzinnej

Heurystyki rozpoznania podpisu (→ `od_kogo`):
- role rodzinne: Matka/Ojciec Chrzestny, Rodzice Chrzestni, Ciocia, Wujek, Babcia, Dziadek
- imiona własne, "z rodziną"

**W razie wątpliwości** — pokaż użytkownikowi obie interpretacje w planie (opcja A/B) i zapytaj, zamiast zgadywać.

**WAŻNE — łączenie wielu pozycji jednego zamówienia w jeden plik (prośby o bycie chrzestnym):**

Dla produktów mapujących się na skrypt `prosba_chrzestny_*.py` — szablon ma dwie ścianki (matka + ojciec) i skrypt akceptuje oba zestawy parametrów jednocześnie.

**Kluczowa zasada:** grupowanie po `(order_id, script_name)`, **nie** po nazwie produktu. Produkty w bazie mają różne nazwy dla matki i ojca (np. `"Akrylowa prośba o zostanie Ojcem Chrzestnym lustrzana złota - Dłonie"` i `"Akrylowa prośba o zostanie Matką Chrzestną lustrzana złota - Dłonie"`), ale mapują się **na ten sam skrypt**. Dlatego mapowania w `project_mappings` muszą mieć OSOBNY wpis dla każdej nazwy produktu wskazujący na ten sam `script_name`.

Algorytm dla skryptów `prosba_chrzestny_*`:

1. Po pobraniu listy zamówień **pogrupuj** pozycje po `(order_id, script_name)`.
2. Dla każdej grupy (jedno zamówienie + jeden skrypt):
   - Rozpoznaj po nazwie produktu lub treści personalizacji, która pozycja to **ojciec**, a która **matka** (słowa-klucze: "Ojcem Chrzestnym", "Wujku", "moim" → ojciec; "Matką Chrzestną", "Ciociu", "moją" → matka).
   - `--imie-dziecka` jest wspólne — wyciągnij z personalizacji (zwykle jedno imię dziecka powtarza się w obu pozycjach).
   - `--matka-wolacz` / `--ojciec-wolacz` — z odpowiadających pozycji.
   - Uruchom skrypt **raz** z obydwoma parametrami.
3. Wygenerowany zostanie **jeden plik PSD** zawierający obie karty na A3.
4. Oznacz **obie** pozycje `order_items` jako `project_generated = 1` po sukcesie (update po `id IN (item_id_matka, item_id_ojciec)`).

Pozostałe przypadki:
- 1× matka + 1× ojciec → **jeden plik** z obojgiem.
- tylko 1× matka → **jeden plik** z samą matką (DP ukryty).
- tylko 1× ojciec → **jeden plik** z samym ojcem (DL ukryty).
- 2× ta sama strona (np. 2× matka) → **jeden plik** z matką; `quantity` decyduje o liczbie wydruków, nie liczba plików PSD; oznacz obie pozycje jako generowane.

**Przykład** (OP000000385): 2 pozycje — `Akrylowa prośba o zostanie Ojcem Chrzestnym...` (Wujku Adi, Laura) + `Akrylowa prośba o zostanie Matką Chrzestną...` (Ciociu Dario, Laura). Wynik: JEDEN plik `Natalia Kwapisz.psd` z `--imie-dziecka "Laura" --ojciec-wolacz "Wujku Adi" --matka-wolacz "Ciociu Dario"`.

**Rozpoznawanie matka/ojciec — po treści personalizacji, NIE po nazwie produktu:**

Klienci często mylą się przy wyborze produktu i zamawiają np. 2× "Matką Chrzestną", ale w personalizacji jedna z pozycji ma treść męską ("Wujku..."). **Nie sugeruj się nazwą produktu** — analizuj treść personalizacji i rozpoznaj:
- `"Wujku [imię]"`, `"Wujek"`, `"moim Ojcem"`, `"Ojcem Chrzestnym"` → **ojciec** (`--ojciec-wolacz`)
- `"Ciociu [imię]"`, `"Ciocia"`, `"moją Matką"`, `"Matką Chrzestną"` → **matka** (`--matka-wolacz`)

Jeśli w jednym zamówieniu klient wybrał 2× ten sam produkt, ale personalizacje wskazują na matkę + ojca — zinterpretuj jako 1 plik z obojgiem chrzestnych.

**Normalizacja wołaczy — klient podaje tylko imię w mianowniku:**

Szablon oczekuje formy typu `"Ciociu Kasiu"` / `"Wujku Darku"` (prefiks roli + wołacz imienia). Jeśli klient podał tylko imię w mianowniku (np. `"Imię cioci: Paulina"`, `"Wujek: Dawid"`, `"Ciocia: Julia"`) — **automatycznie przekształć**:

1. Z imienia w mianowniku utwórz **wołacz polski** (Paulina → Paulino, Dawid → Dawidzie, Julia → Julio, Kasia → Kasiu, Darek → Darku, Michał → Michale, Ola → Olu, itd.).
2. Dodaj prefiks roli: `"Ciociu "` dla matki, `"Wujku "` dla ojca.
3. Finalny format: `"Ciociu Paulino"`, `"Wujku Dawidzie"`, `"Ciociu Julio"`.

**Wyjątek:** Jeśli klient **wyraźnie pisze** że ma być bez zwrotu (np. "bez Ciociu", "tylko imię", "samo imię"), wtedy wstawiaj surowe imię bez prefiksu. W każdym innym przypadku — zawsze dodawaj `Ciociu`/`Wujku`.

**Jeśli klient już podał pełną formę** (`"Ciociu Paulino"`, `"Wujku Dawidzie"`) — zostaw dosłownie, nie modyfikuj.

Te reguły (rozpoznawanie płci po treści + auto-wołacz) są domyślne — NIE pytaj użytkownika za każdym razem, tylko raportuj w planie co zrobiono (oryginał → przekształcenie), żeby mógł zweryfikować.

**WAŻNE — zaproszenia akrylowe (skrypt `zaproszenie_chrzest_*.py`):**

Szablon ma 4 ścianki na A3 (DP, DL, GP, GL) — 4 zaproszenia na arkusz. **Wspólne dla wszystkich ścianek:** imię dziecka, miejsce_data, poczęstunek. **Różne:** `od_kogo` (każda ścianka = jedna osoba zapraszana).

**Grupowanie wielu pozycji zamówienia (analogicznie do próśb o chrzestnego):**

W jednym zamówieniu może być kilka pozycji tego samego (lub mapującego się na ten sam skrypt) produktu zaproszeń. **NIE** generuj pliku per pozycja. Zasady:

1. Pogrupuj pozycje po `(order_id, script_name)`.
2. Dla każdej grupy zbierz **wszystkie osoby zapraszane** ze wszystkich pozycji (z `personalization` każdej pozycji, + uwzględnij `quantity` jeśli klient w jednej pozycji podał wiele osób z quantity > 1).
3. Połącz w jedną listę `od_kogo`.
4. Wspólne dane (imię dziecka, miejsce_data, poczęstunek) — wyciągnij raz, z pierwszej pozycji (powinny być identyczne we wszystkich pozycjach grupy, jeśli nie — zapytaj użytkownika).
5. Zastosuj **batching po 4**: podziel listę `od_kogo` na partie po 4 i wywołaj skrypt N razy z numerowanymi nazwami plików.
6. Po sukcesie oznacz **wszystkie** pozycje grupy jako `project_generated = 1`.

**Batching przy quantity > 4:** 1 plik PSD = max 4 zaproszenia. Jeśli klient zamawia więcej osób (np. 17 zaproszeń), silnik dzieli listę na partie po 4 i wywołuje skrypt wielokrotnie z numerowanymi nazwami plików:
- 17 zaproszeń → 5 plików: `Klient 01.psd` (4), `Klient 02.psd` (4), `Klient 03.psd` (4), `Klient 04.psd` (4), `Klient 05.psd` (1).
- 4 zaproszenia → 1 plik `Klient.psd` (bez numeracji).
- 6 zaproszeń → 2 pliki: `Klient 01.psd` (4) + `Klient 02.psd` (2).

Numerowanie nadawane przez silnik (nie przez skrypt). Zderzenia nazw w `_gotowe/` są rozstrzygane normalnym sufiksem.

**Interpretacja skrótowej personalizacji klienta:**

Klienci wpisują dane skrótowo, trzeba je rozwinąć patrząc na oryginalne placeholdery w szablonie. Przykłady:

Wejście klienta:
```
Imię dziecka: Teodor Surma
Imię i nazwisko proszonego gościa: Matkę Chrzestną Wiktorię Igras
na Chrzest Święty w Parafia pw. Świętej Jadwigi Śląskiej w Hedwiżynie 45A
Data i godzina: 18 Kwiecień 2026 Godzina 13.00
Miejsce przyjęcia: "Kresovia Biłgoraj - Sala Balowa, Okrągłe 1C, 23-400 Biłgoraj"
```

Przekształcenie na parametry skryptu:
- `--imie-dziecka "Teodora"` (mianownik "Teodor" → dopełniacz, bo szablon: "uroczystość przyjęcia Sakramentu Chrztu Świętego [kogo?] Teodora")
- `--miejsce-data "W dniu 18.04.2026\ro godzinie 13:00\rParafia pw. Świętej Jadwigi Śląskiej\rw Hedwiżynie 45A"` (format jak w oryginale: "W dniu DD.MM.RRRR o godzinie HH:MM\rParafia...\rulica")
- `--poczestunek "Po uroczystości serdecznie zapraszamy\rna poczęstunek do Kresovia Biłgoraj - Sala Balowa\rOkrągłe 1C, 23-400 Biłgoraj"` (format jak w oryginale)
- `--od-kogo-1 "Matkę Chrzestną Wiktorię Igras"` (poprawiam literówki "Chszestną" → "Chrzestną")

**Zasady rozwijania danych:**
- Daty: `"18 Kwiecień 2026 Godzina 13.00"` → `"W dniu 18.04.2026\ro godzinie 13:00"` (miesiąc po polsku → numer, "Godzina 13.00" → "o godzinie 13:00", dodany prefiks "W dniu").
- Parafia: `"Parafia pw. X w Y 45A"` → zostaw bez zmian, złącz łamaniem linii w logiczne miejsca.
- Miejsce przyjęcia: osadź w formule "Po uroczystości serdecznie zapraszamy na poczęstunek do [NAZWA]\r[ULICA, KOD MIASTO]".
- Imię dziecka: zawsze dopełniacz (szablon: "Chrztu Świętego [kogo?]").
- Literówki klienta (`"Chszestną"` → `"Chrzestną"`, `"Chszestnego"` → `"Chrzestnego"`) — **poprawiaj automatycznie**.
- Nazwisko zapraszanego gościa: zostaw w formie jaką podał klient (nie odmieniaj jeśli nie jesteś pewny).

**Jeśli klient nie podał czegoś** (np. brak miejsca przyjęcia = brak poczęstunku) → `--poczestunek` pomiń, warstwa zostanie ukryta.

**Formatowanie daty — specyficzne dla szablonu:**

Niektóre szablony mają nietypowy format daty (np. `"10 | 05 | 2026"` z pipe'ami). Skrypt przyjmuje datę **dosłownie** — silnik `/wygeneruj-projekty` musi przekształcić standardowy format klienta (`DD.MM.RRRR` lub `DD-MM-RRRR`) na format oczekiwany przez szablon, zanim wywoła skrypt.

Obecne wzorce formatów daty per skrypt:
- `pudelko_komunia_kwiaty.py` → format `"DD | MM | RRRR"` (np. `"10 | 05 | 2026"`). Silnik: `"10.05.2026"` → `"10 | 05 | 2026"`.
- `pudelko_komunia_kwiaty_wzor2.py` → format `"DD | MM | RRRR"` (np. `"10 | 05 | 2026"`). Silnik: `"10.05.2026"` → `"10 | 05 | 2026"`.
- `pudelko_komunia_golabek_uv.py` → format `"DD | MM | RRRR"` (np. `"10 | 05 | 2026"`). Silnik: `"10.05.2026"` → `"10 | 05 | 2026"`.
- `pudelko_komunia_kielich_uv.py` → format `"DD | MM | RRRR"` (np. `"24 | 05 | 2026"`). Silnik: `"24.05.2026"` → `"24 | 05 | 2026"`.
- Wszystkie pozostałe `pudelko_komunia_*`, `pudelko_chrzest_*`, `buteleczki_slub_*` → format `"DD.MM.RRRR"` (standardowy).

Dodaj nowe wzory tu, gdy będą tworzone nowe skrypty z nietypowymi formatami.

### 6. Przedstaw plan i generuj

Wyświetl tabelę z planem:
```
Zamówienie | Produkt | Imię żeńskie | Imię męskie | Data | Życzenia | Klient (nazwa pliku)
OP000123   | Buteleczka... | Kinga | Łukasz | 30.04.2026 | (domyślne) | Kinga Klimczak
```

**Autonomia przy generowaniu:**
- Jeśli wszystkie interpretacje są **jasne lub wątpliwości minimalne** (rutynowe przekształcenia: dopełniacz imienia, format daty, auto-wołacz, podział naglowek/od_kogo zgodnie z regułami) → **generuj od razu po wyświetleniu planu**, bez pytania o potwierdzenie. Raportuj w planie co zostało przekształcone, żeby użytkownik mógł zweryfikować po fakcie.
- Jeśli wątpliwość jest **istotna** (np. brakujące imię męskie w buteleczkach ślubnych, niejasne przypisanie matka/ojciec przy próśbach, dwuznaczny podział naglowek/od_kogo, dziwny format daty, klient wyraźnie pomylił produkt, treść zawierająca rażące dubluje lub sprzeczność między polami) → **zatrzymaj się i zapytaj** użytkownika, prezentując opcje.

Kierunkowskaz: "czy jestem pewny że wynik będzie akceptowalny?" Jeśli tak — jedź. Jeśli nie — pytaj.

### 7. Uruchom generowanie

Przed generowaniem sprawdź czy Photoshop jest uruchomiony:
```bash
tasklist //FI "IMAGENAME eq Photoshop.exe" 2>/dev/null | grep -i photoshop
```
Jeśli Photoshop nie jest uruchomiony — poinformuj użytkownika i poczekaj aż go uruchomi.

**Pobranie zdjęcia od klienta (jeśli `requires_photo = 1`):**

Dla mapowań z `requires_photo = 1` przed wywołaniem generatora pobierz zdjęcie z poczty klienta:
```bash
python tools/generowanie/email_photo_fetcher.py --email "{buyer_email}" --out "C:/tmp/orderpro_photos" --days 365
```
- Skrypt zwraca ścieżkę pobranego pliku albo komunikat `BRAK` (exit code 1).
- Jeśli zdjęcie się pobrało — przekaż ścieżkę do generatora przez `--zdjecie`.
- Jeśli zdjęcia **nie znaleziono** — generator i tak ma być wywołany **bez** `--zdjecie` (wstawi zielony placeholder jako sygnał "klient nie przysłał foto"). NIE blokuj generacji.
- Zaraportuj w tabeli planu (kolumna "Zdjęcie") status: ścieżka / `BRAK (zielony placeholder)`.

**WAŻNE — rozpoznawanie płci dziecka (dla skryptów z parametrem `--plec`):**
Niektóre skrypty (np. `akrylowe_podziekowanie_matka_chrzestna_wzor2.py`) mają dwa warianty szablonu (chłopiec/dziewczynka) i wymagają parametru `--plec m` lub `--plec k`. Rozpoznaj płeć na podstawie personalizacji:
- **Imię proste** (Fabian, Wojciech, Kacper → `m`; Blanka, Zosia, Wiktoria → `k`) — standardowa wiedza o polskich imionach.
- **Imię odmienione** (np. "Wojtusia", "Kacpra" → `m`; "Blanki", "Zosi", "Wiktorii" → `k`) — rozpoznaj mianownik i z niego określ płeć.
- **Kontekst** — jeśli w personalizacji pojawia się "mój Chrześniak", "Drogi Synku", "malutki" → `m`; "moja Chrześniaczka", "Droga Córeczko", "malutka" → `k`.
- **W razie wątpliwości** — wyświetl surowe dane klientowi i zapytaj.

**WAŻNE — łamanie linii w tekstach wielolinijkowych (życzenia, podziękowanie, itp.):**
Photoshop jako znak łamania linii w warstwach tekstowych rozpoznaje **`\r` (CR)**, NIE `\n` (LF). Jeśli przekażesz `\n`, Photoshop wyświetli go jako śmieciowy kwadrat z literą "n". W bashu użyj ANSI-C quoting: `$'linia1\rlinia2\rlinia3'` do budowy wartości `--zyczenia` / `--podziekowanie` i przekaż ją w cudzysłowach do skryptu.

Dla każdego potwierdzonego produktu:
1. **Sprawdź kolizję nazwy pliku** w katalogu wyjściowym. Jeśli plik `{klient}.psd` (lub inne rozszerzenie używane przez skrypt) już istnieje — dodaj do nazwy klienta sufiks z indeksem `01`, `02`, ... (np. `Anna Rak` → `Anna Rak 01`, a jeśli i to zajęte → `Anna Rak 02`). Inkrementuj aż znajdziesz wolną nazwę. Dopiero wtedy przekaż wynik jako `--klient`.
2. Uruchom skrypt: `python tools/generowanie/{script_name} --klient "Imię Nazwisko" ...` (parametry zależne od skryptu — dla buteleczek/pudełek zwykle `--imie/--imiona`, `--data`, opcjonalnie `--zyczenia`/`--podziekowanie`; dla produktów ze zdjęciem dorzuć `--zdjecie /sciezka/do/foto.jpg`; **dla skryptów `magnes_*` dorzuć `--liczba {order_items.quantity}`** — szablony mają N slotów na arkuszu A3, nadmiar ma być ukrywany żeby nie drukować pustych kopii)

**WAŻNE — imię dziecka w skryptach `magnes_chrzest_*`:** Skrypty magnesów chrzestnych konstruują tytuł jako `"Chrzest Święty\r{imie}"` — słowo "Święty" **nie jest odmieniane**, odmienia się **tylko imię** (dopełniacz). Przekaż samo imię w dopełniaczu (np. `--imie "Tymka"`, `--imie "Rozalii"`, `--imie "Jakuba"`). Wynik: "Chrzest Święty↵Tymka" — poprawnie.
3. Jeśli mapowanie ma `output_dir` — skrypt powinien zapisać tam (jeśli obsługuje)

### 8. Oznacz w bazie

Po udanym generowaniu:
```sql
UPDATE order_items 
SET project_generated = 1, project_generated_at = NOW() 
WHERE id = {item_id};
```

### 9. Raport końcowy

Wyświetl podsumowanie:
- Ile projektów wygenerowano
- Ile pominięto (brak mapowania, brak personalizacji)
- Ewentualne błędy

## Ważne zasady

- **Zawsze pytaj o potwierdzenie** przed generowaniem
- **Photoshop musi być uruchomiony** — sprawdź przed generowaniem
- **Nie oznaczaj jako wygenerowane** jeśli skrypt zwrócił błąd
- **Jeśli nie potrafisz zinterpretować personalizacji** — wyświetl surowe dane i zapytaj użytkownika
- Skrypty generujące znajdują się w `tools/generowanie/` w katalogu projektu orderPRO
