"""Migration report generation (PDF + CSV) for sharing with clients."""
import io
import csv
from datetime import datetime

from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table,
                                TableStyle)


def _fmt_bytes(b):
    b = float(b or 0)
    if b == 0:
        return "0 B"
    units = ["B", "KB", "MB", "GB", "TB"]
    i = 0
    while b >= 1024 and i < len(units) - 1:
        b /= 1024.0
        i += 1
    return f"{b:.2f} {units[i]}" if i else f"{int(b)} {units[i]}"


def _fmt_dt(dt):
    if not dt:
        return "—"
    if isinstance(dt, str):
        return dt
    return dt.strftime("%d %b %Y, %H:%M UTC")


def _duration(m):
    if m.started_at and m.completed_at:
        secs = int((m.completed_at - m.started_at).total_seconds())
        h, rem = divmod(secs, 3600)
        mi, s = divmod(rem, 60)
        parts = []
        if h:
            parts.append(f"{h}h")
        if mi:
            parts.append(f"{mi}m")
        parts.append(f"{s}s")
        return " ".join(parts)
    return "—"


def build_csv(m, folders):
    buf = io.StringIO()
    w = csv.writer(buf)
    w.writerow(["Migration Report"])
    w.writerow(["Name", m.name])
    w.writerow(["Status", m.status])
    w.writerow(["Source", m.source_email])
    w.writerow(["Destination", m.dest_email])
    w.writerow(["Date range", f"{m.date_from.date() if m.date_from else 'all'} to {m.date_to.date() if m.date_to else 'all'}"])
    w.writerow(["Created", _fmt_dt(m.created_at)])
    w.writerow(["Started", _fmt_dt(m.started_at)])
    w.writerow(["Completed", _fmt_dt(m.completed_at)])
    w.writerow(["Duration", _duration(m)])
    w.writerow([])
    w.writerow(["Emails migrated", m.migrated_emails or 0])
    w.writerow(["Emails total", m.total_emails or 0])
    w.writerow(["Emails failed", m.failed_emails or 0])
    w.writerow(["Folders", f"{m.migrated_folders or 0}/{m.total_folders or 0}"])
    w.writerow(["Data transferred", _fmt_bytes(m.bytes_transferred)])
    if m.error:
        w.writerow(["Error", m.error])
    w.writerow([])
    w.writerow(["Folder", "Migrated", "Total", "Status"])
    for f in folders:
        w.writerow([f.name, f.migrated or 0, f.total or 0, f.status])
    return buf.getvalue()


def build_pdf(m, folders, site):
    brand = site.get("brand_color", "#2563EB") if site else "#2563EB"
    site_name = (site.get("site_name") if site else None) or "MailShift"
    try:
        brand_c = colors.HexColor(brand)
    except Exception:
        brand_c = colors.HexColor("#2563EB")

    buf = io.BytesIO()
    doc = SimpleDocTemplate(buf, pagesize=A4, topMargin=18 * mm, bottomMargin=16 * mm,
                            leftMargin=16 * mm, rightMargin=16 * mm, title=f"{m.name} — Migration Report")
    styles = getSampleStyleSheet()
    h_style = ParagraphStyle("h", parent=styles["Title"], textColor=brand_c, fontSize=20, spaceAfter=2)
    sub = ParagraphStyle("sub", parent=styles["Normal"], textColor=colors.HexColor("#64748B"), fontSize=9)
    label = ParagraphStyle("lbl", parent=styles["Normal"], textColor=colors.HexColor("#64748B"), fontSize=8)
    val = ParagraphStyle("val", parent=styles["Normal"], fontSize=10)
    story = []

    story.append(Paragraph(f"{site_name}", h_style))
    story.append(Paragraph("Email Migration Report", sub))
    story.append(Paragraph(f"Generated {datetime.utcnow().strftime('%d %b %Y, %H:%M UTC')}", sub))
    story.append(Spacer(1, 10 * mm))

    story.append(Paragraph(m.name, ParagraphStyle("mn", parent=styles["Heading2"], fontSize=14)))
    story.append(Paragraph(f"{m.source_email} &rarr; {m.dest_email}", val))
    story.append(Spacer(1, 6 * mm))

    date_range = "All emails"
    if m.date_from or m.date_to:
        date_range = f"{m.date_from.date() if m.date_from else 'beginning'} to {m.date_to.date() if m.date_to else 'now'}"

    info = [
        ["Status", (m.status or "").upper(), "Date range", date_range],
        ["Created", _fmt_dt(m.created_at), "Started", _fmt_dt(m.started_at)],
        ["Completed", _fmt_dt(m.completed_at), "Duration", _duration(m)],
    ]
    t = Table(info, colWidths=[26 * mm, 62 * mm, 26 * mm, 62 * mm])
    t.setStyle(TableStyle([
        ("FONTSIZE", (0, 0), (-1, -1), 9),
        ("TEXTCOLOR", (0, 0), (0, -1), colors.HexColor("#64748B")),
        ("TEXTCOLOR", (2, 0), (2, -1), colors.HexColor("#64748B")),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 6),
        ("LINEBELOW", (0, 0), (-1, -2), 0.4, colors.HexColor("#E2E8F0")),
    ]))
    story.append(t)
    story.append(Spacer(1, 8 * mm))

    # Summary metric cards row
    metrics = [
        ["Emails migrated", "Total emails", "Failed", "Data moved", "Folders"],
        [str(m.migrated_emails or 0), str(m.total_emails or 0), str(m.failed_emails or 0),
         _fmt_bytes(m.bytes_transferred), f"{m.migrated_folders or 0}/{m.total_folders or 0}"],
    ]
    mt = Table(metrics, colWidths=[36 * mm] * 5)
    mt.setStyle(TableStyle([
        ("FONTSIZE", (0, 0), (-1, 0), 7),
        ("FONTSIZE", (0, 1), (-1, 1), 13),
        ("FONTNAME", (0, 1), (-1, 1), "Helvetica-Bold"),
        ("TEXTCOLOR", (0, 0), (-1, 0), colors.HexColor("#64748B")),
        ("TEXTCOLOR", (0, 1), (-1, 1), brand_c),
        ("BACKGROUND", (0, 0), (-1, -1), colors.HexColor("#F8FAFC")),
        ("BOX", (0, 0), (-1, -1), 0.5, colors.HexColor("#E2E8F0")),
        ("INNERGRID", (0, 0), (-1, -1), 0.5, colors.HexColor("#E2E8F0")),
        ("TOPPADDING", (0, 0), (-1, -1), 8),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 8),
        ("ALIGN", (0, 0), (-1, -1), "CENTER"),
    ]))
    story.append(mt)
    story.append(Spacer(1, 8 * mm))

    if m.error:
        story.append(Paragraph(f"<b>Error:</b> {m.error}", ParagraphStyle(
            "err", parent=styles["Normal"], fontSize=9, textColor=colors.HexColor("#DC2626"))))
        story.append(Spacer(1, 6 * mm))

    story.append(Paragraph("Folder breakdown", ParagraphStyle("fh", parent=styles["Heading3"], fontSize=11)))
    story.append(Spacer(1, 2 * mm))
    rows = [["Folder", "Migrated", "Total", "Status"]]
    for f in folders:
        rows.append([f.name, str(f.migrated or 0), str(f.total or 0), f.status or "—"])
    if len(rows) == 1:
        rows.append(["No folder data", "", "", ""])
    ft = Table(rows, colWidths=[92 * mm, 28 * mm, 28 * mm, 28 * mm], repeatRows=1)
    ft.setStyle(TableStyle([
        ("FONTSIZE", (0, 0), (-1, -1), 8),
        ("BACKGROUND", (0, 0), (-1, 0), brand_c),
        ("TEXTCOLOR", (0, 0), (-1, 0), colors.white),
        ("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
        ("ROWBACKGROUNDS", (0, 1), (-1, -1), [colors.white, colors.HexColor("#F8FAFC")]),
        ("LINEBELOW", (0, 0), (-1, -1), 0.3, colors.HexColor("#E2E8F0")),
        ("TOPPADDING", (0, 0), (-1, -1), 5),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
    ]))
    story.append(ft)
    story.append(Spacer(1, 10 * mm))
    story.append(Paragraph(f"Report generated by {site_name}", sub))

    doc.build(story)
    return buf.getvalue()
