// Croquis du Torpen au mouillage — illustration héro animée
// Soleil qui suit l'arc de la journée, eau qui monte/descend avec la marée,
// catamaran qui flotte au niveau de l'eau, ancre au fond, sous-quille mesuré.
// Style: carnet de bord — Fraunces italic, traits dessinés à la main.

function CroquisTorpen({ day, time = null, width = 720, height = 760, palette }) {
  // time: Date — defaults to current hour data
  const C = palette || {
    paper:   '#F0E6CC',
    paperDk: '#E4D5A8',
    ink:     '#1A2330',
    inkSoft: '#3D4A5C',
    sun:     '#B8782E',
    sea:     '#3D6E8E',
    seaDk:   '#2A5471',
    seaSurface: '#3268A0',
    sand:    '#D9C58E',
    sandDk:  '#B8A06B',
    red:     '#A4332B',
    rope:    '#1A2330',
  };

  // Pick the hour: closest to time, default = current local hour or noon
  const now = time || new Date();
  let hour = day.hours.find(h => h.date.getHours() === now.getHours()) || day.hours[12];

  // Sun position along arc — based on hour relative to sunrise/sunset
  const srH = day.sunrise.getHours() + day.sunrise.getMinutes() / 60;
  const ssH = day.sunset.getHours() + day.sunset.getMinutes() / 60;
  const curH = hour.date.getHours() + hour.date.getMinutes() / 60;
  const dayProgress = Math.max(0, Math.min(1, (curH - srH) / (ssH - srH)));
  const isDaylight = curH >= srH && curH <= ssH;

  // Sun arc: from left (sunrise) to right (sunset) over a half-ellipse
  const W = width, H = height;
  const margin = 36;
  const arcLeft = margin + 60;
  const arcRight = W - margin - 60;
  const arcCenterX = (arcLeft + arcRight) / 2;
  const arcRadiusX = (arcRight - arcLeft) / 2;
  const arcCenterY = H * 0.42;
  const arcRadiusY = H * 0.30;

  const sunAngle = Math.PI * (1 - dayProgress); // pi=left, 0=right
  const sunX = arcCenterX - arcRadiusX * Math.cos(sunAngle);
  const sunY = arcCenterY - arcRadiusY * Math.sin(sunAngle);

  // === ÉCHELLE PHYSIQUE ===
  // 1 mètre = METER_PX pixels. Le bateau (8m × 4m hors-tout) et la profondeur
  // sont dessinés avec la même unité, donc tout est cohérent à l'échelle.
  const METER_PX = 26;
  const BOAT_LEN_M = 8;     // longueur Torpen
  const BOAT_BEAM_M = 4;    // largeur (non visible de profil mais sert pour cabine)
  const BOAT_DRAFT_M = 0.7; // tirant d'eau
  const BOAT_FREEBOARD_M = 1.0; // hauteur coque hors-eau
  const MAST_HEIGHT_M = 9;  // hauteur mât

  // Le fond est fixe en bas du dessin. La hauteur d'eau (tide ZH) détermine
  // où se trouve la surface. Le bateau flotte juste au-dessus.
  const tide = hour.tide ?? 2.5;
  const sousQuille = hour.depth ?? 1.5;
  const seabedY = H * 0.85;
  // surface de l'eau = seabed - (profondeur d'eau * METER_PX)
  // profondeur d'eau au mouillage = sousQuille + tirant d'eau
  const waterDepthM = sousQuille + BOAT_DRAFT_M;
  const waterY = seabedY - waterDepthM * METER_PX;

  const boatX = W * 0.50;

  const verdict = hour.score?.verdict || 'go';
  const verdictColor = verdict === 'go' ? '#2E7D4F' : verdict === 'caution' ? '#C8841C' : C.red;

  const fmtTime = d => `${String(d.getHours()).padStart(2,'0')}:${String(d.getMinutes()).padStart(2,'0')}`;
  const serif = '"Fraunces", "Times New Roman", serif';
  const mono = '"JetBrains Mono", monospace';

  return (
    <svg viewBox={`0 0 ${W} ${H}`} style={{ width: '100%', height: 'auto', display: 'block', background: C.paper }}>
      <defs>
        {/* Hand-drawn paper texture */}
        <filter id="paperGrain" x="0" y="0">
          <feTurbulence type="fractalNoise" baseFrequency="0.85" numOctaves="2" seed="3" />
          <feColorMatrix values="0 0 0 0 0.06  0 0 0 0 0.05  0 0 0 0 0.04  0 0 0 0.04 0" />
          <feComposite in2="SourceGraphic" operator="in" />
        </filter>
        {/* Wobble — slight irregularity for hand-drawn lines */}
        <filter id="wobble">
          <feTurbulence type="fractalNoise" baseFrequency="0.02" numOctaves="2" seed="5" />
          <feDisplacementMap in="SourceGraphic" scale="1.2" />
        </filter>
        <filter id="wobbleStrong">
          <feTurbulence type="fractalNoise" baseFrequency="0.025" numOctaves="2" seed="9" />
          <feDisplacementMap in="SourceGraphic" scale="2" />
        </filter>
        {/* water surface ripple gradient */}
        <linearGradient id="waterGrad" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" stopColor={C.sea} stopOpacity="0.55" />
          <stop offset="1" stopColor={C.seaDk} stopOpacity="0.78" />
        </linearGradient>
        <linearGradient id="sandGrad" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" stopColor={C.sand} />
          <stop offset="1" stopColor={C.sandDk} />
        </linearGradient>
        {/* Sun rays clip path — easier than drawing each */}
      </defs>

      {/* Paper background with grain */}
      <rect x="0" y="0" width={W} height={H} fill={C.paper} />
      <rect x="0" y="0" width={W} height={H} filter="url(#paperGrain)" opacity="0.6" />

      {/* Inner border (frame), wobbled */}
      <rect x={margin/2} y={margin/2} width={W - margin} height={H - margin} fill="none" stroke={C.ink} strokeWidth="1.5" filter="url(#wobble)" />

      {/* Time label top */}
      <text x={W / 2} y={margin + 12} textAnchor="middle" fontFamily={serif} fontStyle="italic" fontSize="22" fill={C.ink} fontWeight="500">
        {fmtTime(hour.date)}
      </text>

      {/* SUN ARC — segmented by solar phase */}
      {(() => {
        // Solar phases (durations in minutes from sunrise/sunset)
        // - nautical/civil dawn: ~30 min before sunrise (we extend the arc slightly past)
        // - golden hour morning: sunrise → +60 min
        // - blue hour evening: sunset - 30 → sunset
        // - golden hour evening: sunset - 60 → sunset
        const dayLenMs = day.sunset.getTime() - day.sunrise.getTime();
        // dayProgress maps sunrise (0) → sunset (1). compute progress for each phase boundary.
        const goldenMorningEnd = 60 * 60000 / dayLenMs;  // 60 min after sunrise
        const goldenEveningStart = 1 - 60 * 60000 / dayLenMs; // 60 min before sunset

        // Map progress p (0..1) → angle on arc → (x, y)
        const ptAt = (p) => {
          const a = Math.PI * (1 - p);
          return [arcCenterX - arcRadiusX * Math.cos(a), arcCenterY - arcRadiusY * Math.sin(a)];
        };
        const arcSegment = (p1, p2) => {
          const [x1, y1] = ptAt(p1);
          const [x2, y2] = ptAt(p2);
          // large-arc=0, sweep=1 (going up + right along the upper half)
          return `M ${x1} ${y1} A ${arcRadiusX} ${arcRadiusY} 0 0 1 ${x2} ${y2}`;
        };

        const goldenColor = '#D88B3A';
        const dayColor = C.inkSoft;

        // mid-points for labels (along the arc, slightly above)
        const labelPos = (p, offsetY = -10) => {
          const a = Math.PI * (1 - p);
          return {
            x: arcCenterX - (arcRadiusX + 14) * Math.cos(a),
            y: arcCenterY - (arcRadiusY + 14) * Math.sin(a) + offsetY,
            angle: a,
          };
        };
        const gmLabel = labelPos(goldenMorningEnd / 2);
        const geLabel = labelPos((goldenEveningStart + 1) / 2);

        return (
          <g>
            {/* Day plain segment */}
            <path d={arcSegment(goldenMorningEnd, goldenEveningStart)}
                  fill="none" stroke={dayColor} strokeWidth="0.9" strokeDasharray="2 5" opacity="0.7"
                  filter="url(#wobble)" />
            {/* Golden hour morning */}
            <path d={arcSegment(0, goldenMorningEnd)}
                  fill="none" stroke={goldenColor} strokeWidth="2.2" strokeDasharray="3 3"
                  filter="url(#wobble)" />
            {/* Golden hour evening */}
            <path d={arcSegment(goldenEveningStart, 1)}
                  fill="none" stroke={goldenColor} strokeWidth="2.2" strokeDasharray="3 3"
                  filter="url(#wobble)" />

            {/* Phase markers (small ticks) */}
            {[goldenMorningEnd, goldenEveningStart].map((p, i) => {
              const [x, y] = ptAt(p);
              const a = Math.PI * (1 - p);
              const dx = Math.cos(a + Math.PI / 2), dy = Math.sin(a + Math.PI / 2);
              return (
                <line key={i}
                  x1={x - 5 * dx} y1={y - 5 * dy}
                  x2={x + 5 * dx} y2={y + 5 * dy}
                  stroke={goldenColor} strokeWidth="1.4" />
              );
            })}

            {/* Golden hour labels along arc */}
            <text x={gmLabel.x} y={gmLabel.y} textAnchor="middle"
                  fontFamily={serif} fontStyle="italic" fontSize="13" fill={goldenColor}>
              ☀ heure dorée
            </text>
            <text x={geLabel.x} y={geLabel.y} textAnchor="middle"
                  fontFamily={serif} fontStyle="italic" fontSize="13" fill={goldenColor}>
              ☀ heure dorée
            </text>

            {/* Zenith marker (solar noon) */}
            {(() => {
              const [zx, zy] = ptAt(0.5);
              return (
                <g>
                  <line x1={zx} y1={zy - 10} x2={zx} y2={zy + 10} stroke={C.inkSoft} strokeWidth="0.8" opacity="0.5" />
                  <text x={zx} y={zy - 14} textAnchor="middle" fontFamily={mono} fontSize="9" fill={C.inkSoft} letterSpacing="1.5">
                    ZÉNITH
                  </text>
                </g>
              );
            })()}
          </g>
        );
      })()}

      {/* Sunrise / sunset labels */}
      <g>
        <text x={arcLeft - 6} y={arcCenterY + 4} textAnchor="end" fontFamily={serif} fontStyle="italic" fontSize="13" fill={C.inkSoft}>
          lever
        </text>
        <text x={arcLeft - 6} y={arcCenterY + 22} textAnchor="end" fontFamily={mono} fontSize="11" fill={C.ink} letterSpacing="1" fontWeight="600">{fmtTime(day.sunrise)}</text>
        <text x={arcRight + 6} y={arcCenterY + 4} textAnchor="start" fontFamily={serif} fontStyle="italic" fontSize="13" fill={C.inkSoft}>
          coucher
        </text>
        <text x={arcRight + 6} y={arcCenterY + 22} textAnchor="start" fontFamily={mono} fontSize="11" fill={C.ink} letterSpacing="1" fontWeight="600">{fmtTime(day.sunset)}</text>
      </g>

      {/* Decorative clouds — hand drawn */}
      <g stroke={C.inkSoft} strokeWidth="1.3" fill="none" opacity="0.7" filter="url(#wobble)">
        <Cloud x={W * 0.22} y={H * 0.20} scale={0.9} />
        <Cloud x={W * 0.78} y={H * 0.16} scale={1.05} />
        <Cloud x={W * 0.85} y={H * 0.32} scale={0.7} />
      </g>

      {/* SUN or MOON */}
      {isDaylight ? (
        <g transform={`translate(${sunX}, ${sunY})`}>
          {/* rays */}
          {Array.from({ length: 16 }, (_, i) => {
            const a = (i / 16) * Math.PI * 2;
            const r1 = 28, r2 = 44;
            return (
              <line
                key={i}
                x1={r1 * Math.cos(a)} y1={r1 * Math.sin(a)}
                x2={r2 * Math.cos(a)} y2={r2 * Math.sin(a)}
                stroke={C.sun} strokeWidth="1.6" strokeLinecap="round"
              />
            );
          })}
          <circle r="22" fill={C.sun} filter="url(#wobble)" />
          <circle r="22" fill="none" stroke={C.ink} strokeWidth="1.2" filter="url(#wobble)" />
        </g>
      ) : (
        <g transform={`translate(${arcCenterX}, ${arcCenterY - arcRadiusY * 0.3})`}>
          {/* moon */}
          <circle r="22" fill={C.paperDk} stroke={C.ink} strokeWidth="1.2" filter="url(#wobble)" />
          <circle r="20" cx="-8" cy="-3" fill={C.paper} />
          <text y="38" textAnchor="middle" fontFamily={serif} fontStyle="italic" fontSize="14" fill={C.inkSoft}>nuit</text>
        </g>
      )}

      {/* MAST — vertical line from boat top to sun anchor (visual link) */}
      {/* Mast top scaled: MAST_HEIGHT_M * METER_PX above water surface */}
      <line x1={boatX} y1={waterY - BOAT_FREEBOARD_M * METER_PX} x2={boatX} y2={waterY - (BOAT_FREEBOARD_M + MAST_HEIGHT_M) * METER_PX} stroke={C.ink} strokeWidth="1.8" filter="url(#wobble)" />
      <circle cx={boatX} cy={waterY - (BOAT_FREEBOARD_M + MAST_HEIGHT_M) * METER_PX} r="3" fill={C.red} />

      {/* WATER */}
      {/* Bottom area: sand */}
      <path d={`M 0 ${seabedY} Q ${W * 0.3} ${seabedY - 4} ${W * 0.6} ${seabedY + 2} T ${W} ${seabedY - 2} L ${W} ${H} L 0 ${H} Z`} fill="url(#sandGrad)" />
      <path d={`M 0 ${seabedY} Q ${W * 0.3} ${seabedY - 4} ${W * 0.6} ${seabedY + 2} T ${W} ${seabedY - 2}`} fill="none" stroke={C.ink} strokeWidth="1.4" filter="url(#wobbleStrong)" />

      {/* Water body — between waterY and seabedY */}
      <rect x="0" y={waterY} width={W} height={seabedY - waterY} fill="url(#waterGrad)" />

      {/* Water surface — wobbly horizontal line + label */}
      <path
        d={`M ${margin/2} ${waterY} Q ${W * 0.15} ${waterY - 3} ${W * 0.30} ${waterY} T ${W * 0.60} ${waterY} T ${W * 0.90} ${waterY} L ${W - margin/2} ${waterY}`}
        fill="none" stroke={C.seaSurface} strokeWidth="1.6"
      />
      <text x={margin + 12} y={waterY - 8} fontFamily={serif} fontStyle="italic" fontSize="16" fill={C.seaSurface} fontWeight="500">
        marée {tide.toFixed(2)} m
      </text>

      {/* CATAMARAN — side profile, scaled to BOAT_LEN_M × METER_PX */}
      <Catamaran cx={boatX} cy={waterY} colors={C} lengthPx={BOAT_LEN_M * METER_PX} freeboardPx={BOAT_FREEBOARD_M * METER_PX} draftPx={BOAT_DRAFT_M * METER_PX} />

      {/* MOORING ROPE — from bow to anchor on seabed */}
      {(() => {
        const ropeStartX = boatX - BOAT_LEN_M * METER_PX * 0.4;
        const ropeStartY = waterY + BOAT_DRAFT_M * METER_PX;
        const anchorX = boatX - BOAT_LEN_M * METER_PX * 0.85;
        const anchorY = seabedY - 4;
        return (
          <g>
            <line
              x1={ropeStartX} y1={ropeStartY}
              x2={anchorX} y2={anchorY}
              stroke={C.rope} strokeWidth="1.2" strokeDasharray="3 4"
              filter="url(#wobble)"
            />
            <Anchor cx={anchorX} cy={anchorY} colors={C} />
          </g>
        );
      })()}

      {/* SOUS-QUILLE measurement — vertical bracket on the right */}
      {(() => {
        const measX = boatX + BOAT_LEN_M * METER_PX * 0.65;
        const top = waterY + BOAT_DRAFT_M * METER_PX;
        const bottom = seabedY - 2;
        return (
          <g>
            <line x1={measX} y1={top} x2={measX} y2={bottom} stroke={C.red} strokeWidth="1.4" />
            {/* end ticks */}
            <line x1={measX - 6} y1={top} x2={measX + 6} y2={top} stroke={C.red} strokeWidth="1.4" />
            <line x1={measX - 6} y1={bottom} x2={measX + 6} y2={bottom} stroke={C.red} strokeWidth="1.4" />
            {/* arrowheads */}
            <polygon points={`${measX},${top + 4} ${measX - 4},${top + 10} ${measX + 4},${top + 10}`} fill={C.red} />
            <polygon points={`${measX},${bottom - 4} ${measX - 4},${bottom - 10} ${measX + 4},${bottom - 10}`} fill={C.red} />
            <text x={measX + 12} y={(top + bottom) / 2 - 2} fontFamily={serif} fontStyle="italic" fontSize="22" fontWeight="500" fill={C.red}>
              {sousQuille.toFixed(2)} m
            </text>
            <text x={measX + 12} y={(top + bottom) / 2 + 18} fontFamily={mono} fontSize="10" fill={C.red} letterSpacing="1.5">
              SOUS QUILLE
            </text>
          </g>
        );
      })()}

      {/* Seabed label */}
      <text x={margin + 12} y={seabedY + 24} fontFamily={serif} fontStyle="italic" fontSize="14" fill={C.inkSoft}>
        fond — sole asséchant
      </text>

      {/* Bottom caption */}
      <text x={W - margin - 6} y={H - margin + 4} textAnchor="end" fontFamily={serif} fontStyle="italic" fontSize="14" fill={C.inkSoft}>
        « croquis du Torpen au mouillage »
      </text>
      <text x={W - margin - 6} y={H - margin + 22} textAnchor="end" fontFamily={mono} fontSize="10" fill={C.inkSoft} letterSpacing="2">
        — marée à {fmtTime(hour.date)} —
      </text>
    </svg>
  );
}

// === Sub-components ===

function Cloud({ x, y, scale = 1 }) {
  // Hand-drawn cumulus, two bumps
  const s = scale;
  return (
    <path
      d={`M ${x} ${y}
          q ${-12*s} ${-2*s} ${-18*s} ${-10*s}
          q ${-2*s} ${-12*s} ${12*s} ${-12*s}
          q ${4*s} ${-10*s} ${18*s} ${-6*s}
          q ${10*s} ${-8*s} ${22*s} ${0*s}
          q ${14*s} ${-2*s} ${16*s} ${10*s}
          q ${10*s} ${4*s} ${4*s} ${14*s}
          q ${-12*s} ${6*s} ${-26*s} ${0*s}
          q ${-14*s} ${8*s} ${-28*s} ${4*s}
          q ${-14*s} ${0*s} ${0*s} ${0*s}
          z`}
    />
  );
}

function Catamaran({ cx, cy, colors, lengthPx = 208, freeboardPx = 26, draftPx = 18 }) {
  const C = colors;
  // Scaled: lengthPx is total length, freeboardPx is hull above water, draftPx below
  const halfL = lengthPx / 2;
  const hullTop = cy - freeboardPx * 0.4;     // deck top
  const hullBot = cy + draftPx;                // keel underwater
  const wlInner = halfL * 0.92;
  const wlGap = halfL * 0.08;                  // small gap between hulls
  return (
    <g filter="url(#wobble)">
      {/* Left hull underwater bottom curve */}
      <path d={`M ${cx - halfL} ${cy + 2}
                Q ${cx - halfL + 6} ${hullBot} ${cx - wlGap - halfL*0.15} ${hullBot}
                L ${cx - wlGap} ${hullBot - 4}
                L ${cx - wlGap} ${cy + 2}
                Z`}
            fill={C.paper} stroke={C.ink} strokeWidth="1.4" />
      {/* Right hull */}
      <path d={`M ${cx + wlGap} ${cy + 2}
                L ${cx + wlGap} ${hullBot - 4}
                L ${cx + wlGap + halfL*0.15} ${hullBot}
                Q ${cx + halfL - 6} ${hullBot} ${cx + halfL} ${cy + 2}
                Z`}
            fill={C.paper} stroke={C.ink} strokeWidth="1.4" />

      {/* Deck — across the two hulls, just above water */}
      <path d={`M ${cx - halfL * 0.85} ${cy - freeboardPx * 0.4}
                L ${cx + halfL * 0.85} ${cy - freeboardPx * 0.4}
                L ${cx + halfL * 0.78} ${cy + 2}
                L ${cx - halfL * 0.78} ${cy + 2} Z`}
            fill={C.paper} stroke={C.ink} strokeWidth="1.4" />

      {/* Cabin — small bump centered */}
      <path d={`M ${cx - halfL * 0.32} ${cy - freeboardPx * 0.4}
                L ${cx - halfL * 0.26} ${cy - freeboardPx * 0.95}
                L ${cx + halfL * 0.26} ${cy - freeboardPx * 0.95}
                L ${cx + halfL * 0.32} ${cy - freeboardPx * 0.4} Z`}
            fill={C.paper} stroke={C.ink} strokeWidth="1.3" />
    </g>
  );
}

function Anchor({ cx, cy, colors }) {
  const C = colors;
  // Tiny anchor symbol on seabed
  return (
    <g transform={`translate(${cx}, ${cy})`} stroke={C.ink} strokeWidth="1.2" fill="none" filter="url(#wobble)">
      {/* shank */}
      <line x1="0" y1="-8" x2="0" y2="2" />
      {/* crown bar */}
      <line x1="-6" y1="-7" x2="6" y2="-7" />
      {/* arms (curve) */}
      <path d="M -8 0 Q -8 6 -2 6" />
      <path d="M 8 0 Q 8 6 2 6" />
      {/* flukes (small) */}
      <line x1="-8" y1="0" x2="-12" y2="-2" />
      <line x1="8" y1="0" x2="12" y2="-2" />
      {/* ring on top */}
      <circle r="2" cx="0" cy="-9" />
    </g>
  );
}

window.CroquisTorpen = CroquisTorpen;
