from fastapi import APIRouter, HTTPException, Depends, File, Query, Form, UploadFile
from typing import Optional, Dict, Any
import json
import os
from sqlalchemy.orm import Session
from src.utils.db import get_db
from src.menu_design.apps.editor.models import Templates
import shutil
import json


router = APIRouter()

# Path to the static folder
STATIC_PATH = "./src/menu_design/designer/static/json"


def read_json_file(file_name):
    try:
        with open(os.path.join(STATIC_PATH, file_name), "r") as file:
            return json.load(file)  # Directly return the parsed JSON object
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error reading {file_name}: {str(e)}")

def paginate_array(data, size=30, index=0, keyword=''):
    start_index = index * size
    end_index = start_index + size
    # Filter objects where the keyword is found in the description or the data itself
    filtered = [item for item in data if keyword.lower() in item.get("desc", "").lower()]
    return filtered[start_index:end_index]


def search_keywords(query, data):
    if not query:
        return []
    query = query.lower()
    unique_keywords = {kw for item in data for kw in item.get("desc", "").lower().split() if query in kw}
    return [{"id": idx + 1, "name": kw} for idx, kw in enumerate(unique_keywords)]


# Fonts
@router.get("/fonts")
async def get_fonts(ps: int = 30, pi: int = 0, kw: str = ''):
    data = read_json_file("fonts.json").get("data", [])
    return paginate_array(data, ps, pi, kw)

@router.get("/draft-fonts")
async def get_draft_fonts():
    data = read_json_file("fonts.json").get("items", [])
    formatted = [
        {
            "family": font["family"],
            "styles": [{"name": f'{font["family"]} {style.capitalize()}', "style": style, "url": file}
                       for style, file in font.get("files", {}).items()]
        } for font in data
    ]
    return {"data": formatted}


# Templates
@router.get("/templates")
async def get_templates(ps: int = 30, pi: int = 0, kw: str = ''):
    data = read_json_file("templates.json").get("data", [])
    paginated_data = paginate_array(data, ps, pi, kw)
    return paginated_data


@router.get("/template-suggestion")
async def template_suggestion(kw: str):
    data = read_json_file("templates.json").get("data", [])
    return search_keywords(kw, data)


# Texts
@router.get("/texts")
async def get_texts(ps: int = 30, pi: int = 0, kw: str = ''):
    data = read_json_file("texts.json").get("data", [])
    return paginate_array(data, ps, pi, kw)

@router.get("/text-suggestion")
async def text_suggestion(kw: str):
    data = read_json_file("texts.json").get("data", [])
    return search_keywords(kw, data)


# Images
@router.get("/images")
async def get_images(ps: int = 30, pi: int = 0, kw: str = ''):
    data = read_json_file("images.json").get("data", [])
    return paginate_array(data, ps, pi, kw)

@router.get("/image-suggestion")
async def image_suggestion(kw: str):
    data = read_json_file("images.json").get("data", [])
    return search_keywords(kw, data)


# Frames
@router.get("/frames")
async def get_frames(ps: int = 30, pi: int = 0, kw: str = ''):
    data = read_json_file("frames.json").get("data", [])
    return paginate_array(data, ps, pi, kw)

@router.get("/frame-suggestion")
async def frame_suggestion(kw: str):
    data = read_json_file("frames.json").get("data", [])
    return search_keywords(kw, data)


# Shapes
@router.get("/shapes")
async def get_shapes(ps: int = 30, pi: int = 0, kw: str = ''):
    data = read_json_file("shapes.json").get("data", [])
    return paginate_array(data, ps, pi, kw)

@router.get("/shape-suggestion")
async def shape_suggestion(kw: str):
    data = read_json_file("shapes.json").get("data", [])
    return search_keywords(kw, data)



@router.get("/db-templates", response_model=Dict[str, Any])
def get_all_templates(
    page: int = Query(1, description="Page number (starts from 1)", ge=1),
    page_size: int = Query(10, description="Number of records per page", ge=1, le=100),
    db: Session = Depends(get_db)
):
    # Pagination logic
    offset = (page - 1) * page_size

    total_templates = db.query(Templates).count()

    templates = (
        db.query(
            Templates.template_id,
            Templates.template_name,
            Templates.template_url,
            Templates.template_metadata
        )
        .offset(offset)
        .limit(page_size)
        .all()
    )

    return {
        "status": True,
        "page": page,
        "page_size": page_size,
        "total": total_templates,
        "data": [
            {
                "template_id": t.template_id,
                "template_name": t.template_name,
                "template_url": t.template_url,
                "template_metadata": t.template_metadata
            } for t in templates
        ]
    }



@router.get("/templates/{template_id}", response_model=dict)
def get_template_by_id(template_id: int, db: Session = Depends(get_db)):
    template = db.query(Templates).filter(Templates.template_id == template_id).first()

    if not template:
        raise HTTPException(status_code=404, detail="Template not found")

    return {
        "template_id": template.template_id,
        "template_name": template.template_name,
        "template_url": template.template_url,
        "template_data": template.template_data,
        "template_metadata": template.template_metadata,  
    }


BASE_URL = "https://hubwallet-dev.dreamztesting.com/static/template_images"


@router.post("/upload-template/")
async def upload_template(
    template_name: str = Form(...),
    template_metadata: str = Form(...),  # 🔥 Accept metadata as JSON string
    image_file: UploadFile = File(...),
    json_file: UploadFile = File(...),
    db: Session = Depends(get_db)
):
    # Validate image
    if not image_file.filename.lower().endswith((".png", ".jpg", ".jpeg")):
        raise HTTPException(status_code=400, detail="Invalid image file type")
    
    # Validate JSON file
    if not json_file.filename.lower().endswith(".json"):
        raise HTTPException(status_code=400, detail="Only JSON files are allowed")

    # Save image
    STATIC_PATH_TEMP_IMG = "./src/menu_design/designer/static/template_images"
    os.makedirs(STATIC_PATH_TEMP_IMG, exist_ok=True)
    image_path = os.path.join(STATIC_PATH_TEMP_IMG, image_file.filename)
    with open(image_path, "wb") as buffer:
        shutil.copyfileobj(image_file.file, buffer)

    image_url = f"{BASE_URL}/{image_file.filename}"

    # Load template_data JSON
    try:
        json_content = json.load(json_file.file)
        json_data_str = json.dumps(json_content)
    except Exception as e:
        raise HTTPException(status_code=400, detail=f"Invalid JSON in template file: {str(e)}")

    # Load template_metadata JSON
    try:
        metadata = json.loads(template_metadata)  # 🔥 Convert string to dict
    except Exception as e:
        raise HTTPException(status_code=400, detail=f"Invalid JSON in template_metadata: {str(e)}")

    # Save to DB
    template = Templates(
        template_name=template_name,
        template_url=image_url,
        template_data=json_data_str,
        template_metadata=json.dumps(metadata)

    )
    db.add(template)
    db.commit()
    db.refresh(template)

    return {
        "message": "Template uploaded successfully",
        "template_id": template.template_id,
        "template_url": template.template_url
    }
