#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from uuid import uuid4
"""
import_beerds_sql.py

Скрипт читает файлы из каталогов:
- server/modules/descriptions/repository/breed_descriptions
- server/modules/descriptions/repository/breed_signs

и вместо непосредственной вставки генерирует PostgreSQL‑SQL‑файл, который
можно применить через `psql -f <имя_файла.sql>`:

    CREATE TABLE beerds.beerds (
        id varchar NOT NULL,
        name text NOT NULL,
        descriptions text NOT NULL,
        signs json NOT NULL,
        alias text NOT NULL,
        CONSTRAINT beerds_pkey PRIMARY KEY (id)
    );
"""

import sys
import json
import hashlib
import pathlib


# ------------------------------------------------------------------
# 2️⃣ Путь к каталогам (можно изменить под свой проект)
# ------------------------------------------------------------------
BASE_DIR = pathlib.Path(__file__).resolve().parent.parent
DESC_DIR = BASE_DIR / "scripts/assistant/cat_descriptions"
SIGN_DIR = BASE_DIR / "scripts/assistant/cat_breed_signs"
print(f"DESC_DIR = {DESC_DIR}")


# ------------------------------------------------------------------
# 3️⃣ Функции чтения файлов
# ------------------------------------------------------------------
def read_text_file(path: pathlib.Path) -> str:
    """Возвращает содержимое текстового файла (unicode)."""
    with path.open("r", encoding="utf-8") as f:
        return f.read().strip()


def read_json_file(path: pathlib.Path) -> dict:
    """Возвращает JSON‑объект из файла."""
    with path.open("r", encoding="utf-8") as f:
        return json.load(f)


# ------------------------------------------------------------------
# 4️⃣ Формируем словарь: имя → (описание, сигналы)
# ------------------------------------------------------------------
def build_breed_map(desc_dir: pathlib.Path, sign_dir: pathlib.Path) -> dict:
    """Возвращает dict: stem → (description, signs)"""
    desc_files = {p.stem: p for p in desc_dir.glob("*.txt")}
    sign_files = {p.stem: p for p in sign_dir.glob("*.txt")}
    for key in desc_files:
        if key  in sign_files:
            continue
        sign_files[key] = None


    common_keys = desc_files.keys() & sign_files.keys()
    if not common_keys:
        print("⚠️  Нет общих файлов между каталогами описаний и сигналов.")
        return {}

    breeds = {}
    for key in sorted(common_keys):
        desc_path = desc_files[key]
        sign_path = sign_files[key]
        try:
            description = read_text_file(desc_path)
        except Exception as e:
            print(f"❌  Не удалось прочитать описание {desc_path}: {e}")
            continue
        try:
            if sign_path is not None:
                signs = read_json_file(sign_path)
            else:
                signs = {}
        except Exception as e:
            print(f"❌  Не удалось прочитать сигналы {sign_path}: {e}")
            continue
        breeds[key] = (description, signs)
    return breeds


# ------------------------------------------------------------------
# 5️⃣ Генерация id (если нужно уникальное)
# ------------------------------------------------------------------
def generate_id(name: str, alias: str) -> str:
    """Генерирует MD5‑hash из `name:alias`."""
    key = f"{name}:{alias}"
    return hashlib.md5(key.encode("utf-8")).hexdigest()


# ------------------------------------------------------------------
# 6️⃣ Генерация SQL‑файла
# ------------------------------------------------------------------
def write_sql_file(breeds: dict, out_path: pathlib.Path):
    """Создаёт один .sql‑файл, содержащий INSERT‑операции для всех пород."""
    if not breeds:
        print("⚠️  Нет данных для генерации SQL.")
        return

    lines = []
    header = (
        "-- Автоматически сгенерированный скрипт вставки пород\n"
        "-- Запустить: psql -f beerds_insert.sql\n\n"
        "BEGIN;\n"
    )
    lines.append(header)

    # Формируем один блок INSERT с несколькими строками VALUES
    # 1. Столбцы
    cols = "(id, name, descriptions, signs, alias, kind)"
    # 2. Генерируем строки VALUES
    value_lines = []
    for name, (description, signs) in breeds.items():
        alias = name  # можно изменить при необходимости
        breed_id = generate_id(name, alias)
        # Подготовка значений: экранирование апострофов и JSON
        escaped_name = name.replace("_", " ").replace("'", "''")
        escaped_alias = alias.replace("'", "''")
        escaped_desc = description.replace("'", "''")
        # JSON как строка (в PostgreSQL json можно передавать как текст)
        json_str = json.dumps(signs, ensure_ascii=False).replace("'", "''")
        value_line = f"('{breed_id}', '{escaped_name}', '{escaped_desc}', '{json_str}', '{escaped_alias}', 'cat')"
        value_lines.append(value_line)

    # Объединяем VALUES через запятую
    values_section = ",\n".join(value_lines)
    insert_stmt = (
        f"INSERT INTO beerds.beerds {cols}\n"
        f"VALUES\n{values_section}\n"
        f"ON CONFLICT (id) DO UPDATE\n"
        f"    SET name = EXCLUDED.name,\n"
        f"        descriptions = EXCLUDED.descriptions,\n"
        f"        signs = EXCLUDED.signs,\n"
        f"        alias = EXCLUDED.alias;\n"
    )
    lines.append(insert_stmt)
    lines.append("\nCOMMIT;")

    # Записываем в файл
    out_path.write_text("\n".join(lines), encoding="utf-8")
    print(f"✅  SQL‑файл успешно сгенерирован: {out_path}")


# ------------------------------------------------------------------
# 7️⃣ Основная точка входа
# ------------------------------------------------------------------
def main():
    print("🔍  Читаем файлы…")
    breeds_map = build_breed_map(DESC_DIR, SIGN_DIR)

    if not breeds_map:
        print("❌  Ничего не найдено. Завершение.")
        sys.exit(1)

    # Путь для вывода SQL‑файла
    sql_file_path = BASE_DIR / "beerds_insert.sql"
    print(f"📝  Записываем INSERT‑операции в файл: {sql_file_path}")
    write_sql_file(breeds_map, sql_file_path)

    print("🎉  Готово!")


if __name__ == "__main__":
    main()
