import csv
from io import StringIO, BytesIO
from reportlab.lib import colors
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from django.utils import timezone
import os

FONT_PATH = os.path.join(os.path.dirname(__file__), 'fonts')
ARIAL_PATH = os.path.join(FONT_PATH, 'arialmt.ttf')
ARIAL_BOLD_PATH = os.path.join(FONT_PATH, 'arial_bolditalicmt.ttf')

if not os.path.exists(ARIAL_PATH) or not os.path.exists(ARIAL_BOLD_PATH):
    raise FileNotFoundError(
        f"Шрифты не найдены. Пожалуйста, убедитесь что файлы arialmt.ttf и arial_bolditalicmt.ttf "
        f"находятся в директории {FONT_PATH}"
    )

pdfmetrics.registerFont(TTFont('Arial', ARIAL_PATH))
pdfmetrics.registerFont(TTFont('Arial-Bold', ARIAL_BOLD_PATH))

styles = getSampleStyleSheet()
styles.add(ParagraphStyle(
    name='CustomNormal',
    fontName='Arial',
    fontSize=10,
    leading=12,
))
styles.add(ParagraphStyle(
    name='CustomHeading1',
    fontName='Arial-Bold',
    fontSize=14,
    leading=16,
))


def generate_csv_report(alerts):
    """Генерирует CSV отчет из списка алертов"""
    output = StringIO()
    writer = csv.writer(output)
    
    # заголовки
    headers = ['ID', 'Датчик', 'Объект', 'Значение', 'Тип датчика', 'Сообщение', 
              'Уровень важности', 'Дата создания', 'Обработан']
    writer.writerow(headers)
    
    # данные
    for alert in alerts:
        zone = alert.sensor.zones.first()
        object_name = zone.object.title if zone else 'Не указан'
        
        writer.writerow([
            alert.id,
            alert.sensor.name,
            object_name,
            f"{alert.metric.value} {alert.sensor.signal_format.unit if alert.sensor.signal_format else ''}" if alert.metric.value else alert.metric.raw_value,
            alert.sensor_type.name,
            alert.message,
            alert.severity,
            timezone.localtime(alert.created_at).strftime("%Y-%m-%d %H:%M:%S %Z"),
            'Да' if alert.resolved else 'Нет'
        ])
    
    return output.getvalue()

def generate_pdf_report(alerts):
    """Генерирует PDF отчет из списка алертов"""
    buffer = BytesIO()
    doc = SimpleDocTemplate(buffer, pagesize=letter)
    elements = []
    
    # заголовок
    title = Paragraph(
        f"Отчет по алертам (сгенерирован {timezone.localtime().strftime('%Y-%m-%d %H:%M %Z')})", 
        styles['CustomHeading1']
    )
    elements.append(title)
    
    # данные для таблицы
    headers = ['ID', 'Датчик', 'Объект', 'Значение', 'Тип датчика', 'Сообщение', 
              'Уровень', 'Дата создания', 'Обработан']
    
    # оборачиваем заголовки в параграф
    header_cells = [Paragraph(str(header), styles['CustomNormal']) for header in headers]
    data = [header_cells]
    
    for alert in alerts:
        zone = alert.sensor.zones.first()
        object_name = zone.object.title if zone else 'Не указан'
        
        # оборачиваем каждую ячейку в параграф
        row_data = [
            Paragraph(str(alert.id), styles['CustomNormal']),
            Paragraph(str(alert.sensor.name), styles['CustomNormal']),
            Paragraph(str(object_name), styles['CustomNormal']),
            Paragraph(
                str(f"{alert.metric.value} {alert.sensor.signal_format.unit if alert.sensor.signal_format else ''}" if alert.metric.value else alert.metric.raw_value),
                styles['CustomNormal']
            ),
            Paragraph(str(alert.sensor_type.name), styles['CustomNormal']),
            Paragraph(str(alert.message), styles['CustomNormal']),
            Paragraph(str(alert.severity), styles['CustomNormal']),
            Paragraph(timezone.localtime(alert.created_at).strftime("%Y-%m-%d %H:%M:%S %Z"), styles['CustomNormal']),
            Paragraph('Да' if alert.resolved else 'Нет', styles['CustomNormal'])
        ]
        data.append(row_data)
    
    # создаем таблицу
    table = Table(data)
    table.setStyle(TableStyle([
        # стиль заголовка
        ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#1b8755')),
        ('TEXTCOLOR', (0, 0), (-1, 0), colors.white),
        ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
        ('FONTSIZE', (0, 0), (-1, 0), 11),
        ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
        ('TOPPADDING', (0, 0), (-1, 0), 12),
        
        # стиль данных
        ('BACKGROUND', (0, 1), (-1, -1), colors.white),
        ('TEXTCOLOR', (0, 1), (-1, -1), colors.black),
        ('FONTSIZE', (0, 1), (-1, -1), 10), 
        ('ALIGN', (0, 0), (-1, -1), 'LEFT'), 
        ('GRID', (0, 0), (-1, -1), 1, colors.black),
        
        # отступы для всех ячеек
        ('LEFTPADDING', (0, 0), (-1, -1), 6),
        ('RIGHTPADDING', (0, 0), (-1, -1), 6),
        ('TOPPADDING', (0, 1), (-1, -1), 8),
        ('BOTTOMPADDING', (0, 1), (-1, -1), 8),
        
        # чередующиеся цвета строк для лучшей читаемости
        ('BACKGROUND', (0, 1), (-1, -1), colors.white),
        ('ROWBACKGROUNDS', (0, 1), (-1, -1), [colors.white, colors.HexColor('#f5f5f5')])
    ]))
    
    elements.append(table)
    doc.build(elements)
    
    return buffer.getvalue()
