# Пути к файлам в контейнере
import os

# Базовый путь для данных
BASE_DIR = os.path.dirname(os.path.abspath(__file__))

# Путь к файлу для хранения resolutions
CSV_FILE = os.path.join(BASE_DIR, 'resolutions.csv')

# Используем OpenSans шрифт
FONT_PATH = os.path.join(BASE_DIR, 'opensans.ttf')

# Создание папки для галереи
GALLERY_DIR = os.path.join(BASE_DIR, 'gallery')
os.makedirs(GALLERY_DIR, exist_ok=True)

# Пути к шаблонам
TEMPLATES = {
    "Еж-тян": os.path.join(BASE_DIR, "ejtan.png"),
    "Ежунья": os.path.join(BASE_DIR, "ejunya.png"),
    "Оливьешка": os.path.join(BASE_DIR, "olive.png"),
    "Опер-тян": os.path.join(BASE_DIR, "opertan.png"),
    "Фортран & Co": os.path.join(BASE_DIR, "fortranco.png"),
    "Фунтик": os.path.join(BASE_DIR, "funtik.png")
}

import streamlit as st
import pandas as pd
import random
from datetime import datetime
from PIL import Image, ImageDraw, ImageFont
import shutil
import base64

# Функция для инициализации CSV
def initialize_csv():
    df = pd.DataFrame(columns=['Resolution', 'Category', 'Mascot', 'Timestamp', 'ImagePath'])
    df.to_csv(CSV_FILE, index=False)

# Проверка и инициализация CSV
if not os.path.exists(CSV_FILE) or os.path.getsize(CSV_FILE) == 0:
    initialize_csv()
else:
    try:
        pd.read_csv(CSV_FILE)
    except (pd.errors.EmptyDataError, pd.errors.ParserError):
        initialize_csv()

# Список категорий и маскотов
CATEGORIES = ["Новогоднее поздравление", "Ебать ты молодец", "Эпик фейл"]
MASCOTS = ["Еж-тян", "Ежунья", "Оливьешка", "Опер-тян", "Фортран & Co", "Фунтик"]

# Проверка существования файлов шаблонов
def check_templates():
    missing_templates = []
    for name, path in TEMPLATES.items():
        if not os.path.exists(path):
            missing_templates.append(f"{name}: {path}")
    return missing_templates

# Проверка шрифта
def check_font():
    if not os.path.exists(FONT_PATH):
        return False
    return True

# Пул заголовков для каждой категории
title_pools = {
    "Новогоднее поздравление": [
        "Заверяющий официальное пожелание анона",
        "Подтверждает новогоднее настроение",
        "Вручается в честь наступления очередного витка этой вселенной",
        "Официально разрешает радоваться Новому году",
        "Подтверждает наличие оливьешки",
        "На законное распитие всякого под бой курантов",
        "За сохранение новогоднего духа в условиях треда",
        "Выдан без очереди, потому что новый год",
        "Сертифицирует тёплые пожелания от анона к анону",
        "На выдачу новогоднего настроения в треде"
    ],
    "Ебать ты молодец": [
        "Выдаётся охуенному молодцу",
        "Выдаётся по причине охуеть ты молодец",
        "Вручается за ультимативную годноту",
        "Вручается за запредельный уровень молодцовости",
        "Подтверждает факт: ты реально ебать какой молодец",
        "Выдан ебать какому молодцу",
        "За действия, от которых аноны охуели",
        "Официальное признание: охуенно справился",
        "За вклад в общее дело и локальный ахуй",
        "За демонстрацию силы постинга и абсолютной годноты"
    ],
    "Эпик фейл": [
        "За полнейший пиздец",
        "Вручается тотальному серуну",
        "Вручается за эталонный проёб всего и сразу",
        "О фиксации эпик фейла",
        "За вклад в фонд коллективного серунства",
        "Подтверждает: так обосраться - это надо уметь",
        "За достижение дна и уверенное его пробитие",
        "О признании фейлом года без права апелляции",
        "За демонстрацию того, как делать НЕ надо",
        "Официальное признание постера позором Ежача"
    ]
}

# Пул комментариев для каждой категории
comment_pools = {
    "Новогоднее поздравление": [
        "Всем Ежачом верим, что так и будет!",
        "Зафиксировано и заверенно, теперь сбудется, инфа 146%",
        "Эти пожелания искренны, я гарантирую это!",
        "Заверено Оператором, так что точно сбудется",
        "Пожелания занесены в аналлы Ежача",
        "Ежач видел - значит так тому и быть",
        "Так и будет, сомневаться запрещено",
        "Записано, сохранено, пути назад нет",
        "Теперь это официальная реальность (в разработке)",
        "С этого момента считается пророчеством"
    ],
    "Ебать ты молодец": [
        "Так держать!",
        "Ты заслужил уважение всех анонов",
        "Это было эпично!",
        "Такого ещё не видел никто",
        "Твой подвиг войдет в историю",
        "Оче годно, одобряемо всем тредом",
        "Мощно, анон",
        "Это был просто отвал жопы",
        "Восхищаемся всем Ежачом",
        "Это просто вау"
        
    ],
    "Эпик фейл": [
        "Ты обосрался на глазах у всего треда",
        "Господи, зачем ты это сделал",
        "Аноны запомнят это на долгие годы",
        "Таких фейлов у нас ещё не было",
        "Даже Оператору стыдно",
        "Интернет всё помнит",
        "Аноны в ахуе",
        "Поздравляем, ты вошёл не в ту историю",
        "Ну ты и выдал",
        "Лучше больше не пиши"
    ]
}

# Пул нижнего текста для каждой категории
signature_pools = {
    "Новогоднее поздравление": [
        "С Новым 2026 годом, анон!",
        "Желаем исполнения желаний в 2026!",
        "До встречи в новом году!",
        "Пусть все обещания сбудутся!",
        "С наступающим, анончик!",
        "Новый год уже здесь!",
        "2026 начинается прямо сейчас!",
        "Береги себя в новом году!",
        "С теплом, от анона к анону!",
        "Увидимся в 2026!"
    ],
    "Ебать ты молодец": [
        "Так держать и дальше!",
        "Продолжай в том же духе!",
        "Ты - легенда!",
        "Гордимся тобой, анон!",
        "За тобой будущее Ежача!",
        "Это было красиво!",
        "Ежач одобряе!",
        "Достойно!",
        "Не останавливайся!",
        "Уважение заслужено!"
    ],
    "Эпик фейл": [
        "Позор зафиксирован",
        "Это не забудут",
        "Удалить уже не получится",
        "С этим тебе жить",
        "Фейл принят без возражений",
        "Не пиши больше",
        "Это просто пиздец",
        "Невероятный кринж",
        "Смеялись всем тредом",
        "Борды - это не твоё"
    ]
}

# Определение текстовых областей для каждой позиции
# Формат: (x, y, max_width, line_height)
text_areas = {
    "title": (840, 610, 800, 50),       # Заголовок
    "content": (840, 740, 800, 40),     # Основной текст
    "comment": (840, 1120, 800, 40),    # Комментарий
    "signature": (1110, 1260, 600, 35)  # Подпись/нижний текст
}

# Фиксированные размеры шрифтов
font_sizes = {
    "title": 40,
    "content": 34,
    "comment": 34,
    "signature": 28
}

# Цвет текста
FONT_COLOR = (232, 201, 165)

def wrap_text(text, font, max_width):
    """Разбивает текст на строки, чтобы он помещался в заданную ширину"""
    lines = []
    
    # Если текст уже содержит переносы строк, обрабатываем каждую часть отдельно
    text_parts = text.split('\n')
    
    for part in text_parts:
        words = part.split()
        current_line = ""
        
        for word in words:
            # Проверяем ширину текущей строки с новым словом
            test_line = f"{current_line} {word}" if current_line else word
            test_bbox = font.getbbox(test_line)
            test_width = test_bbox[2] - test_bbox[0]
            
            if test_width <= max_width:
                current_line = test_line
            else:
                if current_line:
                    lines.append(current_line)
                current_line = word
        
        if current_line:
            lines.append(current_line)
    
    return lines

def draw_wrapped_text(draw, x, y, text, font, max_width, line_height, color):
    """Рисует текст с автоматическим переносом"""
    lines = wrap_text(text, font, max_width)
    
    for i, line in enumerate(lines):
        draw.text((x, y + i * line_height), line, font=font, fill=color)
    
    return len(lines)

def generate_certificate_image(category, mascot, user_data):
    """Генерация изображения сертификата"""
    # Проверяем существование шаблона
    template_path = TEMPLATES.get(mascot)
    
    if not template_path or not os.path.exists(template_path):
        st.error(f"Шаблон для маскота '{mascot}' не найден!")
        st.info(f"Ожидаемый путь: {template_path}")
        return None
    
    # Проверяем существование шрифта
    if not os.path.exists(FONT_PATH):
        st.error(f"Шрифт не найден по пути: {FONT_PATH}")
        return None
    
    try:
        # Загружаем шаблон
        img = Image.open(template_path)
        draw = ImageDraw.Draw(img)
        
        # Загружаем шрифт OpenSans
        title_font = ImageFont.truetype(FONT_PATH, font_sizes["title"])
        content_font = ImageFont.truetype(FONT_PATH, font_sizes["content"])
        comment_font = ImageFont.truetype(FONT_PATH, font_sizes["comment"])
        signature_font = ImageFont.truetype(FONT_PATH, font_sizes["signature"])
        
    except Exception as e:
        st.error(f"Ошибка при загрузке ресурсов: {str(e)}")
        return None
    
    # Выбираем случайный текст из пулов
    title = random.choice(title_pools[category])
    comment = random.choice(comment_pools[category])
    signature_text = random.choice(signature_pools[category])
    
    # Формируем основной текст в зависимости от категории
    if category == "Новогоднее поздравление":
        main_text = f"Пожелания: {user_data.get('promise', '')}"
    else:
        main_text = f"Для анона: {user_data.get('username', '')}\nПричина вручения: {user_data.get('reason', '')}"
    
    # Получаем параметры областей
    title_x, title_y, title_width, title_line_height = text_areas["title"]
    content_x, content_y, content_width, content_line_height = text_areas["content"]
    comment_x, comment_y, comment_width, comment_line_height = text_areas["comment"]
    signature_x, signature_y, signature_width, signature_line_height = text_areas["signature"]
    
    # Рисуем текст на изображении с автоматическим переносом
    # Заголовок
    draw_wrapped_text(draw, title_x, title_y, title, title_font, title_width, title_line_height, FONT_COLOR)
    
    # Основной текст
    draw_wrapped_text(draw, content_x, content_y, main_text, content_font, content_width, content_line_height, FONT_COLOR)
    
    # Комментарий
    draw_wrapped_text(draw, comment_x, comment_y, comment, comment_font, comment_width, comment_line_height, FONT_COLOR)
    
    # Подпись/нижний текст
    draw_wrapped_text(draw, signature_x, signature_y, signature_text, signature_font, signature_width, signature_line_height, FONT_COLOR)
    
    # Сохранение временного файла
    temp_file = os.path.join(BASE_DIR, 'certificate.png')
    try:
        img.save(temp_file)
        return temp_file
    except Exception as e:
        st.error(f"Ошибка при сохранении сертификата: {str(e)}")
        return None

# Функция для загрузки изображения и конвертации в base64
def get_image_base64(path):
    if os.path.exists(path):
        try:
            with open(path, "rb") as img_file:
                return base64.b64encode(img_file.read()).decode()
        except Exception as e:
            st.error(f"Ошибка при чтении файла: {str(e)}")
            return None
    return None

# Функция для обновления категории
def update_category(new_category):
    """Обновляет категорию и очищает соответствующие поля"""
    st.session_state.category = new_category
    if new_category == "Новогоднее поздравление":
        st.session_state.username = ''
        st.session_state.reason = ''
    else:
        st.session_state.promise = ''

# Настройка страницы
st.set_page_config(
    page_title="Glintwine for ejchan",
    page_icon="🍷",
    layout="wide"
)

# Кастомный CSS для оформления
st.markdown("""
    <style>
    .header-container {
        display: flex;
        align-items: center;
        margin-bottom: 10px;
        padding: 10px 0;
        border-bottom: 1px solid #eee;
    }
    .logo-img {
        height: 60px;
        width: 30px;
        margin-right: 20px;
        object-fit: contain;
    }
    .service-title {
        font-size: 34px;
        font-weight: bold;
        color: #2E8B57;
        margin: 0;
        line-height: 1.2;
    }
    .service-subtitle {
        font-size: 16px;
        color: #666;
        font-style: italic;
        margin-top: 5px;
        margin-bottom: 0;
        opacity: 0.7;
    }
    .footer-container {
        margin-top: 50px;
        padding: 20px 0;
        text-align: center;
        width: 100%;
    }
    .footer-text {
        font-size: 16px;
        color: white;
        opacity: 0.7;
        font-style: italic;
        text-align: center;
        padding: 10px;
        background-color: rgba(46, 139, 87, 0.1);
        border-radius: 5px;
        display: inline-block;
    }
    .main-title {
        margin-top: 30px;
        margin-bottom: 15px;
        color: #ffffff;
    }
    .stButton > button {
        transition: all 0.3s ease;
    }
    .stButton > button:hover {
        transform: translateY(-2px);
        box-shadow: 0 4px 8px rgba(0,0,0,0.1);
    }
    .text-info {
        background-color: #f8f9fa;
        padding: 10px;
        border-radius: 5px;
        border-left: 3px solid #2E8B57;
        margin: 10px 0;
        font-size: 14px;
        color: #666;
    }
    </style>
""", unsafe_allow_html=True)

# Шапка с логотипом и названием сервиса
logo_path = None
for ext in ['.svg', '.png', '.jpg', '.jpeg', '.webp']:
    test_path = os.path.join(BASE_DIR, f'logo{ext}')
    if os.path.exists(test_path):
        logo_path = test_path
        break

# Отображаем шапку
st.markdown("""
    <div class="header-container">
""", unsafe_allow_html=True)

col1, col2, col3 = st.columns([1, 5, 1])
with col1:
    if logo_path:
        st.image(logo_path, width=60)
    else:
        st.markdown('<div style="font-size: 48px; margin-right: 20px;">🍷</div>', unsafe_allow_html=True)

with col2:
    st.markdown('<p class="service-title">Glintwine for ejchan</p>', unsafe_allow_html=True)
    st.markdown('<p class="service-subtitle">Drug for dreams does not exists, but you can drink some glintwine. Cause why not?</p>', unsafe_allow_html=True)

with col3:
    pass

st.markdown("</div>", unsafe_allow_html=True)

# Проверка необходимых файлов
missing_templates = check_templates()
if missing_templates:
    st.warning("⚠️ Некоторые шаблоны не найдены:")
    for missing in missing_templates:
        st.write(f"  - {missing}")

if not check_font():
    st.error(f"⚠️ Шрифт OpenSans не найден по пути: {FONT_PATH}")

# Основной заголовок
st.markdown('<h1 class="main-title">Генератор сертификатов для ежеанонов 🦔</h1>', unsafe_allow_html=True)
st.write("Создай уникальный сертификат для себя или другого анона!")

# Инициализируем session state для хранения данных формы
if 'category' not in st.session_state:
    st.session_state.category = CATEGORIES[0]
if 'promise' not in st.session_state:
    st.session_state.promise = ''
if 'username' not in st.session_state:
    st.session_state.username = ''
if 'reason' not in st.session_state:
    st.session_state.reason = ''
if 'mascot' not in st.session_state:
    st.session_state.mascot = MASCOTS[0]

# Используем st.radio для выбора категории
st.write("### Выбери категорию:")
category = st.radio(
    "Категория",
    CATEGORIES,
    index=CATEGORIES.index(st.session_state.category),
    key="category_radio",
    label_visibility="collapsed",
    horizontal=True
)

# Обновляем session state при изменении категории
if category != st.session_state.category:
    update_category(category)

# Показываем текущую выбранную категорию
st.write(f"**Выбрана категория:** {st.session_state.category}")

# Используем форму с фиксированным ключом
with st.form(key='certificate_form'):
    st.write("### Заполни данные:")
    
    # Динамические поля в зависимости от категории
    if st.session_state.category == "Новогоднее поздравление":
        promise = st.text_area(
            "Твоё поздравление",
            value=st.session_state.promise,
            key='promise_input',
            height=100
        )
        st.session_state.promise = promise
    
    else:
        username = st.text_input(
            "Вставь номер поста или имя анона, кому будет выдано",
            value=st.session_state.username,
            key='username_input'
        )
        
        reason_label = "Причина молодца" if st.session_state.category == "Ебать ты молодец" else "Причина фейла"
        reason_example = "Охуенный пост, познавательный" if st.session_state.category == "Ебать ты молодец" else "'Обосрался в дискуссии о чае'"
        
        reason = st.text_area(
            f"{reason_label} (например: {reason_example})",
            value=st.session_state.reason,
            key='reason_input',
            height=80,
        )
        
        st.session_state.username = username
        st.session_state.reason = reason
    
    # Выбор маскота
    mascot = st.selectbox(
        "Выберите оформление",
        MASCOTS,
        index=MASCOTS.index(st.session_state.mascot) if st.session_state.mascot in MASCOTS else 0,
        key='mascot_select'
    )
    st.session_state.mascot = mascot
    
    # Дополнительные опции
    save_to_gallery = st.checkbox("Сохранить в галерею", key='gallery_checkbox')
    submit_button = st.form_submit_button(label='🎨 Сгенерировать сертификат')

if submit_button:
    # Подготавливаем user_data
    user_data = {}
    if st.session_state.category == "Новогоднее поздравление":
        user_data['promise'] = st.session_state.promise
    else:
        user_data['username'] = st.session_state.username
        user_data['reason'] = st.session_state.reason
    
    # Проверка заполнения полей
    is_valid = True
    error_message = ""
    
    if st.session_state.category == "Новогоднее поздравление":
        if not user_data.get('promise'):
            error_message = "Заполните поле 'Твоё поздравление'!"
            is_valid = False
    else:
        if not user_data.get('username'):
            error_message = "Заполните поле 'Номер поста или имя анона'!"
            is_valid = False
        elif not user_data.get('reason'):
            field_name = "Причина молодца" if st.session_state.category == "Ебать ты молодец" else "Причина фейла"
            error_message = f"Заполните поле '{field_name}'!"
            is_valid = False
    
    if not is_valid:
        st.error(error_message)
    else:
        # Генерация изображения с индикатором загрузки
        with st.spinner("Генерируем сертификат..."):
            cert_path = generate_certificate_image(st.session_state.category, st.session_state.mascot, user_data)
        
        if cert_path:
            # Отображение сертификата
            st.success("Сертификат готов!")
            st.image(cert_path, caption="Ура!")
            
            # Кнопка скачивания
            try:
                with open(cert_path, "rb") as file:
                    st.download_button(
                        label="💾 Скачать сертификат", 
                        data=file, 
                        file_name="certificate.png", 
                        mime="image/png"
                    )
            except Exception as e:
                st.error(f"Ошибка при подготовке файла для скачивания: {str(e)}")
            
            # Сохранение в галерею
            if save_to_gallery:
                try:
                    now = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
                    unique_name = f"cert_{now}.png"
                    gallery_path = os.path.join(GALLERY_DIR, unique_name)
                    shutil.copy(cert_path, gallery_path)
                    
                    # Сохраняем данные в CSV
                    new_entry = pd.DataFrame([[str(user_data), st.session_state.category, st.session_state.mascot, now, gallery_path]], 
                                            columns=['Resolution', 'Category', 'Mascot', 'Timestamp', 'ImagePath'])
                    try:
                        df = pd.read_csv(CSV_FILE)
                    except (pd.errors.EmptyDataError, pd.errors.ParserError):
                        initialize_csv()
                        df = pd.read_csv(CSV_FILE)
                    
                    df = pd.concat([df, new_entry], ignore_index=True)
                    df.to_csv(CSV_FILE, index=False)
                    
                    st.success("✅ Сертификат сохранён в галерее!")
                    
                except Exception as e:
                    st.error(f"Ошибка при сохранении в галерею: {str(e)}")

# Галерея сертификатов
st.header("Галерея сертификатов")
st.caption("Последние сгенерированные сертификаты")

try:
    if os.path.exists(CSV_FILE) and os.path.getsize(CSV_FILE) > 0:
        df = pd.read_csv(CSV_FILE)
        if not df.empty:
            # Получаем только существующие файлы
            valid_images = []
            for i, row in df.iterrows():
                if os.path.exists(row['ImagePath']):
                    valid_images.append(row)
            
            if valid_images:
                # Показываем последние 9 сертификатов (3 ряда по 3)
                recent_images = list(reversed(valid_images))[:9]
                
                # Создаем сетку 3x3
                for i in range(0, len(recent_images), 3):
                    cols = st.columns(3)
                    for j in range(3):
                        if i + j < len(recent_images):
                            with cols[j]:
                                row = recent_images[i + j]
                                try:
                                    st.image(row['ImagePath'], caption=f"{row['Category']}")
                                except Exception as e:
                                    st.error(f"Ошибка при загрузке изображения")
            else:
                st.write("Нет доступных изображений в галерее.")
        else:
            st.write("Пока пусто — будь первым!")
    else:
        st.write("Пока пусто — будь первым!")
        
except Exception as e:
    st.error(f"Ошибка при загрузке галереи: {str(e)}")
    st.write("Попробуйте сгенерировать новый сертификат.")

# Футер с надписью
st.markdown("""
    <div class="footer-container">
        <div class="footer-text">
            Glintwine v1.1a. The d4d project
        </div>
    </div>
""", unsafe_allow_html=True)