import { useMemo } from 'react';
import * as THREE from 'three';
import type { MovementInteriorStyle } from '../data/movement-interior-styles';

interface Props {
  style: MovementInteriorStyle;
  width: number;
  depth: number;
  halfW: number;
  halfD: number;
}

function PalazzoDetails({ width, depth, halfW, halfD, trim }: Props & { trim: string }) {
  const pilasterPositions = useMemo(
    () =>
      [
        [-halfW + 0.35, -halfD + 0.35],
        [halfW - 0.35, -halfD + 0.35],
        [-halfW + 0.35, halfD - 0.35],
        [halfW - 0.35, halfD - 0.35],
      ] as [number, number][],
    [halfW, halfD]
  );

  return (
    <group>
      {pilasterPositions.map(([x, z], i) => (
        <group key={i} position={[x, 0, z]}>
          <mesh position={[0, 1.8, 0]} castShadow>
            <boxGeometry args={[0.22, 3.6, 0.22]} />
            <meshStandardMaterial color="#e8dcc8" roughness={0.85} metalness={0.05} />
          </mesh>
          <mesh position={[0, 3.65, 0]}>
            <boxGeometry args={[0.28, 0.14, 0.28]} />
            <meshStandardMaterial color={trim} roughness={0.35} metalness={0.55} />
          </mesh>
        </group>
      ))}

      {/* Wainscoting rail */}
      {[
        [0, -halfD + 0.09, width, 0.12] as const,
        [0, halfD - 0.09, width, 0.12] as const,
        [-halfW + 0.09, 0, 0.12, depth] as const,
        [halfW - 0.09, 0, 0.12, depth] as const,
      ].map(([x, z, w, d], i) => (
        <mesh key={i} position={[x, 1.05, z]}>
          <boxGeometry args={[w, 0.08, d]} />
          <meshStandardMaterial color="#ddd0b8" roughness={0.78} metalness={0.08} />
        </mesh>
      ))}

      {/* Coffered ceiling */}
      {Array.from({ length: Math.min(6, Math.floor(width / 2.5)) }, (_, col) =>
        Array.from({ length: Math.min(5, Math.floor(depth / 2.8)) }, (_, row) => {
          const cx = -halfW + 1.4 + col * 2.4;
          const cz = -halfD + 1.5 + row * 2.6;
          return (
            <mesh key={`${col}-${row}`} position={[cx, 4.12, cz]} rotation={[Math.PI / 2, 0, 0]}>
              <boxGeometry args={[2.0, 2.2, 0.06]} />
              <meshStandardMaterial color="#f5efe4" roughness={0.88} />
            </mesh>
          );
        })
      )}
    </group>
  );
}

function BaroqueDetails({ width, depth, halfW, halfD, trim }: Props & { trim: string }) {
  return (
    <group>
      {/* Gilded cornice ring */}
      {[
        [0, -halfD + 0.06, width, 0.1] as const,
        [0, halfD - 0.06, width, 0.1] as const,
        [-halfW + 0.06, 0, 0.1, depth] as const,
        [halfW - 0.06, 0, 0.1, depth] as const,
      ].map(([x, z, w, d], i) => (
        <mesh key={i} position={[x, 3.95, z]}>
          <boxGeometry args={[w, 0.18, d]} />
          <meshStandardMaterial color={trim} roughness={0.25} metalness={0.75} emissive="#3a2808" emissiveIntensity={0.08} />
        </mesh>
      ))}

      {/* Wall panels */}
      {[-halfW + 0.12, halfW - 0.12].map((x, i) => (
        <mesh key={i} position={[x, 2.1, 0]} rotation={[0, Math.PI / 2, 0]}>
          <boxGeometry args={[depth * 0.85, 2.8, 0.04]} />
          <meshStandardMaterial color="#3a1820" roughness={0.88} metalness={0.06} />
        </mesh>
      ))}

      <pointLight position={[0, 3.6, 0]} intensity={0.9} distance={Math.max(width, depth)} color="#ffd080" />
      <mesh position={[0, 3.5, 0]}>
        <torusGeometry args={[0.55, 0.04, 8, 24]} />
        <meshStandardMaterial color={trim} roughness={0.2} metalness={0.85} emissive="#5a4010" emissiveIntensity={0.15} />
      </mesh>
    </group>
  );
}

function MedievalDetails({ halfW, halfD }: Pick<Props, 'halfW' | 'halfD'>) {
  const torchPositions = useMemo(
    () =>
      [
        [-halfW + 0.2, -halfD * 0.5],
        [halfW - 0.2, -halfD * 0.5],
        [-halfW + 0.2, halfD * 0.3],
        [halfW - 0.2, halfD * 0.3],
      ] as [number, number][],
    [halfW, halfD]
  );

  return (
    <group>
      {torchPositions.map(([x, z], i) => (
        <group key={i} position={[x, 2.2, z]}>
          <mesh>
            <boxGeometry args={[0.08, 0.35, 0.12]} />
            <meshStandardMaterial color="#3a3028" roughness={0.9} />
          </mesh>
          <pointLight position={[0, 0.15, 0.08]} intensity={0.65} distance={5} color="#ff9830" />
          <mesh position={[0, 0.2, 0.06]}>
            <sphereGeometry args={[0.06, 8, 8]} />
            <meshStandardMaterial color="#ffb040" emissive="#ff8010" emissiveIntensity={0.8} toneMapped={false} />
          </mesh>
        </group>
      ))}

      {/* Rough stone courses */}
      {[-halfD + 0.08, halfD - 0.08].map((z, i) => (
        <mesh key={i} position={[0, 1.5, z]}>
          <boxGeometry args={[0.04, 3, 0.04]} />
          <meshStandardMaterial color="#6a6458" roughness={0.98} />
        </mesh>
      ))}
    </group>
  );
}

function NeoclassicalDetails({ halfW, halfD, trim }: Pick<Props, 'halfW' | 'halfD'> & { trim: string }) {
  const columns = [
    [-halfW + 0.45, -halfD + 0.6],
    [halfW - 0.45, -halfD + 0.6],
    [-halfW + 0.45, halfD - 0.6],
    [halfW - 0.45, halfD - 0.6],
  ] as [number, number][];

  return (
    <group>
      {columns.map(([x, z], i) => (
        <group key={i} position={[x, 0, z]}>
          <mesh position={[0, 1.85, 0]}>
            <cylinderGeometry args={[0.18, 0.2, 3.7, 12]} />
            <meshStandardMaterial color="#f0ece8" roughness={0.72} metalness={0.12} />
          </mesh>
          <mesh position={[0, 3.85, 0]}>
            <boxGeometry args={[0.42, 0.12, 0.42]} />
            <meshStandardMaterial color={trim} roughness={0.4} metalness={0.35} />
          </mesh>
        </group>
      ))}
      <mesh position={[0, 3.88, -halfD + 0.12]}>
        <boxGeometry args={[2.8, 0.14, 0.2]} />
        <meshStandardMaterial color={trim} roughness={0.45} metalness={0.3} />
      </mesh>
    </group>
  );
}

function ClassicalDetails({ halfW, trim }: Pick<Props, 'halfW'> & { trim: string }) {
  return (
    <group>
      {[
        [-halfW + 0.5, 0],
        [halfW - 0.5, 0],
      ].map(([x, z], i) => (
        <group key={i} position={[x, 0, z]}>
          <mesh position={[0, 2, 0]}>
            <cylinderGeometry args={[0.16, 0.18, 4, 10]} />
            <meshStandardMaterial color="#e0d8c8" roughness={0.88} />
          </mesh>
          <mesh position={[0, 4.05, 0]}>
            <boxGeometry args={[0.36, 0.1, 0.36]} />
            <meshStandardMaterial color={trim} roughness={0.5} metalness={0.25} />
          </mesh>
        </group>
      ))}
    </group>
  );
}

function SalonDetails({ trim }: { trim: string }) {
  return (
    <mesh position={[0, 4.05, 0]} rotation={[Math.PI / 2, 0, 0]}>
      <ringGeometry args={[0.3, 1.2, 32]} />
      <meshStandardMaterial color={trim} roughness={0.35} metalness={0.5} side={THREE.DoubleSide} />
    </mesh>
  );
}

export default function MovementHallDetails({ style, width, depth, halfW, halfD }: Props) {
  const trim = style.tints.trim;

  switch (style.details) {
    case 'palazzo':
      return <PalazzoDetails style={style} width={width} depth={depth} halfW={halfW} halfD={halfD} trim={trim} />;
    case 'baroque':
      return <BaroqueDetails style={style} width={width} depth={depth} halfW={halfW} halfD={halfD} trim={trim} />;
    case 'medieval':
      return <MedievalDetails halfW={halfW} halfD={halfD} />;
    case 'neoclassical':
      return <NeoclassicalDetails halfW={halfW} halfD={halfD} trim={trim} />;
    case 'classical':
      return <ClassicalDetails halfW={halfW} trim={trim} />;
    case 'salon':
      return <SalonDetails trim={trim} />;
    default:
      return null;
  }
}
