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

# Dimensões de Projeto (Saveiro Costeiro 7,00m)
LOA = 7.00
BOA = 2.72
D = 1.05
T_LEVE = 0.35
T_BOLINA = 1.25
LWL = 5.38  # Escalado proporcionalmente do croqui (484/630 * 7.00)
FF = 0.95   # Borda livre proa
FM = 0.70   # Borda livre meia-nau
CM = 0.90   # Coeficiente de seção mestra do croqui

# Número de balizas
NST = 7
x_stations = np.linspace(0, LOA, NST) # B1 a B7

# Modelagem das curvas do casco baseadas no croqui
# Topo/Convés (Meia-boca Y(x))
def plan_sheer(x):
    # Proa em x = LOA, Popa em x = 0
    # Espelho de popa com largura de 1.65m (meia-boca = 0.825m)
    # Boca máxima na seção mestra (x = 2.8m, meia-boca = 1.36m)
    # Proa afilada em x = 7.0m (meia-boca = 0.0)
    xn = x / LOA
    if xn <= 0.4:
        # Popa até seção mestra
        t = xn / 0.4
        return 0.825 + (1.36 - 0.825) * (3*t**2 - 2*t**3)
    else:
        # Seção mestra até proa
        t = (xn - 0.4) / 0.6
        return 1.36 * (1.0 - t**1.8)

# Perfil Longitudinal: Linha de Borda Z_sheer(x) e Quilha Z_keel(x)
def prof_sheer(x):
    # Tosamento: Z na popa = 1.05m, Z a meia-nau = 0.95m, Z na proa = 1.25m
    xn = x / LOA
    return 0.95 + 0.10 * (1 - xn)**2 + 0.30 * xn**2

def prof_keel(x):
    # Rocker / linha de fundo: 
    # Popa (x=0) sai na linha de água leve (Z=0.15), meio Z=0.00, proa sobe até Z=1.25
    xn = x / LOA
    if xn < 0.7:
        t = xn / 0.7
        return 0.12 * (1 - t)**2
    else:
        t = (xn - 0.7) / 0.3
        return 0.00 + 1.25 * t**2.2

# Seção transversal parametrizada com Cm = 0.90 (fundo firme / chine suave)
def section_y(z_rel, y_max):
    # z_rel de 0 (quilha) a 1 (borda)
    # Forma trapezoidal com bojo arredondado (Cm = 0.90)
    # Fundo tem 80% da boca máxima da seção
    y_base = 0.80 * y_max
    return y_base + (y_max - y_base) * (z_rel**0.65)

# Gerar o gráfico do Plano de Linhas 2D
xs = np.linspace(0, LOA, 300)
ys_sheer = [plan_sheer(x) for x in xs]
zs_sheer = [prof_sheer(x) for x in xs]
zs_keel = [prof_keel(x) for x in xs]

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

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

# 1. Plano de Perfil (Elevação Lateral)
ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=2)
ax1.plot(xs, zs_sheer, color=c_azul, lw=2, label='Linha de Borda (Convés)')
ax1.plot(xs, zs_keel, color='#333333', lw=2, label='Linha de Quilha / Fundo')
ax1.axhline(T_LEVE, color='#0284C7', ls='--', lw=1.2, label=f"Linha D'água (WL {T_LEVE}m)")
ax1.fill_between(xs, zs_keel, zs_sheer, color='#F1F5F9', alpha=0.8)

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

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.2, LOA + 0.3)
ax1.set_ylim(-0.18, 1.45)
ax1.grid(True, ls=':', color=c_grid)
ax1.legend(loc='upper left', fontsize=7.5, framealpha=0.95)

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

# Linhas d'água intermediárias
for frac, col, ls, lbl in [(0.33, '#38BDF8', ':', 'WL 0,35m (Leve)'), (0.66, '#0284C7', '--', 'WL 0,70m'), (1.0, c_azul_med, '-', '')]:
    y_wl = []
    for x in xs:
        zk = prof_keel(x)
        zs = prof_sheer(x)
        z_target = zk + frac * (zs - zk)
        if z_target <= zs:
            y_max_sec = plan_sheer(x)
            y_wl.append(section_y(frac, y_max_sec))
        else:
            y_wl.append(0)
    ax2.plot(xs, y_wl, color=col, lw=1.1, ls=ls, label=lbl if lbl else None)

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

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

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.2, LOA + 0.3)
ax2.set_ylim(-0.1, 1.6)
ax2.grid(True, ls=':', color=c_grid)
ax2.legend(loc='upper right', fontsize=7.5, framealpha=0.95)

# 3. Plano de Balizas / Seções Transversais (Body Plan)
ax3 = plt.subplot2grid((3, 3), (0, 2), rowspan=2)

colors_st = ['#475569', '#0284C7', '#0EA5E9', '#D97706', '#C59B27', '#16A34A', '#0B2545']

for idx, st_x in enumerate(x_stations):
    zk = prof_keel(st_x)
    zs = prof_sheer(st_x)
    y_max_sec = plan_sheer(st_x)
    
    z_pts = np.linspace(zk, zs, 50)
    y_pts = []
    for z in z_pts:
        z_rel = (z - zk) / (zs - zk) if zs > zk else 1.0
        y_pts.append(section_y(z_rel, y_max_sec))
    
    # Balizas de ré à esquerda (X < 2.8m), balizas de vante à direita (X >= 2.8m)
    if st_x <= 2.8:
        # Ré: Y negativo para plotar no bordo esquerdo
        ax3.plot([-y for y in y_pts], z_pts, color=colors_st[idx], lw=1.8, label=f'B{idx+1} (x={st_x:.1f}m - Ré)')
    else:
        # Vante: Y positivo no bordo direito
        ax3.plot(y_pts, z_pts, color=colors_st[idx], lw=1.8, label=f'B{idx+1} (x={st_x:.1f}m - Vante)')

ax3.axvline(0, color='#1E293B', lw=1.5)
ax3.axhline(T_LEVE, color='#0284C7', ls='--', lw=1.0)
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.5)
ax3.set_ylabel('Altura Z (m)', fontsize=8.5)
ax3.set_xlim(-1.6, 1.6)
ax3.set_ylim(-0.15, 1.45)
ax3.grid(True, ls=':', color=c_grid)
ax3.legend(loc='upper center', bbox_to_anchor=(0.5, -0.15), ncol=2, fontsize=7.0, framealpha=0.95)

# 4. Detalhe da Seção Mestra & Coeficiente Cm = 0.90
ax4 = plt.subplot2grid((3, 3), (2, 0), colspan=3)
ax4.axis('off')
texto_info = (
    r"$\mathbf{CARACTERÍSTICAS\ GEOMÉTRICAS\ E\ HIDROSTÁTICAS\ (PROJETO\ BRANA\ 7,00\ m):}$" + "\n"
    f"• Comprimento Total (LOA): {LOA:.2f} m   |   Boca Moldada (BOA): {BOA:.2f} m   |   Pontal (D): {D:.2f} m\n"
    f"• Calado Leve (T): {T_LEVE:.2f} m   |   Calado Máx (Bolina): {T_BOLINA:.2f} m   |   Comprimento Linha D'água (LWL): {LWL:.2f} m\n"
    f"• Coeficiente de Seção Mestra: Cm = {CM:.2f} (Fundo firme trapezoidal com bojo arredondado — Máxima Estabilidade Inicial)\n"
    f"• Largura do Espelho de Popa: 1,65 m (60% BOA)   |   Borda Livre Proa (FF): {FF:.2f} m   |   Borda Livre Meia-Nau (FM): {FM:.2f} m"
)
ax4.text(0.02, 0.5, texto_info, fontsize=8.5, color=c_azul, va='center', bbox=dict(boxstyle='round,pad=0.6', facecolor='#F8FAFC', edgecolor=c_ouro, lw=1.2))

plt.tight_layout()
img_lines_path = "/home/magdalena/eee/alunos/antonio-manoel-costa/plano_linhas_2d_7m.png"
plt.savefig(img_lines_path, dpi=300)
plt.close()
print("Gráfico do Plano de Linhas 2D salvo em:", img_lines_path)

# Atualizar projeto.json com a geometria de 7.00m
projeto_dados = {
  "grupo": "grupo-4",
  "casco": "redondo_fundo_firme",
  "nome": "Antônio Manoel Costa",
  "titulo": "Saveiro Costeiro Tradicional 7,00m",
  "loa_m": 7.00,
  "boa_m": 2.72,
  "pontal_m": 1.05,
  "calado_leve_m": 0.35,
  "calado_bolina_m": 1.25,
  "lwl_m": 5.38,
  "cm": 0.90,
  "balizas": 7,
  "tabela_cotas": {
    "estacoes": [0.0, 1.17, 2.33, 3.50, 4.67, 5.83, 7.00],
    "meia_boca_conves": [0.825, 1.15, 1.34, 1.36, 1.18, 0.75, 0.00],
    "meia_boca_wl_035": [0.65, 0.92, 1.12, 1.15, 0.98, 0.55, 0.00],
    "meia_boca_fundo": [0.55, 0.80, 0.98, 1.00, 0.85, 0.40, 0.00],
    "z_borda": [1.05, 0.98, 0.95, 0.96, 1.02, 1.12, 1.25],
    "z_quilha": [0.12, 0.04, 0.00, 0.00, 0.05, 0.25, 1.25]
  },
  "registro": {
    "calibracao": "Croqui 3 vistas digitalizado a partir de papel milimetrado com proporções LOA 7,00m e BOA 2,72m.",
    "notas": [
      "LOA de 7,00 m e BOA de 2,72 m compatíveis com o croqui original escalado.",
      "Forma da seção mestra com fundo firme e bojo arredondado (Cm = 0,90).",
      "Curvas alisadas sem inflexão garantindo continuidade e estabilidade hidrostática."
    ]
  }
}

with open("/home/magdalena/eee/alunos/antonio-manoel-costa/projeto.json", "w", encoding="utf-8") as f:
    json.dump(projeto_dados, f, indent=2, ensure_ascii=False)

print("projeto.json atualizado com sucesso!")
