from datetime import datetime
from io import BytesIO
from time import time

from fastapi import APIRouter
from fastapi.responses import Response
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import ParagraphStyle
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer, Image

from app import mongo
from app.utils.response_util import response

router = APIRouter()


@router.get("/get-all", tags=[""])
async def get_all(with_placeholders: bool = True):
    start_time = time()

    services = await mongo.services_collection.find({}, {
        "_id": False
    }).sort("id", mongo.desc).to_list()

    return response({
        "services": services
    }, start_time=start_time)


@router.post("/create", tags=[""])
async def create(params: dict):
    start_time = time()
    data = params["service"]
    data["id"] = await mongo.get_next_id(mongo.services_collection)

    try:
        await mongo.services_collection.insert_one(data)

        return response({
            "message": "Сервис создан",
            "ok": True
        }, start_time=start_time)
    except Exception as e:
        return response({
            "message": str(e),
            "ok": False
        }, start_time=start_time, code=400)


@router.post("/update", tags=[""])
async def update(params: dict):
    start_time = time()
    data = params["data"]

    try:
        await mongo.services_collection.update_one({
            "id": data["id"]
        }, {
            "$set": data
        })

        return response({
            "message": "Данные сервиса обновлены",
            "ok": True
        }, start_time=start_time)
    except Exception as e:
        return response({
            "message": str(e),
            "ok": False
        }, start_time=start_time, code=400)


@router.post("/delete", tags=[""])
async def delete(params: dict):
    start_time = time()
    service_id = params["serviceId"]

    try:
        await mongo.services_collection.delete_one({
            "id": service_id
        })

        return response({
            "message": "Сервис удален",
            "ok": True
        }, start_time=start_time)
    except Exception as e:
        return response({
            "message": str(e),
            "ok": False
        }, start_time=start_time, code=400)


@router.get("/export-list/pdf", tags=[""])
async def export_list_pdf():
    pdfmetrics.registerFont(TTFont("Arial", "assets/arial.ttf"))
    pdfmetrics.registerFont(TTFont("Arial Bold", "assets/arial_bold.ttf"))

    center = ParagraphStyle(name="center", fontName="Arial", fontSize=10, alignment=1)
    title = ParagraphStyle(name="title", fontName="Arial Bold", fontSize=14, alignment=1)
    bold_center = ParagraphStyle(name="bold_center", fontName="Arial Bold", fontSize=10, alignment=1)
    left_align = ParagraphStyle(name="left_align", fontName="Arial", fontSize=10, alignment=0)
    right_align = ParagraphStyle(name="right_align", fontName="Arial", fontSize=10, alignment=2)

    services = await mongo.services_collection.find({}, {"_id": False}).to_list(length=None)
    categories = {}

    for service in services:
        category_name = service["category"]["name"]
        categories.setdefault(category_name, []).append(service)

    buffer = BytesIO()
    doc = SimpleDocTemplate(buffer, pagesize=A4, leftMargin=20, rightMargin=20, topMargin=30, bottomMargin=20)
    elements = []

    logo = Image("assets/logo.jpg", width=152, height=56)
    logo.hAlign = "LEFT"
    elements.append(logo)
    elements.append(Spacer(1, 10))

    elements.append(Paragraph("Общие услуги", title))
    elements.append(Spacer(1, 6))
    elements.append(Paragraph(f"Дата формирования: {datetime.now().strftime('%d.%m.%Y')}", center))
    elements.append(Spacer(1, 10))

    table_width = 480

    for category, service_list in categories.items():
        data = [[
            Paragraph("Услуга", bold_center),
            Paragraph("Цена", bold_center),
        ]]

        for service in service_list:
            name = service["name"]
            price_ranges = service.get("priceRanges", [])

            if price_ranges:
                prices = []
                for price_range in sorted(price_ranges, key=lambda x: x['fromQuantity']):
                    if price_range["toQuantity"] != 99999:
                        prices.append(f"{price_range['fromQuantity']} шт - {price_range['toQuantity']} шт: {price_range['price']} ₽")
                    else:
                        prices.append(f"от {price_range['fromQuantity']} шт: {price_range['price']} ₽")
                price_text = "<br />".join(prices)
            else:
                price_text = f"{service['price']} ₽"

            data.append([
                Paragraph(name, left_align),
                Paragraph(price_text, right_align),
            ])

        table = Table(data, colWidths=[table_width * 0.6, table_width * 0.4])
        table.setStyle(TableStyle([
            ("BOX", (0, 0), (-1, -1), 0.8, colors.black),
            ("INNERGRID", (0, 0), (-1, -1), 0.4, colors.grey),
            ("BACKGROUND", (0, 0), (0, 0), colors.lightgrey),
            ("ALIGN", (0, 0), (-1, -1), "CENTER"),
            ("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
            ("ROUNDEDCORNERS", (16, 16, 16, 16)),
        ]))

        elements.append(Paragraph(category, bold_center))
        elements.append(Spacer(1, 4))
        elements.append(table)
        elements.append(Spacer(1, 12))

    doc.build(elements)
    buffer.seek(0)
    return Response(buffer.getvalue(), media_type="application/pdf", headers={"Content-Disposition": "inline; filename=service_list.pdf"})
