import React from "react";
import {
  AbsoluteFill,
  interpolate,
  spring,
  useCurrentFrame,
  useVideoConfig,
  Easing,
} from "remotion";
import { ThreeCanvas } from "@remotion/three";
import { Environment, Lightformer, MeshReflectorMaterial, RoundedBox } from "@react-three/drei";
import { EffectComposer, Bloom, DepthOfField, Vignette } from "@react-three/postprocessing";
import * as THREE from "three";
import { z } from "zod";
import { colorSchema } from "../lib/branding";
import { FONT } from "../lib/fonts";
import { useLayout } from "../lib/aspect";
import { hexToRgba, rand } from "../lib/anim";

export const nowruz3DSchema = z.object({
  greeting: z.string(),
  subtitle: z.string(),
  message: z.string(),
  ...colorSchema,
});

type Props = z.infer<typeof nowruz3DSchema>;

const GOLD = "#f5c542";
const RED = "#e23b3b";
const SKIN = "#f0b486";
const GREEN = "#4fb84f";

// ── Stylized 3D Haji Firuz (primitive-built, clay-render look) ────────────────
const HajiFiruz3D: React.FC = () => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  const enter = spring({ frame: frame - 20, fps, config: { damping: 14, stiffness: 60 } });
  const bob = Math.abs(Math.sin(frame / 7)) * 0.12 * enter;
  const sway = Math.sin(frame / 7) * 0.08 * enter;
  const armSwing = Math.sin(frame / 3.2) * 0.5;
  const y = -0.5 + bob;

  return (
    <group position={[0, y, 0]} rotation={[0, sway, 0]} scale={enter}>
      {/* tunic (tapered) */}
      <mesh position={[0, 0.55, 0]} castShadow>
        <cylinderGeometry args={[0.32, 0.6, 1.1, 32]} />
        <meshStandardMaterial color={RED} roughness={0.55} metalness={0.05} />
      </mesh>
      {/* gold hem + sash */}
      <mesh position={[0, 0.05, 0]}>
        <cylinderGeometry args={[0.6, 0.62, 0.12, 32]} />
        <meshStandardMaterial color={GOLD} roughness={0.25} metalness={0.85} />
      </mesh>
      <mesh position={[0, 0.55, 0.0]}>
        <torusGeometry args={[0.42, 0.05, 12, 32]} />
        <meshStandardMaterial color={GOLD} roughness={0.25} metalness={0.85} />
      </mesh>
      {/* buttons */}
      {[0.75, 0.6, 0.45].map((by, i) => (
        <mesh key={i} position={[0, by, 0.46 - i * 0.02]}>
          <sphereGeometry args={[0.04, 16, 16]} />
          <meshStandardMaterial color={GOLD} metalness={0.9} roughness={0.2} />
        </mesh>
      ))}
      {/* head */}
      <mesh position={[0, 1.32, 0]} castShadow>
        <sphereGeometry args={[0.33, 32, 32]} />
        <meshStandardMaterial color={SKIN} roughness={0.6} />
      </mesh>
      {/* eyes */}
      {[-0.12, 0.12].map((ex, i) => (
        <mesh key={i} position={[ex, 1.36, 0.3]}>
          <sphereGeometry args={[0.045, 16, 16]} />
          <meshStandardMaterial color="#2a2030" roughness={0.4} />
        </mesh>
      ))}
      {/* smile */}
      <mesh position={[0, 1.24, 0.3]} rotation={[0, 0, 0]}>
        <torusGeometry args={[0.1, 0.018, 12, 24, Math.PI]} />
        <meshStandardMaterial color="#7a3a30" roughness={0.5} />
      </mesh>
      {/* hat (cone) + band + tip */}
      <mesh position={[0, 1.95, 0]} castShadow>
        <coneGeometry args={[0.34, 0.8, 32]} />
        <meshStandardMaterial color={RED} roughness={0.5} metalness={0.05} />
      </mesh>
      <mesh position={[0, 1.62, 0]}>
        <cylinderGeometry args={[0.35, 0.35, 0.1, 32]} />
        <meshStandardMaterial color={GOLD} roughness={0.25} metalness={0.85} />
      </mesh>
      <mesh position={[0, 2.36, 0]}>
        <sphereGeometry args={[0.07, 16, 16]} />
        <meshStandardMaterial color={GOLD} metalness={0.9} roughness={0.2} />
      </mesh>
      {/* right arm (down, swings) */}
      <group position={[0.45, 0.95, 0]} rotation={[0, 0, -0.5 + armSwing * 0.3]}>
        <mesh position={[0, -0.3, 0]} castShadow>
          <capsuleGeometry args={[0.1, 0.5, 8, 16]} />
          <meshStandardMaterial color={RED} roughness={0.55} />
        </mesh>
        <mesh position={[0, -0.62, 0]}>
          <sphereGeometry args={[0.12, 16, 16]} />
          <meshStandardMaterial color={SKIN} roughness={0.6} />
        </mesh>
      </group>
      {/* left arm raised with tambourine */}
      <group position={[-0.45, 1.0, 0.05]} rotation={[0, 0, 0.9 + armSwing * 0.4]}>
        <mesh position={[0, 0.28, 0]} castShadow>
          <capsuleGeometry args={[0.1, 0.5, 8, 16]} />
          <meshStandardMaterial color={RED} roughness={0.55} />
        </mesh>
        <group position={[0, 0.6, 0]} rotation={[Math.PI / 2, 0, armSwing]}>
          <mesh>
            <torusGeometry args={[0.26, 0.05, 16, 32]} />
            <meshStandardMaterial color={GOLD} metalness={0.85} roughness={0.25} />
          </mesh>
          <mesh>
            <circleGeometry args={[0.24, 32]} />
            <meshStandardMaterial color="#fff3d6" roughness={0.4} side={THREE.DoubleSide} transparent opacity={0.85} />
          </mesh>
          {Array.from({ length: 8 }).map((_, i) => (
            <mesh key={i} position={[Math.cos((i / 8) * Math.PI * 2) * 0.26, Math.sin((i / 8) * Math.PI * 2) * 0.26, 0]}>
              <sphereGeometry args={[0.035, 12, 12]} />
              <meshStandardMaterial color={GOLD} metalness={0.9} roughness={0.2} />
            </mesh>
          ))}
        </group>
      </group>
      {/* legs */}
      {[-0.16, 0.16].map((lx, i) => (
        <mesh key={i} position={[lx, -0.2, 0]} castShadow>
          <capsuleGeometry args={[0.1, 0.3, 8, 16]} />
          <meshStandardMaterial color="#2a2f45" roughness={0.6} />
        </mesh>
      ))}
    </group>
  );
};

// ── Haft-Sin props ───────────────────────────────────────────────────────────
const Candle: React.FC<{ x: number; z: number }> = ({ x, z }) => {
  const frame = useCurrentFrame();
  const flick = 1 + Math.sin(frame / 4) * 0.12;
  return (
    <group position={[x, -0.5, z]}>
      <mesh castShadow>
        <cylinderGeometry args={[0.09, 0.1, 0.5, 24]} />
        <meshStandardMaterial color="#fbf0d8" roughness={0.6} />
      </mesh>
      <mesh position={[0, 0.34, 0]} scale={[1, flick, 1]}>
        <coneGeometry args={[0.05, 0.18, 16]} />
        <meshStandardMaterial color="#ffd27a" emissive="#ffae3b" emissiveIntensity={4} toneMapped={false} />
      </mesh>
      <pointLight position={[0, 0.4, 0]} intensity={2.2 * flick} color="#ffb14d" distance={3} />
    </group>
  );
};

const Egg: React.FC<{ x: number; z: number; color: string }> = ({ x, z, color }) => (
  <mesh position={[x, -0.42, z]} scale={[1, 1.3, 1]} castShadow>
    <sphereGeometry args={[0.14, 24, 24]} />
    <meshStandardMaterial color={color} roughness={0.35} metalness={0.1} />
  </mesh>
);

const FishBowl3D: React.FC<{ x: number; z: number }> = ({ x, z }) => {
  const frame = useCurrentFrame();
  const fishX = Math.sin(frame / 20) * 0.12;
  return (
    <group position={[x, -0.25, z]}>
      {/* water */}
      <mesh position={[0, -0.02, 0]}>
        <sphereGeometry args={[0.27, 32, 32]} />
        <meshStandardMaterial color="#5bc8f0" roughness={0.1} metalness={0.2} transparent opacity={0.55} />
      </mesh>
      {/* fish */}
      <mesh position={[fishX, -0.02, 0]} scale={[0.13, 0.08, 0.05]}>
        <sphereGeometry args={[1, 16, 16]} />
        <meshStandardMaterial color="#ff5a2c" roughness={0.4} emissive="#ff4a1a" emissiveIntensity={0.2} />
      </mesh>
      {/* glass */}
      <mesh>
        <sphereGeometry args={[0.32, 32, 32]} />
        <meshPhysicalMaterial color="#ffffff" roughness={0.05} metalness={0} transmission={0.0} transparent opacity={0.18} ior={1.4} />
      </mesh>
    </group>
  );
};

const Sabzeh3D: React.FC<{ x: number; z: number }> = ({ x, z }) => {
  const frame = useCurrentFrame();
  return (
    <group position={[x, -0.5, z]}>
      <mesh position={[0, 0.05, 0]} castShadow>
        <cylinderGeometry args={[0.26, 0.22, 0.18, 24]} />
        <meshStandardMaterial color="#caa06a" roughness={0.7} />
      </mesh>
      {Array.from({ length: 30 }).map((_, i) => {
        const a = rand(i) * Math.PI * 2;
        const r = rand(i + 5) * 0.22;
        const sway = Math.sin(frame / 18 + i) * 0.08;
        return (
          <mesh key={i} position={[Math.cos(a) * r, 0.28, Math.sin(a) * r]} rotation={[sway, 0, sway]}>
            <coneGeometry args={[0.012, 0.3 + rand(i + 2) * 0.2, 5]} />
            <meshStandardMaterial color={i % 2 ? GREEN : "#3da53d"} roughness={0.7} />
          </mesh>
        );
      })}
    </group>
  );
};

const Petals3D: React.FC = () => {
  const frame = useCurrentFrame();
  return (
    <group>
      {Array.from({ length: 30 }).map((_, i) => {
        const x = (rand(i) - 0.5) * 9;
        const z = (rand(i + 3) - 0.5) * 4 - 1;
        const fall = 4 - ((frame * (0.01 + rand(i) * 0.02) + rand(i + 7) * 6) % 7);
        const rot = frame * 0.03 * (1 + rand(i));
        return (
          <mesh key={i} position={[x + Math.sin(frame / 30 + i) * 0.4, fall, z]} rotation={[rot, rot * 0.7, rot * 0.3]}>
            <circleGeometry args={[0.06 + rand(i + 1) * 0.05, 8]} />
            <meshStandardMaterial color={["#ffd1e8", "#ffc1dd", "#fff0f6"][i % 3]} side={THREE.DoubleSide} roughness={0.6} />
          </mesh>
        );
      })}
    </group>
  );
};

// ── Scene ────────────────────────────────────────────────────────────────────
const Scene: React.FC = () => {
  const frame = useCurrentFrame();
  const orbit = Math.sin(frame / 110) * 0.22;
  return (
    <group rotation={[0, orbit, 0]}>
      <ambientLight intensity={0.5} />
      <directionalLight position={[4, 8, 4]} intensity={2.4} color="#fff3e0" castShadow shadow-mapSize={[1024, 1024]} />
      <pointLight position={[-4, 2, 3]} intensity={20} color="#ff8a5c" />
      <pointLight position={[4, 1, -2]} intensity={16} color={GOLD} />

      <Environment resolution={256}>
        <Lightformer intensity={2} position={[0, 4, -3]} scale={[10, 5, 1]} color="#fff0d8" />
        <Lightformer intensity={1.2} position={[-4, 2, 2]} scale={[4, 6, 1]} color="#ffb98a" />
        <Lightformer intensity={1.2} position={[4, 2, 2]} scale={[4, 6, 1]} color="#9ad8e8" />
      </Environment>

      {/* reflective floor */}
      <mesh rotation={[-Math.PI / 2, 0, 0]} position={[0, -0.62, 0]} receiveShadow>
        <planeGeometry args={[40, 40]} />
        <MeshReflectorMaterial
          blur={[300, 80]}
          resolution={1024}
          mixBlur={1}
          mixStrength={45}
          roughness={0.85}
          depthScale={1}
          minDepthThreshold={0.4}
          maxDepthThreshold={1.2}
          color="#2a2236"
          metalness={0.5}
        />
      </mesh>

      <HajiFiruz3D />
      <FishBowl3D x={1.5} z={0.3} />
      <Sabzeh3D x={-1.5} z={0.2} />
      <Candle x={0.9} z={0.9} />
      <Candle x={-0.9} z={0.9} />
      <Egg x={0.5} z={1.1} color={RED} />
      <Egg x={-0.4} z={1.15} color="#5bc8f0" />
      <Egg x={1.0} z={-0.4} color={GOLD} />
      <Petals3D />
    </group>
  );
};

export const Nowruz3D: React.FC<Props> = ({
  greeting,
  subtitle,
  message,
  accentColor,
  secondaryColor,
  backgroundColor,
  textColor,
}) => {
  const frame = useCurrentFrame();
  const { width, height } = useVideoConfig();
  const L = useLayout();

  const gSpring = spring({ frame: frame - 120, fps: 30, config: { damping: 13, stiffness: 90 } });
  const gScale = interpolate(gSpring, [0, 1], [0.6, 1]);
  const gOp = interpolate(frame, [120, 140], [0, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp" });
  const subOp = interpolate(frame, [142, 162], [0, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp" });
  const msgOp = interpolate(frame, [156, 176], [0, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp" });

  return (
    <AbsoluteFill style={{ backgroundColor }}>
      <AbsoluteFill style={{ background: `radial-gradient(circle at 50% 35%, ${hexToRgba(accentColor, 0.22)} 0%, ${hexToRgba(secondaryColor, 0.08)} 38%, ${backgroundColor} 72%)` }} />

      <ThreeCanvas
        width={width}
        height={height}
        camera={{ position: [0, 2.0, 5.0], fov: 50 }}
        shadows
        style={{ position: "absolute", inset: 0 }}
        gl={{ toneMapping: THREE.ACESFilmicToneMapping, antialias: true }}
      >
        <Scene />
        <EffectComposer>
          <Bloom intensity={0.75} luminanceThreshold={0.62} luminanceSmoothing={0.3} mipmapBlur />
          <DepthOfField focusDistance={0.013} focalLength={0.045} bokehScale={3} />
          <Vignette eskil={false} offset={0.32} darkness={0.55} />
        </EffectComposer>
      </ThreeCanvas>

      {/* Greeting overlay */}
      <AbsoluteFill style={{ fontFamily: FONT, direction: "rtl", alignItems: "center", justifyContent: "flex-start", paddingTop: height * 0.05 }}>
        <div style={{ transform: `scale(${gScale})`, opacity: gOp, fontWeight: 900, fontSize: L.vmin(96), color: textColor, textShadow: `0 ${L.vmin(3)}px ${L.vmin(6)}px ${hexToRgba("#1a0a00", 0.7)}, 0 0 ${L.vmin(30)}px ${hexToRgba(accentColor, 0.7)}` }}>
          {greeting}
        </div>
        <div style={{ marginTop: L.vmin(12), opacity: subOp, fontWeight: 700, fontSize: L.vmin(32), color: textColor, textShadow: `0 ${L.vmin(2)}px ${L.vmin(6)}px ${hexToRgba("#1a0a00", 0.8)}` }}>
          {subtitle}
        </div>
        <div style={{ marginTop: L.vmin(8), opacity: msgOp, fontWeight: 600, fontSize: L.vmin(26), color: hexToRgba(textColor, 0.9) }}>
          {message}
        </div>
      </AbsoluteFill>
    </AbsoluteFill>
  );
};
