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
)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib import colors

# Carrega projeto.json
caminho_projeto = '/home/magdalena/eee/alunos/andre-veleiro-40pe/projeto.json'
with open(caminho_projeto, 'r', encoding='utf-8') as f:
    proj = json.load(f)

def eval_hermite(p0, p1, m0, m1, x):
    dx = p1[0] - p0[0]
    if abs(dx) < 1e-9:
        return p0[1]
    t = (x - p0[0]) / dx
    h00 = 2*t**3 - 3*t**2 + 1
    h10 = t**3 - 2*t**2 + t
    h01 = -2*t**3 + 3*t**2
    h11 = t**3 - t**2
    return h00*p0[1] + h10*dx*m0 + h01*p1[1] + h11*dx*m1

def eval_curve(nodes, x):
    if x <= nodes[0][0]:
        return nodes[0][1]
    if x >= nodes[-1][0]:
        return nodes[-1][1]
    for i in range(len(nodes)-1):
        if nodes[i][0] <= x <= nodes[i+1][0]:
            return eval_hermite(nodes[i], nodes[i+1], nodes[i][2], nodes[i+1][2], x)
    return nodes[-1][1]

def super_ellipse_y(u, p):
    if u <= 0: return 0.0
    if u >= 1: return 1.0
    return (1.0 - (1.0 - u)**p)**(1.0/p)

LOA = proj['loa_m']
LOA_SQ = proj['loa_sq']
NST = proj['balizas']
p_exp = proj['cheia']['p']

xs = np.linspace(0, LOA_SQ, 300)
plan_sheer_y = [eval_curve(proj['curvas']['planSheer'], x) for x in xs]
prof_sheer_z = [eval_curve(proj['curvas']['profSheer'], x) for x in xs]
prof_keel_z = [eval_curve(proj['curvas']['profKeel'], x) for x in xs]

# 1. Gerar imagem em alta resolução otimizada para formato landscape ou 2 páginas A4
fig = plt.figure(figsize=(10.5, 5.2), dpi=300)
plt.rcParams['font.sans-serif'] = 'DejaVu Sans'
plt.rcParams['axes.edgecolor'] = '#333333'
plt.rcParams['axes.linewidth'] = 0.8

c_primary = '#003366'
c_water = '#006699'
c_grid = '#e0e0e0'

# Subplot 1: Plano de Perfil
ax1 = plt.subplot2grid((2, 3), (0, 0), colspan=2)
ax1.plot(xs, prof_sheer_z, color=c_primary, lw=2, label='Borda / Convés')
ax1.plot(xs, prof_keel_z, color='#222222', lw=2, label='Quilha / Fundo')
ax1.fill_between(xs, prof_keel_z, prof_sheer_z, color='#f0f4f8', alpha=0.7)
for st in range(NST):
    st_x = st * (LOA_SQ / (NST - 1))
    ax1.axvline(st_x, color='#999999', ls='--', lw=0.7)
    ax1.text(st_x, -0.22, f'B{st+1}', ha='center', va='top', fontsize=7.5, color='#555555')
ax1.set_title('Plano de Perfil (Vista Lateral)', fontsize=10, fontweight='bold', color=c_primary, pad=6)
ax1.set_ylabel('Z (m)', fontsize=8.5)
ax1.set_xlim(-0.5, 15.5)
ax1.set_ylim(-0.35, 2.1)
ax1.grid(True, ls=':', color=c_grid)
ax1.legend(loc='upper left', fontsize=7.5, framealpha=0.9)

# Subplot 2: Plano de Linhas d\'Água
ax2 = plt.subplot2grid((2, 3), (1, 0), colspan=2)
ax2.plot(xs, plan_sheer_y, color=c_primary, lw=2, label='Borda (Convés)')
for frac, ls, col in [(0.25, ':', '#88aacc'), (0.5, '--', '#5588bb'), (0.75, '-.', '#225588')]:
    wl_y = [plan_sheer_y[i] * super_ellipse_y(frac, p_exp) for i in range(len(xs))]
    ax2.plot(xs, wl_y, color=col, lw=1.0, ls=ls, label=f'WL {frac*1.7:.2f}m' if frac==0.5 else "")
ax2.axhline(0, color='#111111', lw=1.2, ls='-')
ax2.fill_between(xs, 0, plan_sheer_y, color='#e8f0f8', alpha=0.6)
for st in range(NST):
    st_x = st * (LOA_SQ / (NST - 1))
    ax2.axvline(st_x, color='#999999', ls='--', lw=0.7)
ax2.set_title('Plano de Meia-Boca (Vista Superior)', fontsize=10, fontweight='bold', color=c_primary, pad=6)
ax2.set_xlabel('Comprimento X (m)', fontsize=8.5)
ax2.set_ylabel('Y (m)', fontsize=8.5)
ax2.set_xlim(-0.5, 15.5)
ax2.set_ylim(-0.25, 2.6)
ax2.grid(True, ls=':', color=c_grid)

# Subplot 3: Plano de Balizas
ax3 = plt.subplot2grid((2, 3), (0, 2), rowspan=2)
u_vals = np.linspace(0, 1, 100)
colors_bal = ['#003366', '#006699', '#3388bb', '#d9534f', '#e67e22', '#27ae60']

for st in range(NST):
    st_x = st * (LOA_SQ / (NST - 1))
    b_max = eval_curve(proj['curvas']['planSheer'], st_x)
    z_deck = eval_curve(proj['curvas']['profSheer'], st_x)
    z_bot = eval_curve(proj['curvas']['profKeel'], st_x)
    depth_local = max(0.01, z_deck - z_bot)
    
    y_sec = [b_max * super_ellipse_y(u, p_exp) for u in u_vals]
    z_sec = [z_bot + u * depth_local for u in u_vals]
    
    if st <= 2:
        ax3.plot([-y for y in y_sec], z_sec, color=colors_bal[st], lw=1.8, label=f'B{st+1} ({st_x:.0f}m)')
    else:
        ax3.plot(y_sec, z_sec, color=colors_bal[st], lw=1.8, label=f'B{st+1} ({st_x:.0f}m)')

ax3.axvline(0, color='#111111', lw=1.2)
ax3.axhline(0, color='#555555', lw=0.8, ls=':')
ax3.set_title('Plano de Balizas (Body Plan)', fontsize=10, fontweight='bold', color=c_primary, pad=6)
ax3.set_xlabel('Meia-Boca Y (m)\n← Popa | Proa →', fontsize=8.5)
ax3.set_ylabel('Altura Z (m)', fontsize=8.5)
ax3.set_xlim(-2.5, 2.5)
ax3.set_ylim(-0.2, 2.0)
ax3.grid(True, ls=':', color=c_grid)
ax3.legend(loc='lower center', fontsize=7.5, framealpha=0.95)

plt.tight_layout()
img_path = '/home/magdalena/eee/alunos/andre-veleiro-40pe/desenho_linhas_naval.png'
plt.savefig(img_path, dpi=300)
plt.close()

# 2. Dados da Tabela de Cotas
tabela_dados = [
    ['Baliza', 'X (m)', 'Quilha Z (m)', 'Convés Z (m)', 'WL 0,425m', 'WL 0,850m', 'WL 1,275m', 'Borda Y (m)']
]

for st in range(NST):
    st_x = st * (LOA_SQ / (NST - 1))
    b_max = eval_curve(proj['curvas']['planSheer'], st_x)
    z_deck = eval_curve(proj['curvas']['profSheer'], st_x)
    z_bot = eval_curve(proj['curvas']['profKeel'], st_x)
    
    y_wl1 = b_max * super_ellipse_y(0.25, p_exp)
    y_wl2 = b_max * super_ellipse_y(0.50, p_exp)
    y_wl3 = b_max * super_ellipse_y(0.75, p_exp)
    
    tabela_dados.append([
        f"Baliza {st+1}",
        f"{st_x:.2f}",
        f"{z_bot:.3f}",
        f"{z_deck:.3f}",
        f"{y_wl1:.3f}",
        f"{y_wl2:.3f}",
        f"{y_wl3:.3f}",
        f"{b_max:.3f}"
    ])

# 3. Montagem do PDF A4 Landscape de Página Única Impecável
pdf_path = '/home/magdalena/eee/alunos/andre-veleiro-40pe/Plano_de_Linhas_2D_Barco_Escola_Andre.pdf'
doc = SimpleDocTemplate(
    pdf_path,
    pagesize=landscape(A4),
    leftMargin=28, rightMargin=28,
    topMargin=24, bottomMargin=24
)

styles = getSampleStyleSheet()
cor_brana_azul = colors.HexColor('#003366')
cor_cinza_escuro = colors.HexColor('#222222')

title_style = ParagraphStyle(
    'DocTitle',
    parent=styles['Heading1'],
    fontName='Helvetica-Bold',
    fontSize=15,
    leading=18,
    textColor=cor_brana_azul,
    alignment=0,
    spaceAfter=2
)

subtitle_style = ParagraphStyle(
    'DocSubTitle',
    parent=styles['Normal'],
    fontName='Helvetica',
    fontSize=9,
    leading=12,
    textColor=colors.HexColor('#555555'),
    spaceAfter=6
)

body_style = ParagraphStyle(
    'BodyDark',
    parent=styles['Normal'],
    fontName='Helvetica',
    fontSize=8,
    leading=11,
    textColor=cor_cinza_escuro
)

callout_style = ParagraphStyle(
    'Callout',
    parent=styles['Normal'],
    fontName='Helvetica-Oblique',
    fontSize=7.5,
    leading=10,
    textColor=colors.HexColor('#004080')
)

story = []

# Cabeçalho compacto em 2 colunas
header_data = [
    [
        Paragraph("<b>ESCOLA DE ARQUITETURA E ENGENHARIA NAVAL BRANA</b><br/><font color='#777777'>ESTALEIRO ESCOLA EMBRIÃO — SALVADOR / BA</font>", ParagraphStyle('HLeft', fontName='Helvetica', fontSize=8, leading=11)),
        Paragraph("<b>PROJETO:</b> Barco Escola com Vela e Motor (LOA 15,0 m)<br/><b>PROJETISTA:</b> André &nbsp;|&nbsp; <b>DATA:</b> Setembro/2026", ParagraphStyle('HRight', fontName='Helvetica', fontSize=8, leading=11, alignment=2))
    ]
]
t_header = Table(header_data, colWidths=[380, 400])
t_header.setStyle(TableStyle([
    ('LINEBELOW', (0,0), (-1,-1), 1.0, cor_brana_azul),
    ('BOTTOMPADDING', (0,0), (-1,-1), 4),
    ('TOPPADDING', (0,0), (-1,-1), 0),
]))
story.append(t_header)
story.append(Spacer(1, 4))

story.append(Paragraph("Plano de Linhas e Geometria de Casco 2D", title_style))
story.append(Paragraph("Digitalização geométrica com alisamento monotônico e aprovação em 31 critérios navais do Brana.", subtitle_style))

# Imagem do desenho técnico
story.append(RLImage(img_path, width=785, height=275))
story.append(Spacer(1, 6))

# Tabela de Cotas + Quadro de Características lado a lado
tabela_pdf = []
for r_idx, row in enumerate(tabela_dados):
    linha_formatada = []
    for c_idx, cell in enumerate(row):
        if r_idx == 0:
            p = Paragraph(f"<b>{cell}</b>", ParagraphStyle('Th', fontName='Helvetica-Bold', fontSize=7, textColor=colors.white, alignment=1))
        else:
            p = Paragraph(cell, ParagraphStyle('Td', fontName='Helvetica', fontSize=7, textColor=cor_cinza_escuro, alignment=1))
        linha_formatada.append(p)
    tabela_pdf.append(linha_formatada)

t_offsets = Table(tabela_pdf, colWidths=[55, 45, 55, 55, 55, 55, 55, 55])
t_offsets.setStyle(TableStyle([
    ('BACKGROUND', (0,0), (-1,0), cor_brana_azul),
    ('ALIGN', (0,0), (-1,-1), 'CENTER'),
    ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
    ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#cccccc')),
    ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.white, colors.HexColor('#f2f6fa')]),
    ('TOPPADDING', (0,0), (-1,-1), 2.5),
    ('BOTTOMPADDING', (0,0), (-1,-1), 2.5),
]))

resumo_html = (
    "<b>PARÂMETROS GEOMÉTRICOS PRINCIPAIS:</b><br/>"
    "• <b>Comprimento Total (LOA):</b> 15,00 m<br/>"
    "• <b>Boca Máxima (BOA):</b> 4,50 m (L/B = 3,33)<br/>"
    "• <b>Pontal Moldado (D):</b> 1,70 m (B/D = 2,65)<br/>"
    "• <b>Forma Transversal:</b> Super-Elipse (p = 2,35, Cm = 0,830)<br/>"
    "• <b>Tipo de Casco:</b> Bojo Redondo contínuo (<i>round bilge</i>)<br/>"
    "• <b>Validação:</b> 31/31 testes de alisamento e convexidade aprovados."
)
p_resumo = Paragraph(resumo_html, ParagraphStyle('ResBox', fontName='Helvetica', fontSize=7.5, leading=10.5, textColor=cor_cinza_escuro))

quadro_inferior = [
    [
        t_offsets,
        p_resumo
    ]
]
t_quadro = Table(quadro_inferior, colWidths=[450, 335])
t_quadro.setStyle(TableStyle([
    ('VALIGN', (0,0), (-1,-1), 'TOP'),
    ('BACKGROUND', (1,0), (1,0), colors.HexColor('#f8f9fa')),
    ('BOX', (1,0), (1,0), 0.8, cor_brana_azul),
    ('TOPPADDING', (1,0), (1,0), 6),
    ('BOTTOMPADDING', (1,0), (1,0), 6),
    ('LEFTPADDING', (1,0), (1,0), 8),
    ('RIGHTPADDING', (1,0), (1,0), 8),
]))

story.append(t_quadro)
story.append(Spacer(1, 4))
story.append(Paragraph("Documento técnico gerado no âmbito do Estaleiro Escola Embrião & Escola Brana. Acesso web ao modelo 3D interativo: http://eee.brana.com.br/alunos/andre-veleiro-40pe/Plano-de-Linhas-Redondo-Andre.html", callout_style))

doc.build(story)
print("PDF finalizado com sucesso!")
