import os
import base64
import pickle
import random
from flask import Flask, render_template, request

app = Flask(__name__)
app.config['SESSION_COOKIE_NAME'] = "task_session"

FLAG = os.environ.get('FLAG', 'vsosh{c4es4r_s4ys_n0t_t0_trust_p1ckl3}')

EXAMPLE_COLLECTION = [
    {'name': 'Обычный морской огурец', 'count': 2, 'glow': False},
    {'name': 'Светящийся морской огурец', 'count': 1, 'glow': True},
    {'name': 'Коралловый огурец', 'count': 3, 'glow': False},
]


def caesar_encode(data: bytes, shift: int) -> bytes:
    shift = shift % 256
    return bytes((b + shift) % 256 for b in data)


def caesar_decode(data: bytes, shift: int) -> bytes:
    shift = shift % 256
    return bytes((b - shift) % 256 for b in data)


def serialize_collection(collection: list, shift: int) -> str:
    raw = pickle.dumps(collection)
    shifted = caesar_encode(raw, shift)
    return f"{shift}:{base64.b64encode(shifted).decode()}"


def deserialize_save(save_str: str):
    if ':' not in save_str:
        return [], "Нарушена целостность сохранения"

    head, _, rest = save_str.strip().partition(':')
    try:
        shift = int(head)
    except ValueError:
        return [], "Нарушена целостность сохранения"

    if not (0 <= shift <= 255):
        return [], "Нарушена целостность сохранения"

    try:
        shifted = base64.b64decode(rest)
    except Exception:
        return [], "Нарушена целостность сохранения"

    try:
        raw = caesar_decode(shifted, shift)
        data = pickle.loads(raw)
    except Exception as e:
        return [], "Нарушена целостность сохранения"

    return (data if isinstance(data, list) else [data], None)


def normalize_items(collection_data):
    items = []
    for el in collection_data:
        if isinstance(el, dict) and 'name' in el:
            items.append({
                'name': str(el.get('name', '')),
                'count': int(el.get('count', 1)) if isinstance(el.get('count'), (int, float)) else 1,
                'glow': bool(el.get('glow', False)),
            })
        else:
            items.append({'name': str(el)[:80], 'count': 1, 'glow': False})
    return items


@app.route('/')
def index():
    return render_template('index.html')


@app.route('/collection', methods=['GET', 'POST'])
def collection():
    if request.method == 'GET':
        return render_template(
            'collection.html',
            result=None,
            items=None,
            total_count=None,
            created_save=None,
            error=None,
        )

    if request.form.get('action') == 'create':
        collection_data = []
        for i in range(1, 4):
            name = request.form.get(f'item{i}_name', '').strip() or f'Предмет {i}'
            try:
                count = int(request.form.get(f'item{i}_count', 1))
                count = max(1, min(count, 99))
            except (TypeError, ValueError):
                count = 1
            glow = request.form.get(f'item{i}_glow') == 'on'
            collection_data.append({'name': name, 'count': count, 'glow': glow})

        shift = random.randint(1, 255)
        save_str = serialize_collection(collection_data, shift)
        items = normalize_items(collection_data)
        total_count = sum(item['count'] for item in items)
        return render_template(
            'collection.html',
            result=f'Коллекция создана! Морских огурцов: {total_count}',
            items=items,
            total_count=total_count,
            created_save=save_str,
            error=None,
        )

    raw = request.form.get('save_data', '').strip()
    if not raw:
        return render_template(
            'collection.html',
            result=None,
            items=None,
            total_count=None,
            created_save=None,
            error='Пришлите сохранение (сдвиг:данные в base64).',
        )

    collection_data, err = deserialize_save(raw)
    if err:
        return render_template(
            'collection.html',
            result=None,
            items=None,
            total_count=None,
            created_save=None,
            error=err,
        )

    items = normalize_items(collection_data)
    total_count = sum(item['count'] for item in items)
    return render_template(
        'collection.html',
        result=f'Коллекция загружена! Морских огурцов: {total_count}',
        items=items,
        total_count=total_count,
        created_save=None,
        error=None,
    )


@app.route('/collection/example')
def collection_example():
    shift = 42
    example_save = serialize_collection(EXAMPLE_COLLECTION, shift)
    total_count = sum(item['count'] for item in EXAMPLE_COLLECTION)
    return render_template(
        'example.html',
        example_save=example_save,
        items=EXAMPLE_COLLECTION,
        total_count=total_count,
    )


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=False)
