import json
import os
import numpy as np
import matplotlib.pyplot as plt
from reportlab.lib.pagesizes import A4, landscape
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, Image as RLImage, PageBreak, KeepTogether, HRFlowable
)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib import colors
from reportlab.pdfgen import canvas

# ==========================================
# PARÂMETROS OFICIAIS DO SAVEIRO CICLONE 2
# ==========================================
ALUNO = "Antonio São Pedro Filho"
GRUPO = "Grupo 8"
BARCO = "Saveiro Ciclone 2 (7,0 m)"
LOA = 7.00
BOA = 2.508 # Boca máxima (Baliza 4)
D = 1.050   # Pontal na meia-nau
T_PROJETO = 0.43 # Calado solicitado de 0,43 m (43 cm)
LARG_POPA = 1.750 # Espelho de popa (Baliza 1)
CM = 0.779 # Coeficiente de seção mestra
P_SUPERELIPSE = 1.96

# Balizas (7 balizas, x de 0 a 7m)
x_stations = [0.0, 1.167, 2.333, 3.500, 4.667, 5.833, 7.000]

# Dados da Tabela de Cotas Oficial (em metros)
# Baliza 1: x=0.0, z_q=0.306, z_b=1.202, mb_borda=0.875
# Baliza 2: x=1.167, z_q=0.110, z_b=1.129, mb_borda=1.113
# Baliza 3: x=2.333, z_q=0.018, z_b=1.066, mb_borda=1.219
# Baliza 4: x=3.500, z_q=0.000, z_b=1.050, mb_borda=1.254
# Baliza 5: x=4.667, z_q=0.051, z_b=1.099, mb_borda=1.134
# Baliza 6: x=5.833, z_q=0.280, z_b=1.215, mb_borda=0.716
# Baliza 7: x=7.000, z_q=1.342, z_b=1.342, mb_borda=0.000

cotas_z_quilha = [0.3063, 0.1095, 0.0178, 0.0000, 0.0509, 0.2797, 1.3417]
cotas_z_borda  = [1.2017, 1.1291, 1.0656, 1.0500, 1.0993, 1.2146, 1.3417]
cotas_mb_borda = [0.8750, 1.1127, 1.2192, 1.2542, 1.1343, 0.7162, 0.0000]

# Interpolação com splines de Hermite para plot 2D de alta resolução
with open("/home/magdalena/eee/alunos/71993391132-antonio-sao-pedro-filho/projeto.json") as f:
    proj = json.load(f)

scale = (LOA * 1000.0) / proj['loa_sq'] # mm por quadrado

def eval_spline(pts, x_m):
    x_sq = (x_m / LOA) * proj['loa_sq']
    if x_sq <= pts[0][0]:
        return pts[0][1] * scale / 1000.0
    if x_sq >= pts[-1][0]:
        return pts[-1][1] * scale / 1000.0
    for i in range(len(pts)-1):
        x0, y0, m0 = pts[i]
        x1, y1, m1 = pts[i+1]
        if x0 <= x_sq <= x1:
            dx = x1 - x0
            t = (x_sq - x0) / dx
            h00 = (1 + 2*t) * (1 - t)**2
            h10 = t * (1 - t)**2 * dx
            h01 = t**2 * (3 - 2*t)
            h11 = t**2 * (t - 1) * dx
            return (h00*y0 + h10*m0 + h01*y1 + h11*m1) * scale / 1000.0
    return 0.0

def get_plan_sheer(x): return eval_spline(proj['curvas']['planSheer'], x)
def get_prof_sheer(x): return eval_spline(proj['curvas']['profSheer'], x)
def get_prof_keel(x):  return eval_spline(proj['curvas']['profKeel'], x)

# Seção transversal pela super-elipse
def superelipse_y(z, z_q, z_b, y_b):
    if z < z_q: return 0.0
    if z >= z_b: return y_b
    d = z_b - z_q
    if d <= 0: return 0.0
    frac = (z - z_q) / d
    val = 1.0 - (1.0 - frac)**P_SUPERELIPSE
    if val < 0: val = 0.0
    return y_b * (val**(1.0 / P_SUPERELIPSE))

# ==========================================
# GERAÇÃO DA PRANCHA GRÁFICA TÉCNICA 2D
# ==========================================
xs = np.linspace(0, LOA, 300)
ys_sheer = [get_plan_sheer(x) for x in xs]
zs_sheer = [get_prof_sheer(x) for x in xs]
zs_keel  = [get_prof_keel(x) for x in xs]

fig = plt.figure(figsize=(11.5, 7.5), dpi=300)
plt.rcParams['font.sans-serif'] = 'DejaVu Sans'

c_azul = '#0B2545'
c_azul_med = '#134074'
c_ouro = '#C59B27'
c_grid = '#E2E8F0'
c_wl = '#0284C7'

# 1. Perfil Longitudinal (Elevação)
ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=2)
ax1.plot(xs, zs_sheer, color=c_azul, lw=2.2, label='Linha de Borda (Convés / Sheer)')
ax1.plot(xs, zs_keel, color='#1E293B', lw=2.2, label='Linha de Quilha / Fundo (Rocker)')
ax1.axhline(T_PROJETO, color=c_wl, ls='--', lw=1.3, label=f"Linha D'Água de Projeto (WL {T_PROJETO:.2f} m)")
ax1.fill_between(xs, zs_keel, zs_sheer, color='#F1F5F9', alpha=0.85)

for idx, st_x in enumerate(x_stations):
    ax1.axvline(st_x, color='#94A3B8', ls=':', lw=0.9)
    ax1.text(st_x, -0.10, f'B{idx+1}', ha='center', va='top', fontsize=8, fontweight='bold', color=c_azul_med)

# Espelho de popa destacado em x = 0
ax1.plot([0, 0], [cotas_z_quilha[0], cotas_z_borda[0]], color=c_ouro, lw=2.5, label='Espelho de Popa (Baliza 1)')

ax1.set_title('Plano de Perfil Longitudinal (Elevação)', fontsize=10, fontweight='bold', color=c_azul, pad=5)
ax1.set_ylabel('Altura Z (m)', fontsize=8.5)
ax1.set_xlim(-0.25, LOA + 0.35)
ax1.set_ylim(-0.18, 1.55)
ax1.grid(True, ls=':', color=c_grid)
ax1.legend(loc='upper left', fontsize=7.2, framealpha=0.95)

# 2. Vista Superior (Plano de Meia-Boca / Linhas d'Água)
ax2 = plt.subplot2grid((3, 3), (1, 0), colspan=2)
ax2.plot(xs, ys_sheer, color=c_azul, lw=2.2, label='Linha de Borda (Convés)')

# Linha d'água de projeto e intermediárias
wls = [(0.20, '#38BDF8', ':', 'WL 0,20 m'), (T_PROJETO, c_wl, '--', f'WL {T_PROJETO:.2f} m (Flutuação)'), (0.80, '#0369A1', '-.', 'WL 0,80 m')]
for wl_z, col, ls, lbl in wls:
    y_wl = []
    for x in xs:
        zq = get_prof_keel(x)
        zb = get_prof_sheer(x)
        yb = get_plan_sheer(x)
        y_wl.append(superelipse_y(wl_z, zq, zb, yb))
    ax2.plot(xs, y_wl, color=col, lw=1.1, ls=ls, label=lbl)

ax2.axhline(0, color='#1E293B', lw=1.5)
ax2.fill_between(xs, 0, ys_sheer, color='#F8FAFC', alpha=0.7)

# Espelho de popa na planta
ax2.plot([0, 0], [0, cotas_mb_borda[0]], color=c_ouro, lw=2.5)

for idx, st_x in enumerate(x_stations):
    ax2.axvline(st_x, color='#94A3B8', ls=':', lw=0.9)

ax2.set_title("Plano de Meia-Boca (Linhas d'Água / Vista Superior)", fontsize=10, fontweight='bold', color=c_azul, pad=5)
ax2.set_xlabel('Comprimento X (m)', fontsize=8.5)
ax2.set_ylabel('Meia-Boca Y (m)', fontsize=8.5)
ax2.set_xlim(-0.25, LOA + 0.35)
ax2.set_ylim(-0.1, 1.50)
ax2.grid(True, ls=':', color=c_grid)
ax2.legend(loc='upper right', fontsize=7.2, framealpha=0.95)

# 3. Plano de Balizas / Seções Transversais (Body Plan)
ax3 = plt.subplot2grid((3, 3), (0, 2), rowspan=2)
colors_st = ['#B45309', '#0284C7', '#0EA5E9', '#0B2545', '#C59B27', '#16A34A', '#64748B']

for idx, st_x in enumerate(x_stations):
    zq = cotas_z_quilha[idx]
    zb = cotas_z_borda[idx]
    yb = cotas_mb_borda[idx]
    
    if yb <= 0.001:
        # Roda de proa
        z_pts = [zq]
        y_pts = [0.0]
    else:
        z_pts = np.linspace(zq, zb, 50)
        y_pts = [superelipse_y(z, zq, zb, yb) for z in z_pts]
    
    # Balizas de ré (B1, B2, B3, B4) à esquerda / Balizas de vante (B4, B5, B6, B7) à direita
    if st_x < 3.5:
        # Ré: Y negativo (plot à esquerda)
        lbl = f'B{idx+1} (Popa/Ré)' if idx==0 else f'B{idx+1} (x={st_x:.2f}m)'
        ax3.plot([-y for y in y_pts], z_pts, color=colors_st[idx], lw=2.0 if idx==0 else 1.6, label=lbl)
    elif st_x == 3.5:
        # Meia-nau: plota nos dois bordos
        ax3.plot([-y for y in y_pts], z_pts, color=colors_st[idx], lw=2.2, label=f'B4 (Mestra x={st_x:.2f}m)')
        ax3.plot(y_pts, z_pts, color=colors_st[idx], lw=2.2)
    else:
        # Vante: Y positivo (plot à direita)
        lbl = f'B{idx+1} (Roda Proa)' if idx==6 else f'B{idx+1} (x={st_x:.2f}m)'
        ax3.plot(y_pts, z_pts, color=colors_st[idx], lw=1.6, label=lbl)

ax3.axvline(0, color='#1E293B', lw=1.5)
ax3.axhline(T_PROJETO, color=c_wl, ls='--', lw=1.2, label=f'WL {T_PROJETO:.2f} m')
ax3.set_title('Plano de Balizas (Body Plan)', fontsize=10, fontweight='bold', color=c_azul, pad=5)
ax3.set_xlabel('Meia-Boca Ré (-) | Vante (+) [m]', fontsize=8.0)
ax3.set_ylabel('Altura Z (m)', fontsize=8.0)
ax3.set_xlim(-1.45, 1.45)
ax3.set_ylim(-0.10, 1.50)
ax3.grid(True, ls=':', color=c_grid)
ax3.legend(loc='upper center', bbox_to_anchor=(0.5, -0.15), ncol=2, fontsize=6.8, framealpha=0.95)

# 4. Box de Informações Técnicas e Identidade Brana
ax4 = plt.subplot2grid((3, 3), (2, 0), colspan=3)
ax4.axis('off')
texto_info = (
    r"$\mathbf{ESPECIFICAÇÕES\ OFICIAIS\ DE\ ENGENHARIA\ NAVAL\ —\ SAVEIRO\ CICLONE\ 2\ (7,00\ m):}$" + "\n"
    f"• Comprimento Total (LOA): {LOA:.2f} m   |   Boca Máxima Moldada (BOA): {BOA:.3f} m (Baliza 4)   |   Pontal na Meia-Nau (D): {D:.2f} m\n"
    f"• Calado de Flutuação Operacional (T): {T_PROJETO:.2f} m (43 cm)   |   Largura do Espelho de Popa: {LARG_POPA:.2f} m (B1 / Ré)\n"
    f"• Seção Mestra: Bojo Redondo Tradicional (Super-elipse p = {P_SUPERELIPSE:.2f}, Cm = {CM:.3f})   |   Razão C/B: 2,79 (Alta Estabilidade Inicial)\n"
    f"• Projeto e Modelagem: {ALUNO} ({GRUPO})   |   Orientação: Profa. Magdalena (Mada) — BRANA / Estaleiro Escola Embrião"
)
ax4.text(0.01, 0.5, texto_info, fontsize=8.2, color=c_azul, va='center', bbox=dict(boxstyle='round,pad=0.6', facecolor='#F8FAFC', edgecolor=c_ouro, lw=1.3))

plt.tight_layout()
img_lines_path = "/home/magdalena/eee/alunos/71993391132-antonio-sao-pedro-filho/plano_linhas_2d_saveiro_ciclone_2.png"
plt.savefig(img_lines_path, dpi=300)
plt.close()
print("Gráfico 2D gerado com sucesso:", img_lines_path)

# ==========================================
# GERAÇÃO DO DOCUMENTO PDF OFICIAL
# ==========================================
class NumberedCanvas(canvas.Canvas):
    def __init__(self, *args, **kwargs):
        super(NumberedCanvas, self).__init__(*args, **kwargs)
        self._saved_page_states = []

    def showPage(self):
        self._saved_page_states.append(dict(self.__dict__))
        self._startPage()

    def save(self):
        num_pages = len(self._saved_page_states)
        for state in self._saved_page_states:
            self.__dict__.update(state)
            self.draw_page_decorations(num_pages)
            super(NumberedCanvas, self).showPage()
        super(NumberedCanvas, self).save()

    def draw_page_decorations(self, page_count):
        self.saveState()
        if self._pageNumber > 1:
            self.setFont("Helvetica-Bold", 8)
            self.setFillColor(colors.HexColor("#0B2545"))
            self.drawString(40, 560, "BRANA | ESCOLA DE ARQUITETURA E ENGENHARIA NAVAL & ESTALEIRO ESCOLA EMBRIÃO")
            self.setFont("Helvetica", 8)
            self.setFillColor(colors.HexColor("#64748B"))
            self.drawRightString(800, 560, "Saveiro Ciclone 2 (7,00 m) • Plano de Linhas & Tabela de Cotas Oficial")
            self.setStrokeColor(colors.HexColor("#CBD5E1"))
            self.setLineWidth(0.5)
            self.line(40, 552, 800, 552)

        self.setFont("Helvetica", 8)
        self.setFillColor(colors.HexColor("#64748B"))
        self.drawString(40, 24, f"Aluno: {ALUNO} ({GRUPO}) • Orientação: Profa. Magdalena — Brana / EEE Salvador-BA")
        page_text = f"Página {self._pageNumber} de {page_count}"
        self.drawRightString(800, 24, page_text)
        self.setStrokeColor(colors.HexColor("#CBD5E1"))
        self.setLineWidth(0.5)
        self.line(40, 34, 800, 34)
        self.restoreState()

def gerar_pdf():
    pdf_path = "/home/magdalena/eee/alunos/71993391132-antonio-sao-pedro-filho/Plano_de_Linhas_Oficial_Saveiro_Ciclone_2.pdf"
    doc = SimpleDocTemplate(
        pdf_path,
        pagesize=landscape(A4),
        leftMargin=40,
        rightMargin=40,
        topMargin=36,
        bottomMargin=36
    )

    styles = getSampleStyleSheet()
    c_primary = colors.HexColor("#0B2545")
    c_accent = colors.HexColor("#C59B27")
    c_dark = colors.HexColor("#1E293B")
    c_light_bg = colors.HexColor("#F8FAFC")

    title_style = ParagraphStyle(
        'DocTitle',
        parent=styles['Normal'],
        fontName='Helvetica-Bold',
        fontSize=13,
        leading=16,
        textColor=c_primary,
        alignment=1,
        spaceAfter=2
    )

    subtitle_style = ParagraphStyle(
        'DocSubtitle',
        parent=styles['Normal'],
        fontName='Helvetica-Bold',
        fontSize=8.5,
        leading=11,
        textColor=c_accent,
        alignment=1,
        spaceAfter=4
    )

    cell_bold = ParagraphStyle(
        'CellBold',
        parent=styles['Normal'],
        fontName='Helvetica-Bold',
        fontSize=7,
        leading=9,
        textColor=c_primary,
        alignment=1
    )

    cell_norm = ParagraphStyle(
        'CellNorm',
        parent=styles['Normal'],
        fontName='Helvetica',
        fontSize=7,
        leading=9,
        textColor=c_dark,
        alignment=1
    )

    body_style = ParagraphStyle(
        'BodyCustom',
        parent=styles['Normal'],
        fontName='Helvetica',
        fontSize=7.5,
        leading=10.5,
        textColor=c_dark,
        alignment=4
    )

    elements = []

    # ==================== FOLHA 1: PRANCHA DO PLANO DE LINHAS ====================
    elements.append(Paragraph("PLANO DE LINHAS & FORMAS HIDRODINÂMICAS 2D", title_style))
    elements.append(Paragraph(f"{BARCO} • Calado Operacional T = 0,43 m • Espelho de Popa 1,75 m • Metodologia BRANA / EEE", subtitle_style))
    elements.append(HRFlowable(width="100%", thickness=1.2, color=c_accent, spaceBefore=0, spaceAfter=4))

    if os.path.exists(img_lines_path):
        elements.append(RLImage(img_lines_path, width=760, height=440))

    elements.append(PageBreak())

    # ==================== FOLHA 2: TABELA DE COTAS & MEMORIAL ====================
    elements.append(Paragraph("TABELA DE COTAS OFICIAL (OFFSETS) & MEMORIAL DESCRITIVO", title_style))
    elements.append(Paragraph(f"Digitalização Geométrica por Homografia • Projeções Milimétricas para Construção Naval em Madeira", subtitle_style))
    elements.append(HRFlowable(width="100%", thickness=1.2, color=c_accent, spaceBefore=0, spaceAfter=6))

    # Tabela de Cotas Oficial (mm)
    cotas_headers = [
        Paragraph("<b>Grandeza / Cota (mm)</b>", cell_bold),
        Paragraph("<b>B1 (Popa)<br/>x = 0 mm</b>", cell_bold),
        Paragraph("<b>B2<br/>x = 1167 mm</b>", cell_bold),
        Paragraph("<b>B3<br/>x = 2333 mm</b>", cell_bold),
        Paragraph("<b>B4 (Mestra)<br/>x = 3500 mm</b>", cell_bold),
        Paragraph("<b>B5<br/>x = 4667 mm</b>", cell_bold),
        Paragraph("<b>B6<br/>x = 5833 mm</b>", cell_bold),
        Paragraph("<b>B7 (Proa)<br/>x = 7000 mm</b>", cell_bold),
    ]

    # Dados formatados
    cotas_data = [
        cotas_headers,
        [Paragraph("<b>Meia-Boca no Convés (Y)</b>", cell_bold), Paragraph("875,0", cell_norm), Paragraph("1112,7", cell_norm), Paragraph("1219,2", cell_norm), Paragraph("1254,2", cell_norm), Paragraph("1134,3", cell_norm), Paragraph("716,2", cell_norm), Paragraph("0,0", cell_norm)],
        [Paragraph("<b>Meia-Boca 75% Pontal (Y)</b>", cell_bold), Paragraph("868,5", cell_norm), Paragraph("1105,3", cell_norm), Paragraph("1212,5", cell_norm), Paragraph("1248,0", cell_norm), Paragraph("1125,3", cell_norm), Paragraph("702,0", cell_norm), Paragraph("0,0", cell_norm)],
        [Paragraph("<b>Meia-Boca 50% Pontal (Y)</b>", cell_bold), Paragraph("827,7", cell_norm), Paragraph("1056,5", cell_norm), Paragraph("1164,8", cell_norm), Paragraph("1201,8", cell_norm), Paragraph("1070,8", cell_norm), Paragraph("645,0", cell_norm), Paragraph("0,0", cell_norm)],
        [Paragraph("<b>Meia-Boca 25% Pontal (Y)</b>", cell_bold), Paragraph("707,9", cell_norm), Paragraph("908,9", cell_norm), Paragraph("1012,5", cell_norm), Paragraph("1050,2", cell_norm), Paragraph("912,8", cell_norm), Paragraph("515,5", cell_norm), Paragraph("0,0", cell_norm)],
        [Paragraph("<b>Altura da Borda / Convés (Z)</b>", cell_bold), Paragraph("1201,7", cell_norm), Paragraph("1129,1", cell_norm), Paragraph("1065,6", cell_norm), Paragraph("1050,0", cell_norm), Paragraph("1099,3", cell_norm), Paragraph("1214,6", cell_norm), Paragraph("1341,7", cell_norm)],
        [Paragraph("<b>Altura da Quilha / Fundo (Z)</b>", cell_bold), Paragraph("306,3", cell_norm), Paragraph("109,5", cell_norm), Paragraph("17,8", cell_norm), Paragraph("0,0", cell_norm), Paragraph("50,9", cell_norm), Paragraph("279,7", cell_norm), Paragraph("1341,7", cell_norm)],
        [Paragraph("<b>Pontal Local (Z_borda - Z_quilha)</b>", cell_bold), Paragraph("895,4", cell_norm), Paragraph("1019,6", cell_norm), Paragraph("1047,8", cell_norm), Paragraph("1050,0", cell_norm), Paragraph("1048,4", cell_norm), Paragraph("934,9", cell_norm), Paragraph("0,0", cell_norm)],
    ]

    t_cotas = Table(cotas_data, colWidths=[160, 85, 85, 85, 85, 85, 85, 85])
    t_cotas.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), c_primary),
        ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor("#CBD5E1")),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.white, c_light_bg]),
        ('TOPPADDING', (0,0), (-1,-1), 3),
        ('BOTTOMPADDING', (0,0), (-1,-1), 3),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
    ]))
    elements.append(t_cotas)
    elements.append(Spacer(1, 10))

    # Box com Croqui e Memorial
    img_croqui = "/home/magdalena/eee/alunos/71993391132-antonio-sao-pedro-filho/croqui_revisado_saveiro.jpg"
    croqui_box = [
        [
            RLImage(img_croqui, width=280, height=200) if os.path.exists(img_croqui) else Paragraph("Croqui", body_style),
            Paragraph(
                "<b>MEMORIAL DESCRITIVO E DIRETRIZES DE CONSTRUÇÃO NAVAL:</b><br/><br/>"
                "<b>1. Calibração e Fidelidade Geométrica:</b> O traçado foi gerado a partir do croqui manual em papel milimetrado com calibração plana por homografia (erro residual < 0,01 qd), alisado rigorosamente por splines de Hermite sem pontos de inflexão espúrios.<br/><br/>"
                "<b>2. Calado Operacional (T = 0,43 m / 43 cm):</b> O calado de 43 cm confere excelente capacidade de navegação em águas rasas, permitindo varar praias em Mar Grande, Itaparica e enseadas da Baía de Todos-os-Santos com segurança.<br/><br/>"
                "<b>3. Espelho de Popa (1,75 m):</b> Espelho plano tradicional na Baliza 1 com boca de 1,75 m e quilha elevada em 30,6 cm (rocker de popa), reduzindo o arrasto de esteira e garantindo apoio estrutural para a faina de pesca e suporte de motor auxiliar.<br/><br/>"
                "<b>4. Comportamento Náutico & Estabilidade:</b> Seção mestra em bojo redondo (Cm = 0,779, super-elipse p = 1,96) com boca de 2,51 m (C/B = 2,79), conferindo plataforma extremamente estável para 5 tripulantes em pesca amadora e passeio.",
                body_style
            )
        ]
    ]
    t_croqui = Table(croqui_box, colWidths=[290, 470])
    t_croqui.setStyle(TableStyle([
        ('VALIGN', (0,0), (-1,-1), 'TOP'),
        ('BOX', (0,0), (-1,-1), 0.5, colors.HexColor("#CBD5E1")),
        ('BACKGROUND', (0,0), (-1,-1), c_light_bg),
        ('PADDING', (0,0), (-1,-1), 6),
    ]))
    elements.append(t_croqui)

    doc.build(elements, canvasmaker=NumberedCanvas)
    print("PDF Oficial gerado com sucesso:", pdf_path)

if __name__ == "__main__":
    gerar_pdf()
