from io import BytesIO

from flask import Blueprint, Response, current_app, jsonify, request
from flask_login import login_required

from app.labels.template_renderer import (
    DEFAULT_TEMPLATES, SAMPLE_FIELDS, TEMPLATE_FIELDS,
    get_template, render_template, render_template_preview, save_template,
)

label_templates_bp = Blueprint('label_templates', __name__)

_VALID = {'order_summary', 'order_item', 'product', 'product_sealed', 'digikey'}


@label_templates_bp.route('/label-templates/<name>/get')
@login_required
def get(name):
    if name not in _VALID:
        return jsonify(error='Not found'), 404
    db_path = current_app.config['DATABASE_PATH']
    elements = get_template(name, db_path)
    fields = TEMPLATE_FIELDS.get(name, [])
    return jsonify(elements=elements, fields=fields)


@label_templates_bp.route('/label-templates/<name>/preview.png', methods=['GET', 'POST'])
@login_required
def preview(name):
    """Server-render a preview PNG; POST body may contain custom {fields}."""
    if name not in _VALID:
        return jsonify(error='Not found'), 404
    db_path = current_app.config['DATABASE_PATH']
    elements = get_template(name, db_path)
    if request.method == 'POST':
        data = request.get_json(silent=True) or {}
        fields = {**SAMPLE_FIELDS.get(name, {}), **data.get('fields', {})}
    else:
        fields = SAMPLE_FIELDS.get(name, {})
    img = render_template_preview(elements, fields)
    buf = BytesIO()
    img.save(buf, format='PNG')
    buf.seek(0)
    return Response(
        buf.read(), mimetype='image/png',
        headers={'Cache-Control': 'no-store'},
    )


@label_templates_bp.route('/label-templates/<name>/save', methods=['POST'])
@login_required
def save(name):
    if name not in _VALID:
        return jsonify(error='Not found'), 404
    data = request.get_json(silent=True) or {}
    elements = data.get('elements', [])
    db_path = current_app.config['DATABASE_PATH']
    try:
        save_template(name, elements, db_path)
        return jsonify(ok=True)
    except Exception as e:
        return jsonify(ok=False, error=str(e)), 500


@label_templates_bp.route('/label-templates/<name>/reset', methods=['POST'])
@login_required
def reset(name):
    """Restore the built-in default template."""
    if name not in _VALID:
        return jsonify(error='Not found'), 404
    db_path = current_app.config['DATABASE_PATH']
    try:
        save_template(name, list(DEFAULT_TEMPLATES.get(name, [])), db_path)
        return jsonify(ok=True)
    except Exception as e:
        return jsonify(ok=False, error=str(e)), 500


@label_templates_bp.route('/label-templates/<name>/test-print', methods=['POST'])
@login_required
def test_print(name):
    """Print a sample label to the small printer."""
    if name not in _VALID:
        return jsonify(error='Not found'), 404
    from app.services import printer as printer_svc
    db_path = current_app.config['DATABASE_PATH']
    data = request.get_json(silent=True) or {}
    fields = {**SAMPLE_FIELDS.get(name, {}), **data.get('fields', {})}
    elements = get_template(name, db_path)
    img = render_template(elements, fields)
    try:
        printer_svc.print_label(img, printer='small', also_preview=True)
        return jsonify(ok=True)
    except Exception as e:
        return jsonify(ok=False, error=str(e)), 500
