"""
FastAPI Server for Konica Minolta Ink Estimation Tool
Provides REST API endpoints and serves the modern Web UI.
"""

import os
import tempfile
import json
from typing import Optional
from fastapi import FastAPI, File, UploadFile, Form, HTTPException, Response
from fastapi.staticfiles import StaticFiles
from fastapi.responses import HTMLResponse, StreamingResponse
from fastapi.middleware.cors import CORSMiddleware

from engine.estimator import InkEstimator
from engine.profile_manager import ProfileManager
from engine.report_generator import ReportGenerator

app = FastAPI(
    title="Konica Minolta Ink Estimation Application",
    description="Next-generation web-based ink consumption and cost prediction tool for KM-1 press.",
    version="2.0.0"
)

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"]
)

# Initialize estimator
estimator = InkEstimator()
profile_mgr = ProfileManager()

# Mount static files directory
STATIC_DIR = os.path.join(os.path.dirname(__file__), "..", "static")
os.makedirs(STATIC_DIR, exist_ok=True)
app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")


@app.get("/api/presets")
def get_presets():
    """Returns available configuration presets."""
    return profile_mgr.list_options()


@app.post("/api/estimate")
async def estimate_ink(
    file: UploadFile = File(...),
    mode: int = Form(1),
    media: int = Form(1),
    quality: int = Form(1),
    dpi: float = Form(300.0),
    use_icc: bool = Form(True),
    quantity: int = Form(1000),
    duplex: bool = Form(False),
    cost_cyan: float = Form(120.0),
    cost_magenta: float = Form(120.0),
    cost_yellow: float = Form(120.0),
    cost_black: float = Form(100.0),
    currency: str = Form("EUR"),
    currency_symbol: str = Form("€")
):
    """
    Uploads a PDF or TIFF file and runs ink estimation.
    Returns complete volumetric and cost analysis.
    """
    ext = os.path.splitext(file.filename)[1].lower()
    if ext not in [".pdf", ".tif", ".tiff"]:
        raise HTTPException(status_code=400, detail="Invalid file format. Please upload a PDF or TIFF.")

    # Save to temp file
    with tempfile.NamedTemporaryFile(delete=False, suffix=ext) as tmp:
        content = await file.read()
        tmp.write(content)
        tmp_path = tmp.name

    try:
        costs = {
            "cyan": cost_cyan,
            "magenta": cost_magenta,
            "yellow": cost_yellow,
            "black": cost_black
        }

        result = estimator.estimate_document(
            filepath=tmp_path,
            mode=mode,
            media=media,
            quality=quality,
            dpi=dpi,
            use_icc=use_icc,
            quantity=quantity,
            duplex=duplex,
            cost_per_liter=costs,
            currency=currency,
            currency_symbol=currency_symbol,
            generate_previews=True
        )

        # Restore original filename in result
        result["document"]["filename"] = file.filename
        return result

    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))
    finally:
        if os.path.exists(tmp_path):
            os.remove(tmp_path)


@app.post("/api/export/pdf")
async def export_pdf(data: dict):
    """Exports estimation result as a PDF report."""
    try:
        pdf_bytes = ReportGenerator.generate_pdf(data)
        filename = f"Ink_Estimate_{os.path.splitext(data['document']['filename'])[0]}.pdf"
        return Response(
            content=pdf_bytes,
            media_type="application/pdf",
            headers={"Content-Disposition": f'attachment; filename="{filename}"'}
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@app.post("/api/export/xlsx")
async def export_xlsx(data: dict):
    """Exports estimation result as an Excel (.xlsx) workbook."""
    try:
        xlsx_bytes = ReportGenerator.generate_excel(data)
        filename = f"Ink_Estimate_{os.path.splitext(data['document']['filename'])[0]}.xlsx"
        return Response(
            content=xlsx_bytes,
            media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            headers={"Content-Disposition": f'attachment; filename="{filename}"'}
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@app.get("/", response_class=HTMLResponse)
def index():
    """Serves the main application frontend."""
    index_path = os.path.join(STATIC_DIR, "index.html")
    if os.path.exists(index_path):
        with open(index_path, "r", encoding="utf-8") as f:
            return f.read()
    return "<h1>Ink Estimation Tool Backend is Running</h1><p>Visit /docs for API documentation.</p>"
