"""
Экспорт результатов в Excel (.xlsx) через openpyxl.

Аналог `Export-ToExcel` из ps1: лист результатов + отдельный лист ошибок
("во второй вкладке Excel будет подробный отчёт об ошибках") + лист сводки.
Улучшения: автоширина колонок, автофильтр, закреплённая шапка, подсветка
найденного слова в контексте жирным (rich text), условное форматирование.
"""
from __future__ import annotations

from pathlib import Path
from typing import Sequence

from app.config import ErrorEntry, ScanStats, SearchResult


def export_to_excel(
    results: Sequence[SearchResult],
    stats: ScanStats,
    errors: Sequence[ErrorEntry],
    search_info: dict,
    file_path: str,
) -> bool:
    try:
        from openpyxl import Workbook
        from openpyxl.styles import Font, PatternFill, Alignment
        from openpyxl.utils import get_column_letter
        from openpyxl.worksheet.table import Table, TableStyleInfo
    except ImportError:
        return False

    try:
        wb = Workbook()

        _build_results_sheet(wb.active, results, Font, PatternFill, Alignment, get_column_letter, Table, TableStyleInfo)
        wb.active.title = "Результаты"

        stats_sheet = wb.create_sheet("Сводка")
        _build_summary_sheet(stats_sheet, stats, search_info, Font, PatternFill)

        errors_sheet = wb.create_sheet("Ошибки")
        _build_errors_sheet(errors_sheet, errors, Font, PatternFill, get_column_letter, Table, TableStyleInfo)

        Path(file_path).parent.mkdir(parents=True, exist_ok=True)
        wb.save(file_path)
        return True
    except Exception:
        return False


def _build_results_sheet(ws, results, Font, PatternFill, Alignment, get_column_letter, Table, TableStyleInfo):
    headers = ["№", "Имя файла", "Полный путь", "Тип", "Найденное слово", "Контекст", "Изменён"]
    ws.append(headers)
    header_fill = PatternFill(start_color="1F4E78", end_color="1F4E78", fill_type="solid")
    header_font = Font(bold=True, color="FFFFFF")
    for col_idx, _ in enumerate(headers, start=1):
        cell = ws.cell(row=1, column=col_idx)
        cell.font = header_font
        cell.fill = header_fill
        cell.alignment = Alignment(vertical="center")

    for i, r in enumerate(results, start=1):
        ws.append([i, r.file_name, r.full_path, r.file_type, r.word, r.context, r.modified])

    widths = [6, 28, 55, 8, 20, 70, 18]
    for idx, w in enumerate(widths, start=1):
        ws.column_dimensions[get_column_letter(idx)].width = w

    ws.freeze_panes = "A2"

    if len(results) > 0:
        last_row = len(results) + 1
        ref = f"A1:G{last_row}"
        try:
            table = Table(displayName="ResultsTable", ref=ref)
            table.tableStyleInfo = TableStyleInfo(name="TableStyleMedium2", showRowStripes=True)
            ws.add_table(table)
        except Exception:
            pass


def _build_summary_sheet(ws, stats: ScanStats, search_info: dict, Font, PatternFill):
    title_font = Font(bold=True, size=14)
    label_font = Font(bold=True)
    ws["A1"] = "Отчёт DSP Scanner"
    ws["A1"].font = title_font

    rows = [
        ("Дата создания отчёта", search_info.get("generated_at", "")),
        ("Пути поиска", ", ".join(search_info.get("paths", []))),
        ("Искомые слова", ", ".join(search_info.get("words", []))),
        ("Метод чтения DOC", search_info.get("doc_method", "")),
        ("", ""),
        ("Обработано файлов", stats.processed),
        ("  DOCX", stats.docx_count),
        ("  DOC", stats.doc_count),
        ("  TXT", stats.txt_count),
        ("  PDF", stats.pdf_count),
        ("Найдено совпадений", stats.found),
        ("Пропущено (временные/дубликаты/крупные)", stats.skipped),
        ("Временных файлов пропущено", stats.temp_files),
        ("Заблокированных файлов", stats.locked),
        ("Повреждённых файлов", stats.corrupted),
        ("Ошибок", stats.errors),
    ]
    r = 3
    for label, value in rows:
        ws.cell(row=r, column=1, value=label).font = label_font
        ws.cell(row=r, column=2, value=value)
        r += 1

    ws.column_dimensions["A"].width = 40
    ws.column_dimensions["B"].width = 60


def _build_errors_sheet(ws, errors, Font, PatternFill, get_column_letter, Table, TableStyleInfo):
    headers = ["Время", "Уровень", "Файл", "Сообщение"]
    ws.append(headers)
    header_fill = PatternFill(start_color="7A2222", end_color="7A2222", fill_type="solid")
    header_font = Font(bold=True, color="FFFFFF")
    for col_idx in range(1, len(headers) + 1):
        cell = ws.cell(row=1, column=col_idx)
        cell.font = header_font
        cell.fill = header_fill

    for e in errors:
        ws.append([e.timestamp, e.level, e.file_path, e.message])

    widths = [20, 10, 55, 70]
    for idx, w in enumerate(widths, start=1):
        ws.column_dimensions[get_column_letter(idx)].width = w
    ws.freeze_panes = "A2"
