import {
  CofferedCeiling,
  CorniceRing,
  FlutedShaft,
  HangingFixture,
  RoundArch,
  ShaftBase,
  TuscanCapital,
  WallBand,
} from './primitives';
import {
  shade,
  useBayZ,
  useCorners,
  useRepeat,
  useWallClearance,
  type PeriodProps,
} from './geometry';

/**
 * Roman atrium — Ancient / Classical.
 *
 * Engaged Tuscan half-columns on a bay rhythm carry a compressed but complete
 * entablature (architrave, plain frieze, dentil course, projecting cornice).
 * Below the frame line the walls carry the Pompeian red socle of a Fourth Style
 * room; a bronze polycandelon hangs over the centre in place of ceiling lights.
 */
export function RomanAtriumDetails({ room, trim }: PeriodProps) {
  const bays = useBayZ(room.depth, room.halfD, 4.0, 9);
  const corners = useCorners(room.halfW, room.halfD, 0.1);
  const stone = '#e6dcc6';
  const shadowStone = shade(stone, -0.14);
  const socle = '#7c3227';

  const dentils = useRepeat(room.depth, 0.46, 30);

  return (
    <group>
      {/* Pompeian socle with a black skirting course */}
      {(['left', 'right', 'back'] as const).map((wall) => (
        <group key={wall}>
          <WallBand wall={wall} room={room} y={0.62} height={1.16} proud={0.07} color={socle} roughness={0.8} metalness={0.04} />
          <WallBand wall={wall} room={room} y={0.09} height={0.18} proud={0.09} color="#241a14" roughness={0.7} metalness={0.06} />
          <WallBand wall={wall} room={room} y={1.24} height={0.08} proud={0.1} color={stone} roughness={0.66} metalness={0.06} />
        </group>
      ))}

      {/* Engaged half-columns on the bay rhythm */}
      {bays.map((z, i) => (
        <group key={i}>
          {[-1, 1].map((side) => (
            <group key={side} position={[side * (room.halfW - 0.115), 0, z]}>
              <ShaftBase size={0.15} color={shadowStone} />
              <group position={[0, 0.26, 0]}>
                <FlutedShaft height={3.34} radius={0.135} color={stone} flutes={10} facing="x" />
              </group>
              <TuscanCapital y={3.72} size={0.15} color={stone} />
            </group>
          ))}
        </group>
      ))}

      {/* Entablature: architrave, frieze and dentils along the colonnaded walls */}
      {(['left', 'right'] as const).map((wall) => (
        <group key={wall}>
          <WallBand wall={wall} room={room} y={3.9} height={0.1} proud={0.16} color={shadowStone} roughness={0.7} />
          <WallBand wall={wall} room={room} y={3.99} height={0.11} proud={0.13} color={stone} roughness={0.74} />
          {dentils.map((z, i) => (
            <mesh
              key={i}
              position={[(wall === 'left' ? -1 : 1) * (room.halfW - 0.16), 4.07, z]}
            >
              <boxGeometry args={[0.16, 0.07, 0.16]} />
              <meshStandardMaterial color={shade(stone, 0.06)} roughness={0.7} metalness={0.05} />
            </mesh>
          ))}
        </group>
      ))}

      {/* Projecting cornice returning around the whole room */}
      <CorniceRing room={room} y={4.13} height={0.09} proud={0.19} color={trim} roughness={0.62} metalness={0.12} />

      {/* Corner antae — square pilasters closing the order at each corner */}
      {corners.map(([x, z], i) => (
        <mesh key={i} position={[x, 1.95, z]}>
          <boxGeometry args={[0.2, 3.9, 0.2]} />
          <meshStandardMaterial color={shade(stone, 0.04)} roughness={0.76} metalness={0.04} />
        </mesh>
      ))}

      <HangingFixture
        position={[0, 4.05, 0]}
        dropLength={0.72}
        radius={0.46}
        arms={8}
        metalColor={trim}
        light
        lightColor="#ffb862"
        lightIntensity={0.9}
        lightDistance={9}
      />
    </group>
  );
}

/**
 * Florentine palazzo — Early Renaissance.
 *
 * Brunelleschi's grammar: flat pietra serena pilasters set against lime plaster,
 * a blind arcade of semicircular arches springing between them, glazed roundels
 * in the spandrels, and a painted-and-beamed quattrocento ceiling.
 */
export function QuattrocentoDetails({ room, trim, windows }: PeriodProps) {
  const bays = useBayZ(room.depth, room.halfD, 3.8, 9);
  const clearLeft = useWallClearance(windows, 'left');
  const clearRight = useWallClearance(windows, 'right');
  const serena = '#8b8f8a';
  const serenaLight = shade(serena, 0.16);
  const step = bays.length > 1 ? bays[1] - bays[0] : room.depth / 2;

  return (
    <group>
      {/* Pietra serena dado with a moulded cap */}
      {(['left', 'right', 'back'] as const).map((wall) => (
        <group key={wall}>
          <WallBand wall={wall} room={room} y={0.6} height={1.2} proud={0.05} color={shade(serena, 0.24)} roughness={0.72} metalness={0.05} />
          <WallBand wall={wall} room={room} y={1.24} height={0.09} proud={0.08} color={serena} roughness={0.62} metalness={0.07} />
        </group>
      ))}

      {/* Flat pilasters carrying the arcade */}
      {bays.map((z, i) => (
        <group key={i}>
          {[-1, 1].map((side) => (
            <group key={side} position={[side * (room.halfW - 0.05), 0, z]}>
              <mesh position={[0, 1.78, 0]}>
                <boxGeometry args={[0.08, 3.56, 0.34]} />
                <meshStandardMaterial color={serena} roughness={0.66} metalness={0.07} />
              </mesh>
              <mesh position={[0, 0.11, 0]}>
                <boxGeometry args={[0.11, 0.22, 0.44]} />
                <meshStandardMaterial color={shade(serena, -0.08)} roughness={0.7} metalness={0.06} />
              </mesh>
              {/* Simplified Corinthian capital */}
              <mesh position={[0, 3.68, 0]}>
                <boxGeometry args={[0.1, 0.2, 0.44]} />
                <meshStandardMaterial color={serenaLight} roughness={0.6} metalness={0.08} />
              </mesh>
              <mesh position={[0, 3.82, 0]}>
                <boxGeometry args={[0.12, 0.09, 0.5]} />
                <meshStandardMaterial color={serenaLight} roughness={0.58} metalness={0.08} />
              </mesh>
            </group>
          ))}
        </group>
      ))}

      {/* Blind arcade between the pilasters, plus a roundel in each spandrel */}
      {bays.slice(0, -1).map((z, i) => {
        const mid = z + step / 2;
        return (
          <group key={i}>
            {([-1, 1] as const).map((side) => (
              <group key={side} position={[side * (room.halfW - 0.05), 3.88, mid]} rotation={[0, Math.PI / 2, 0]}>
                <RoundArch
                  span={step - 0.34}
                  rise={0.24}
                  thickness={0.12}
                  depth={0.09}
                  color={serena}
                  segments={9}
                  roughness={0.64}
                  metalness={0.07}
                />
                {/* Glazed tondo, only where no window claims the bay */}
                {(side < 0 ? clearLeft : clearRight)(mid, 0.22) && (
                  <mesh position={[0, -0.5, 0]}>
                    <torusGeometry args={[0.17, 0.035, 8, 20]} />
                    <meshStandardMaterial color={trim} roughness={0.42} metalness={0.35} />
                  </mesh>
                )}
              </group>
            ))}
          </group>
        );
      })}

      {/* Painted beam ceiling over the arcade */}
      <CorniceRing room={room} y={4.11} height={0.1} proud={0.14} color={serena} roughness={0.64} metalness={0.07} />
      <CofferedCeiling
        room={room}
        y={4.09}
        cell={2.0}
        panelColor="#e2d3ba"
        ribColor="#8a5a30"
        ribWidth={0.14}
        ribDrop={0.14}
      />
    </group>
  );
}

/**
 * Roman palazzo — High Renaissance.
 *
 * Bramante's cinquecento order: paired fluted Corinthian pilasters on a wide
 * bay, a full marble entablature, panelled dado, and a rosetted coffer field
 * modelled on the Pantheon soffit.
 */
export function CinquecentoDetails({ room, trim }: PeriodProps) {
  const bays = useBayZ(room.depth, room.halfD, 5.2, 6);
  const marble = '#efe9dd';
  const grey = shade(marble, -0.16);

  return (
    <group>
      {/* Panelled marble dado */}
      {(['left', 'right', 'back'] as const).map((wall) => (
        <group key={wall}>
          <WallBand wall={wall} room={room} y={0.58} height={1.16} proud={0.06} color={grey} roughness={0.44} metalness={0.1} />
          <WallBand wall={wall} room={room} y={1.2} height={0.1} proud={0.09} color={marble} roughness={0.38} metalness={0.12} />
          <WallBand wall={wall} room={room} y={0.07} height={0.14} proud={0.1} color={shade(grey, -0.18)} roughness={0.4} metalness={0.12} />
        </group>
      ))}

      {/* Paired fluted pilasters */}
      {bays.map((z, i) => (
        <group key={i}>
          {[-1, 1].map((side) =>
            [-0.19, 0.19].map((dz) => (
              <group key={`${side}-${dz}`} position={[side * (room.halfW - 0.13), 0, z + dz]}>
                <ShaftBase size={0.12} color={grey} />
                <group position={[0, 0.24, 0]}>
                  <FlutedShaft height={3.32} radius={0.11} color={marble} flutes={8} facing="x" />
                </group>
                <mesh position={[0, 3.66, 0]}>
                  <cylinderGeometry args={[0.15, 0.1, 0.24, 12]} />
                  <meshStandardMaterial color={marble} roughness={0.42} metalness={0.1} />
                </mesh>
                <mesh position={[0, 3.82, 0]}>
                  <boxGeometry args={[0.12, 0.1, 0.34]} />
                  <meshStandardMaterial color={shade(marble, 0.06)} roughness={0.4} metalness={0.11} />
                </mesh>
              </group>
            ))
          )}
        </group>
      ))}

      {/* Full entablature on the pilastered walls, cornice all round */}
      {(['left', 'right'] as const).map((wall) => (
        <group key={wall}>
          <WallBand wall={wall} room={room} y={3.92} height={0.1} proud={0.15} color={marble} roughness={0.42} metalness={0.1} />
          <WallBand wall={wall} room={room} y={4.02} height={0.1} proud={0.12} color={grey} roughness={0.46} metalness={0.1} />
        </group>
      ))}
      <CorniceRing room={room} y={4.12} height={0.09} proud={0.18} color={trim} roughness={0.4} metalness={0.28} />

      <CofferedCeiling
        room={room}
        y={4.08}
        cell={2.6}
        panelColor="#f2ede3"
        ribColor="#ded5c4"
        ribWidth={0.2}
        ribDrop={0.18}
        rosette={trim}
      />
    </group>
  );
}
