from fpdf import FPDF

import os
from datetime import datetime
from asgiref.sync import sync_to_async
from django.utils.timezone import make_aware, is_naive, is_aware
import os

# Определение абсолютного пути к папке "reports"
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
REPORTS_DIR = os.path.join(BASE_DIR, "reports")

# Убедитесь, что директория существует
os.makedirs(REPORTS_DIR, exist_ok=True)



# Асинхронная функция для извлечения данных о бронировании
def ensure_datetime(value):
    """Преобразует строку или naive datetime в timezone-aware datetime."""
    if isinstance(value, str):
        value = datetime.strptime(value, '%Y-%m-%d %H:%M:%S')
    if isinstance(value, datetime) and is_naive(value):
        value = make_aware(value)
    return value

@sync_to_async
def get_reservation_data(res):
    print(f"[DEBUG] Processing reservation {res.id}")
    
    # Убедитесь, что даты являются timezone-aware
    check_in = ensure_datetime(res.check_in)
    check_out = ensure_datetime(res.check_out)
    
    result = {
        "hotel_name": res.hotel.name,
        "pms": getattr(res.hotel, 'pms', 'N/A'),
        "reservation_id": res.reservation_id,
        "room_number": res.room_number if res.room_number else "Не указан",
        "room_type": res.room_type,
        "check_in": check_in,
        "check_out": check_out,
        "status": res.status,
    }
    # print(f"[DEBUG] Reservation data: {result}")
    return result



class CustomPDF(FPDF):
    def __init__(self, hotel_name, start_date, end_date, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.font_folder = "bot/fonts/"
        self.add_font("DejaVuSans-Bold", "", os.path.join(self.font_folder, "DejaVuSans-Bold.ttf"), uni=True)
        self.add_font("DejaVuSans", "", os.path.join(self.font_folder, "DejaVuSans.ttf"), uni=True)
        self.creation_date = datetime.now().strftime("%d.%m.%Y %H:%M:%S")
        
        # Переданные параметры
        self.hotel_name = hotel_name
        self.start_date = start_date
        self.end_date = end_date

    def header(self):
        """Добавление заголовка и заголовков таблицы на каждой странице."""
        # Заголовок отчёта
        if self.page == 1:  # Заголовок отчёта только на первой странице
            self.set_font("DejaVuSans-Bold", size=14)
            self.cell(0, 10, f"Отчет о бронированиях отеля {self.hotel_name}", ln=1, align="C")
            self.ln(5)

            self.set_font("DejaVuSans", size=10)
            self.cell(0, 10, f"за период {self.start_date.strftime('%Y-%m-%d %H:%M:%S')} - {self.end_date.strftime('%Y-%m-%d %H:%M:%S')}", ln=1, align="C")
            self.ln(10)

        # Заголовки таблицы
        self.set_font("DejaVuSans-Bold", size=8)
        headers = ["Отель", "№ бронирования", "№ комнаты", "Тип комнаты", "Заезд", "Выезд", "Статус"]
        col_widths = [30, 30, 30, 60, 35, 35, 30]
        row_height = 10

        for col_width, header in zip(col_widths, headers):
            self.cell(col_width, row_height, header, border=1, align="C")
        self.ln()

    def footer(self):
        """Добавление колонтитула внизу страницы."""
        self.set_y(-15)
        self.set_font("DejaVuSans", size=8)
        self.cell(60, 10, f"Copyright (C) 2024 by Touchh", align="L")
        self.cell(0, 10, f"Лист {self.page_no()} из {{nb}} / Дата генерации отчета: {self.creation_date}", align="C")
 


    def trim_text_right(self, text, max_width):
        """Обрезка текста справа."""
        while self.get_string_width(text) > max_width:
            text = text[:-1]
        return text + "..." if len(text) > 3 else text

async def generate_pdf_report(hotel_name, reservations, start_date, end_date):
    # Создание экземпляра PDF с передачей параметров
    pdf = CustomPDF(hotel_name=hotel_name, start_date=start_date, end_date=end_date, orientation="L", unit="mm", format="A4")
    pdf.alias_nb_pages()
    pdf.add_page()  # Заголовок отчёта и таблица будут добавлены через методы header и footer

    # Таблица
    pdf.set_font("DejaVuSans", size=8)
    col_widths = [30, 30, 30, 60, 35, 35, 30]
    row_height = 10

    for res in reservations:
        try:
            res_data = await get_reservation_data(res)

            row_data = [
                res_data["hotel_name"],
                str(res_data["reservation_id"]),
                res_data["room_number"],
                res_data["room_type"],
                res_data["check_in"].strftime('%Y-%m-%d %H:%M:%S'),
                res_data["check_out"].strftime('%Y-%m-%d %H:%M:%S'),
                res_data["status"],
            ]

            for col_width, data in zip(col_widths, row_data):
                pdf.cell(col_width, row_height, data, border=1, align="C")
            pdf.ln()
        except Exception as e:
            print(f"pdf_report.py [ERROR] Error processing reservation {res.id}: {e}")

    # Сохранение PDF
    hotel_name_safe = hotel_name.replace(" ", "_").replace("/", "_")
    start_date_str = start_date.strftime('%Y-%m-%d')
    end_date_str = end_date.strftime('%Y-%m-%d')

    pdf_output_path = os.path.join(REPORTS_DIR, f"{hotel_name_safe}_report_{start_date_str}-{end_date_str}.pdf")
    pdf.output(pdf_output_path)

    if not os.path.exists(pdf_output_path):
        raise RuntimeError(f"PDF file was not created at: {pdf_output_path}")

    return pdf_output_path


