import os
from io import BytesIO
from uuid import uuid4

from flask import flash, redirect, render_template, request, url_for
from werkzeug.utils import secure_filename

from app.admin import admin_blueprint
from app.admin.auth import admin_login_required
from config.aws_config import get_aws_settings, get_s3_client
from models.user_model import get_site_assets, update_site_asset


ALLOWED_EXTENSIONS = {"jpg", "jpeg", "png"}
MAX_FILE_SIZE = 5 * 1024 * 1024  # 5MB
ASSET_RULES = {
    "logo": {"label": "Site Logo", "width": 320, "height": 120},
    "header": {"label": "Header Image", "width": 1200, "height": 250},
    "footer": {"label": "Footer Image", "width": 1200, "height": 150},
    "watermark": {"label": "Watermark Image", "width": 400, "height": 150},
    "hero_bg": {"label": "Hero Background", "width": 1920, "height": 800},
    "cover": {"label": "Cover Image", "width": 1920, "height": 600},
}


def allowed_file(filename):
    """Check if file has an allowed extension."""
    return "." in filename and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS


def upload_to_s3(file_object, folder_name="others"):
    """Upload a file to S3 and return the public URL."""
    try:
        settings = get_aws_settings()
        s3_client = get_s3_client()

        original_filename = secure_filename(file_object.filename or "image.jpg")
        unique_filename = f"{uuid4().hex}_{original_filename}"
        s3_key = f"{folder_name}/{unique_filename}"

        file_object.seek(0)
        s3_client.upload_fileobj(
            Fileobj=file_object,
            Bucket=settings.s3_bucket,
            Key=s3_key,
            ExtraArgs={"ContentType": file_object.content_type or "image/jpeg"},
        )

        file_url = f"https://{settings.s3_bucket}.s3.amazonaws.com/{s3_key}"
        return {"success": True, "url": file_url, "s3_key": s3_key}
    except Exception as exc:
        return {"success": False, "error": str(exc)}


@admin_blueprint.route("/banners", methods=["GET"])
@admin_login_required
def banners_page():
    """Display banners with current site assets."""
    all_assets = get_site_assets()
    print("Assets:", all_assets)  # Debug: Check what's coming from DB

    # Convert to dict for easy lookup (extract image_path from nested dict)
    assets_dict = {}
    for asset_type, asset_data in all_assets.items():
        if asset_data and "image_path" in asset_data:
            assets_dict[asset_type] = asset_data["image_path"]
        else:
            assets_dict[asset_type] = None

    return render_template(
        "banners.html",
        asset_rules=ASSET_RULES,
        assets=assets_dict,
    )


@admin_blueprint.route("/banners/update", methods=["POST"])
@admin_login_required
def update_banner():
    """Update banner image via URL or file upload to S3."""
    link_type = (request.form.get("link_type") or "").strip()
    image_url = (request.form.get("image_url") or "").strip()
    image_file = request.files.get("image_file")

    if link_type not in ASSET_RULES:
        flash("Unknown asset type.", "error")
        return redirect(url_for("admin.banners_page"))

    final_url = None

    # Priority 1: File upload to S3
    if image_file and image_file.filename:
        # Validate file extension
        if not allowed_file(image_file.filename):
            flash("Only JPG, JPEG, and PNG files are allowed.", "error")
            return redirect(url_for("admin.banners_page"))

        # Validate file size
        image_file.seek(0, os.SEEK_END)
        file_size = image_file.tell()
        image_file.seek(0)

        if file_size > MAX_FILE_SIZE:
            flash(f"File size exceeds 5MB limit. Current size: {file_size / 1024 / 1024:.2f}MB", "error")
            return redirect(url_for("admin.banners_page"))

        if file_size == 0:
            flash("Uploaded file is empty.", "error")
            return redirect(url_for("admin.banners_page"))

        # Upload to S3
        upload_result = upload_to_s3(image_file, folder_name="others")

        if not upload_result["success"]:
            flash(f"Upload failed: {upload_result['error']}", "error")
            return redirect(url_for("admin.banners_page"))

        final_url = upload_result["url"]

    # Priority 2: Manual URL
    elif image_url:
        final_url = image_url

    # Error: Neither provided
    if not final_url:
        flash("Please provide an image URL or upload an image file.", "error")
        return redirect(url_for("admin.banners_page"))

    # Save to event_site_assets table
    try:
        update_site_asset(link_type, final_url)
        print(f"Updated {link_type} with URL: {final_url}")  # Debug: Verify new URL is saved
        flash(f"{ASSET_RULES[link_type]['label']} updated successfully.", "success")
    except Exception as exc:
        flash(f"Failed to save: {exc}", "error")

    return redirect(url_for("admin.banners_page"))