import { motion, useInView, useReducedMotion } from 'framer-motion';
import { useRef } from 'react';

/* ── Scene constants ─────────────────────────────────────── */
const CX = 240; // sphere / composition centre x
const SY = 228; // sphere centre y
const SR = 80; // sphere radius
const RCX = 240,
    RCY = 226; // node-ring centre
const RX = 172,
    RY = 152; // node-ring radii

/* ── Palette — teal / orange / navy with brand orange ────── */
const TEAL_LINE = '#2EB4AE';
const ORANGE_LINE = '#FB6B2C';
const NAVY_LINE = '#6B92C7';

type Tone = 'teal' | 'orange' | 'navy';

const TONES: Record<
    Tone,
    { line: string; depth: string; face: string; rim: string }
> = {
    teal: {
        line: TEAL_LINE,
        depth: '#07363B',
        face: 'url(#ilxFaceTeal)',
        rim: 'url(#ilxRimTeal)',
    },
    orange: {
        line: ORANGE_LINE,
        depth: '#6E2803',
        face: 'url(#ilxFaceOrange)',
        rim: 'url(#ilxRimOrange)',
    },
    navy: {
        line: NAVY_LINE,
        depth: '#0F1D36',
        face: 'url(#ilxFaceNavy)',
        rim: 'url(#ilxRimNavy)',
    },
};

/* ── Hexagon geometry (pointy-top, centred at 0,0) ───────── */
function hexPath(r: number): string {
    const w = (r * 0.866).toFixed(2);
    const h = (r / 2).toFixed(2);
    return `M0,${-r} L${w},${-h} L${w},${h} L0,${r} L${-w},${h} L${-w},${-h} Z`;
}

const HEX_OUTER = hexPath(37); // + strokeWidth 6 → rounded silhouette ≈ r40
const HEX_INNER = hexPath(28.5);
/* Upper portion of inner hex — glass gloss overlay */
const HEX_GLOSS =
    'M0,-28.5 L24.68,-14.25 L24.68,-3 Q0,7 -24.68,-3 L-24.68,-14.25 Z';

/* ── Stage icons — white line work, ~30px box, centred ───── */
function DocIcon(): JSX.Element {
    return (
        <g
            stroke="#fff"
            strokeWidth="2"
            strokeLinecap="round"
            strokeLinejoin="round"
            fill="none"
        >
            <path d="M-10,-14 h13 l7,7 v21 h-20 z" />
            <path d="M3,-14 v7 h7" />
            <line x1="-5" y1="-1" x2="5" y2="-1" />
            <line x1="-5" y1="4" x2="5" y2="4" />
            <line x1="-5" y1="9" x2="0" y2="9" />
        </g>
    );
}

function ShieldCheckIcon(): JSX.Element {
    return (
        <g
            stroke="#fff"
            strokeWidth="2.2"
            strokeLinecap="round"
            strokeLinejoin="round"
            fill="none"
        >
            <path d="M0,-15 L11.5,-10.5 L11.5,-1 C11.5,7.5 6,13 0,15 C-6,13 -11.5,7.5 -11.5,-1 L-11.5,-10.5 Z" />
            <polyline points="-5,-1 -1.5,4 6,-5" strokeWidth="2.5" />
        </g>
    );
}

function TransferIcon(): JSX.Element {
    return (
        <g
            stroke="#fff"
            strokeWidth="2"
            strokeLinecap="round"
            strokeLinejoin="round"
            fill="none"
        >
            <ellipse cx="0" cy="10" rx="9" ry="3.4" />
            <ellipse cx="0" cy="5.5" rx="9" ry="3.4" />
            <ellipse cx="0" cy="1" rx="9" ry="3.4" />
            <line x1="0" y1="-3.5" x2="0" y2="-12.5" />
            <polyline points="-4,-8.5 0,-13 4,-8.5" />
        </g>
    );
}

function RepaymentIcon(): JSX.Element {
    return (
        <g
            stroke="#fff"
            strokeWidth="2.3"
            strokeLinecap="round"
            strokeLinejoin="round"
            fill="none"
        >
            <path d="M-11,0 A11,11 0 0 1 11,0" />
            <polyline points="7.1,-4.7 11,0 14.9,-4.7" />
            <path d="M11,0 A11,11 0 0 1 -11,0" />
            <polyline points="-14.9,4.7 -11,0 -7.1,4.7" />
        </g>
    );
}

function CollectionsIcon(): JSX.Element {
    return (
        <g
            stroke="#fff"
            strokeWidth="2"
            strokeLinecap="round"
            strokeLinejoin="round"
            fill="none"
        >
            <path d="M-13,-14 h16 v9" />
            <path d="M-13,-14 v23 h9" />
            <line x1="-8.5" y1="-8" x2="-1" y2="-8" />
            <line x1="-8.5" y1="-3" x2="-3" y2="-3" />
            <circle cx="5.5" cy="4" r="7" />
            <line x1="10.5" y1="9" x2="15" y2="13.5" strokeWidth="2.8" />
        </g>
    );
}

function AnalyticsIcon(): JSX.Element {
    return (
        <g fill="#fff" stroke="none">
            <rect
                x="-13.5"
                y="1"
                width="6.5"
                height="11"
                rx="1.2"
                opacity="0.7"
            />
            <rect
                x="-3.5"
                y="-5"
                width="6.5"
                height="17"
                rx="1.2"
                opacity="0.85"
            />
            <rect x="6.5" y="-11" width="6.5" height="23" rx="1.2" />
            <rect
                x="-14.5"
                y="14"
                width="28"
                height="1.8"
                rx="0.9"
                opacity="0.4"
            />
        </g>
    );
}

/* ── Stage definitions — angles on the node ring ─────────── */
const STAGES: Array<{
    label: string;
    tone: Tone;
    deg: number;
    labelAbove: boolean;
    Icon: () => JSX.Element;
}> = [
    {
        label: 'Application',
        tone: 'teal',
        deg: 240,
        labelAbove: true,
        Icon: DocIcon,
    },
    {
        label: 'Approval',
        tone: 'orange',
        deg: 300,
        labelAbove: true,
        Icon: ShieldCheckIcon,
    },
    {
        label: 'Disbursement',
        tone: 'teal',
        deg: 0,
        labelAbove: false,
        Icon: TransferIcon,
    },
    {
        label: 'Repayment',
        tone: 'navy',
        deg: 60,
        labelAbove: false,
        Icon: RepaymentIcon,
    },
    {
        label: 'Collections',
        tone: 'teal',
        deg: 120,
        labelAbove: false,
        Icon: CollectionsIcon,
    },
    {
        label: 'Analytics',
        tone: 'navy',
        deg: 180,
        labelAbove: false,
        Icon: AnalyticsIcon,
    },
];

function nodePos(deg: number): { x: number; y: number } {
    const t = (deg * Math.PI) / 180;
    return {
        x: Math.round(RCX + RX * Math.cos(t)),
        y: Math.round(RCY + RY * Math.sin(t)),
    };
}

/* ── HexNode — floating glass hexagonal prism ────────────── */
function HexNode({
    stage,
    index,
    inView,
    reduce,
}: {
    stage: (typeof STAGES)[number];
    index: number;
    inView: boolean;
    reduce: boolean;
}): JSX.Element {
    const { x, y } = nodePos(stage.deg);
    const tone = TONES[stage.tone];

    return (
        <g transform={`translate(${x} ${y})`}>
            {/* Entrance spring */}
            <motion.g
                initial={{ opacity: 0, scale: 0.5 }}
                animate={inView ? { opacity: 1, scale: 1 } : {}}
                transition={{
                    duration: 0.55,
                    delay: 0.35 + index * 0.1,
                    type: 'spring',
                    stiffness: 230,
                    damping: 19,
                }}
                style={{ originX: '0px', originY: '0px' }}
            >
                {/* Label — outside the bob layer so it stays put */}
                <text
                    x={0}
                    y={stage.labelAbove ? -56 : 62}
                    textAnchor="middle"
                    style={{ fill: 'hsl(var(--il-text))' }}
                    fontSize={13.5}
                    fontWeight={600}
                    letterSpacing="0.2"
                >
                    {stage.label}
                </text>

                {/* Gentle float */}
                <motion.g
                    animate={inView && !reduce ? { y: [0, -5, 0] } : undefined}
                    transition={{
                        duration: 3.6 + index * 0.4,
                        repeat: Infinity,
                        ease: 'easeInOut',
                        delay: 1 + index * 0.33,
                    }}
                >
                    {/* Ambient glow */}
                    <ellipse
                        cx={0}
                        cy={0}
                        rx={44}
                        ry={40}
                        fill={tone.line}
                        opacity={0.16}
                        filter="url(#ilxBlur6)"
                    />

                    {/* Prism depth — dark hex offset below */}
                    <path
                        d={HEX_OUTER}
                        transform="translate(0 7)"
                        fill={tone.depth}
                        stroke={tone.depth}
                        strokeWidth="6"
                        strokeLinejoin="round"
                    />

                    {/* Outer rim */}
                    <path
                        d={HEX_OUTER}
                        fill={tone.rim}
                        stroke={tone.rim}
                        strokeWidth="6"
                        strokeLinejoin="round"
                    />
                    {/* Rim edge light */}
                    <path
                        d={HEX_OUTER}
                        fill="none"
                        stroke="#fff"
                        strokeWidth="1"
                        strokeLinejoin="round"
                        opacity={0.22}
                    />

                    {/* Inner glossy face */}
                    <path
                        d={HEX_INNER}
                        fill={tone.face}
                        stroke={tone.face}
                        strokeWidth="5"
                        strokeLinejoin="round"
                    />

                    {/* Glass gloss — upper half sheen */}
                    <path d={HEX_GLOSS} fill="url(#ilxGloss)" opacity={0.32} />

                    {/* Icon */}
                    <stage.Icon />
                </motion.g>
            </motion.g>
        </g>
    );
}

/* ── Component ────────────────────────────────────────────── */
interface Props {
    className?: string;
}

export function IsometricLoanIllustration({ className = '' }: Props) {
    const ref = useRef<SVGSVGElement>(null);
    const inView = useInView(ref, { once: true, margin: '-60px' });
    const reduce = useReducedMotion() ?? false;

    return (
        <svg
            ref={ref}
            viewBox="0 0 480 480"
            className={className}
            fill="none"
            aria-hidden="true"
        >
            <defs>
                {/* Central sphere — offset radial = studio key light */}
                <radialGradient id="ilxSphere" cx="36%" cy="27%" r="80%">
                    <stop offset="0%" stopColor="#7FE8EE" />
                    <stop offset="28%" stopColor="#2FAFC0" />
                    <stop offset="55%" stopColor="#15788C" />
                    <stop offset="78%" stopColor="#145073" />
                    <stop offset="100%" stopColor="#182E52" />
                </radialGradient>

                {/* Hex face gradients — light top → deep bottom */}
                <linearGradient id="ilxFaceTeal" x1="0" y1="0" x2="0.35" y2="1">
                    <stop offset="0%" stopColor="#8BEDE5" />
                    <stop offset="50%" stopColor="#31B0AA" />
                    <stop offset="100%" stopColor="#0F6B6E" />
                </linearGradient>
                <linearGradient id="ilxRimTeal" x1="0" y1="0" x2="0" y2="1">
                    <stop offset="0%" stopColor="#2A968F" />
                    <stop offset="100%" stopColor="#0A474C" />
                </linearGradient>

                <linearGradient
                    id="ilxFaceOrange"
                    x1="0"
                    y1="0"
                    x2="0.35"
                    y2="1"
                >
                    <stop offset="0%" stopColor="#FFC493" />
                    <stop offset="50%" stopColor="#FA7A2E" />
                    <stop offset="100%" stopColor="#CC4A0B" />
                </linearGradient>
                <linearGradient id="ilxRimOrange" x1="0" y1="0" x2="0" y2="1">
                    <stop offset="0%" stopColor="#DE5E17" />
                    <stop offset="100%" stopColor="#8A3305" />
                </linearGradient>

                <linearGradient id="ilxFaceNavy" x1="0" y1="0" x2="0.35" y2="1">
                    <stop offset="0%" stopColor="#88ADE0" />
                    <stop offset="50%" stopColor="#40639B" />
                    <stop offset="100%" stopColor="#1E3459" />
                </linearGradient>
                <linearGradient id="ilxRimNavy" x1="0" y1="0" x2="0" y2="1">
                    <stop offset="0%" stopColor="#3E5E92" />
                    <stop offset="100%" stopColor="#152643" />
                </linearGradient>

                {/* Glass sheen — white fading downward */}
                <linearGradient id="ilxGloss" x1="0" y1="0" x2="0" y2="1">
                    <stop offset="0%" stopColor="#fff" stopOpacity="0.95" />
                    <stop offset="100%" stopColor="#fff" stopOpacity="0" />
                </linearGradient>

                {/* Platform faces */}
                <linearGradient id="ilxPlatTop" x1="0" y1="0" x2="0.55" y2="1">
                    <stop offset="0%" stopColor="#93E6E0" />
                    <stop offset="45%" stopColor="#2F949E" />
                    <stop offset="100%" stopColor="#135A69" />
                </linearGradient>
                <linearGradient id="ilxPlatSide" x1="0" y1="0" x2="0" y2="1">
                    <stop offset="0%" stopColor="#0E4A57" />
                    <stop offset="100%" stopColor="#082C3A" />
                </linearGradient>

                <filter
                    id="ilxBlur6"
                    x="-60%"
                    y="-60%"
                    width="220%"
                    height="220%"
                >
                    <feGaussianBlur stdDeviation="6" />
                </filter>
                <filter
                    id="ilxBlur3"
                    x="-60%"
                    y="-60%"
                    width="220%"
                    height="220%"
                >
                    <feGaussianBlur stdDeviation="2.5" />
                </filter>
            </defs>

            {/* ── Orbit ring + connectors — beneath everything ── */}
            <motion.g
                initial={{ opacity: 0 }}
                animate={inView ? { opacity: 1 } : {}}
                transition={{ duration: 0.8, delay: 0.15 }}
            >
                <ellipse
                    cx={RCX}
                    cy={RCY}
                    rx={RX}
                    ry={RY}
                    stroke={TEAL_LINE}
                    strokeWidth="1.2"
                    opacity={0.28}
                />
                {STAGES.map((s) => {
                    const { x, y } = nodePos(s.deg);
                    return (
                        <line
                            key={s.label}
                            x1={x}
                            y1={y}
                            x2={CX}
                            y2={SY}
                            stroke={TONES[s.tone].line}
                            strokeWidth="1.2"
                            opacity={0.32}
                        />
                    );
                })}

                {/* Pulses travelling node → hub */}
                {!reduce &&
                    STAGES.map((s, i) => {
                        const { x, y } = nodePos(s.deg);
                        return (
                            <motion.circle
                                key={s.label}
                                r={2.6}
                                fill={TONES[s.tone].line}
                                initial={{ cx: x, cy: y, opacity: 0 }}
                                animate={
                                    inView
                                        ? {
                                              cx: [x, CX],
                                              cy: [y, SY],
                                              opacity: [0, 0.85, 0],
                                          }
                                        : {}
                                }
                                transition={{
                                    duration: 2.4,
                                    repeat: Infinity,
                                    repeatDelay: 3.2,
                                    delay: 1.6 + i * 0.9,
                                    ease: 'easeInOut',
                                }}
                            />
                        );
                    })}
            </motion.g>

            {/* ── Platform + sphere ───────────────────────────── */}
            <motion.g
                initial={{ opacity: 0, scale: 0.9 }}
                animate={inView ? { opacity: 1, scale: 1 } : {}}
                transition={{
                    duration: 0.6,
                    delay: 0.1,
                    type: 'spring',
                    stiffness: 200,
                    damping: 21,
                }}
                style={{ originX: `${CX}px`, originY: `${SY + 60}px` }}
            >
                {/* Floor shadow + under-glow */}
                <ellipse
                    cx={240}
                    cy={412}
                    rx={112}
                    ry={15}
                    fill="#000"
                    opacity={0.16}
                    filter="url(#ilxBlur6)"
                />
                <ellipse
                    cx={240}
                    cy={408}
                    rx={95}
                    ry={13}
                    fill={TEAL_LINE}
                    opacity={0.12}
                    filter="url(#ilxBlur6)"
                />

                {/* Floating platform */}
                <g transform="translate(240 326)">
                    {/* Side extrusion — band between top face and its copy 16px down */}
                    <path
                        d="M-104.7,0 Q-104.7,3.25 -97.4,6.5 L-14.6,43.5 Q0,50 14.6,43.5 L97.4,6.5 Q104.7,3.25 104.7,0 L104.7,16 Q104.7,19.25 97.4,22.5 L14.6,59.5 Q0,66 -14.6,59.5 L-97.4,22.5 Q-104.7,19.25 -104.7,16 Z"
                        fill="url(#ilxPlatSide)"
                    />
                    {/* Rounded-diamond top face */}
                    <path
                        d="M-97.4,-6.5 L-14.6,-43.5 Q0,-50 14.6,-43.5 L97.4,-6.5 Q112,0 97.4,6.5 L14.6,43.5 Q0,50 -14.6,43.5 L-97.4,6.5 Q-112,0 -97.4,-6.5 Z"
                        fill="url(#ilxPlatTop)"
                    />
                    <path
                        d="M-97.4,-6.5 L-14.6,-43.5 Q0,-50 14.6,-43.5 L97.4,-6.5 Q112,0 97.4,6.5 L14.6,43.5 Q0,50 -14.6,43.5 L-97.4,6.5 Q-112,0 -97.4,-6.5 Z"
                        fill="none"
                        stroke="#B8F1EC"
                        strokeWidth="1"
                        opacity={0.35}
                    />
                    {/* Sphere contact shadow on the platform */}
                    <ellipse
                        cx={0}
                        cy={-10}
                        rx={46}
                        ry={13}
                        fill="#041F26"
                        opacity={0.32}
                        filter="url(#ilxBlur3)"
                    />
                </g>

                {/* Sphere — gentle float */}
                <motion.g
                    animate={inView && !reduce ? { y: [0, -6, 0] } : undefined}
                    transition={{
                        duration: 5,
                        repeat: Infinity,
                        ease: 'easeInOut',
                        delay: 0.9,
                    }}
                >
                    {/* Halo */}
                    <circle
                        cx={CX}
                        cy={SY}
                        r={SR + 14}
                        fill={TEAL_LINE}
                        opacity={0.08}
                        filter="url(#ilxBlur6)"
                    />
                    <circle cx={CX} cy={SY} r={SR} fill="url(#ilxSphere)" />
                    {/* Reflected platform light along the lower limb */}
                    <ellipse
                        cx={CX}
                        cy={SY + 62}
                        rx={50}
                        ry={13}
                        fill="#2FB8C4"
                        opacity={0.2}
                        filter="url(#ilxBlur3)"
                    />
                    {/* Specular highlights */}
                    <ellipse
                        cx={CX - 33}
                        cy={SY - 48}
                        rx={26}
                        ry={15}
                        fill="#fff"
                        opacity={0.5}
                        transform={`rotate(-28 ${CX - 33} ${SY - 48})`}
                        filter="url(#ilxBlur3)"
                    />
                    <ellipse
                        cx={CX - 39}
                        cy={SY - 53}
                        rx={10}
                        ry={5.5}
                        fill="#fff"
                        opacity={0.85}
                        transform={`rotate(-28 ${CX - 39} ${SY - 53})`}
                    />

                    {/* Hub label */}
                    <text
                        x={CX}
                        y={SY - 4}
                        textAnchor="middle"
                        fill="#EDFDFD"
                        fontSize={23}
                        fontWeight={600}
                        letterSpacing="0.3"
                    >
                        Loan
                    </text>
                    <text
                        x={CX}
                        y={SY + 24}
                        textAnchor="middle"
                        fill="#EDFDFD"
                        fontSize={23}
                        fontWeight={600}
                        letterSpacing="0.3"
                    >
                        Lifecycle
                    </text>
                </motion.g>
            </motion.g>

            {/* ── Orbiting stage prisms — in front ────────────── */}
            {STAGES.map((s, i) => (
                <HexNode
                    key={s.label}
                    stage={s}
                    index={i}
                    inView={inView}
                    reduce={reduce}
                />
            ))}
        </svg>
    );
}
