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

/* ── Palette — shared with IsometricLoanIllustration ──────── */
const TEAL_LINE = '#2EB4AE';
const ORANGE_LINE = '#FB6B2C';
const NAVY_LINE = '#6B92C7';

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

const TONES: Record<Tone, { line: string; top: string; side: string }> = {
    teal: {
        line: TEAL_LINE,
        top: 'url(#ofxTopTeal)',
        side: 'url(#ofxSideTeal)',
    },
    orange: {
        line: ORANGE_LINE,
        top: 'url(#ofxTopOrange)',
        side: 'url(#ofxSideOrange)',
    },
    navy: {
        line: NAVY_LINE,
        top: 'url(#ofxTopNavy)',
        side: 'url(#ofxSideNavy)',
    },
};

/* ── Slab geometry (local coords, centred at 0,0) ──────────
 * Rounded isometric diamond: half-width 58, half-height 29,
 * corner cut 10, extruded 14 down. Rounded tip apex x = ±53.55.
 */
const QH = 29; // half diamond height
const TIP = 54; // connector attach x (≈ rounded tip apex)

const SLAB_TOP =
    'M-49.1,-4.5 L-8.9,-24.5 Q0,-29 8.9,-24.5 L49.1,-4.5 Q58,0 49.1,4.5 ' +
    'L8.9,24.5 Q0,29 -8.9,24.5 L-49.1,4.5 Q-58,0 -49.1,-4.5 Z';

/* Side band — bottom silhouette of the top face joined to its copy 14px down */
const SLAB_SIDE =
    'M-53.55,0 Q-53.55,2.25 -49.1,4.5 L-8.9,24.5 Q0,29 8.9,24.5 L49.1,4.5 ' +
    'Q53.55,2.25 53.55,0 L53.55,14 Q53.55,16.25 49.1,18.5 L8.9,38.5 Q0,43 ' +
    '-8.9,38.5 L-49.1,18.5 Q-53.55,16.25 -53.55,14 Z';

/* ── Step icons — white line work, centred at 0,0 ─────────── */
function SignUpIcon(): JSX.Element {
    return (
        <g stroke="#fff" strokeWidth="1.9" strokeLinecap="round" fill="none">
            <circle cx="-1.5" cy="-8" r="5" />
            <path d="M-10,7 Q-10,-0.5 -1.5,-0.5 Q7,-0.5 7,7" />
            <line x1="7" y1="-8" x2="13" y2="-8" />
            <line x1="10" y1="-11" x2="10" y2="-5" />
        </g>
    );
}

function ConfigureIcon(): JSX.Element {
    return (
        <g stroke="#fff" strokeWidth="1.9" strokeLinecap="round" fill="none">
            <line x1="-10" y1="-7.5" x2="10" y2="-7.5" />
            <line x1="-10" y1="0" x2="10" y2="0" />
            <line x1="-10" y1="7.5" x2="10" y2="7.5" />
            <circle cx="-4" cy="-7.5" r="2.7" fill="#fff" stroke="none" />
            <circle cx="5" cy="0" r="2.7" fill="#fff" stroke="none" />
            <circle cx="-1.5" cy="7.5" r="2.7" fill="#fff" stroke="none" />
        </g>
    );
}

function ImportIcon(): JSX.Element {
    return (
        <g
            stroke="#fff"
            strokeWidth="1.9"
            strokeLinecap="round"
            strokeLinejoin="round"
            fill="none"
        >
            <line x1="0" y1="-11" x2="0" y2="3" />
            <path d="M-5.5,-2.5 L0,3 L5.5,-2.5" />
            <path d="M-10,3.5 L-10,9 L10,9 L10,3.5" />
        </g>
    );
}

function GoLiveIcon(): JSX.Element {
    return (
        <g
            stroke="#fff"
            strokeWidth="1.9"
            strokeLinecap="round"
            strokeLinejoin="round"
            fill="none"
        >
            <path d="M0,-12 C4.5,-8 5.5,-1 3.5,5 L-3.5,5 C-5.5,-1 -4.5,-8 0,-12 Z" />
            <circle cx="0" cy="-4.5" r="2.2" />
            <path d="M-3.5,1.5 L-7,7.5" />
            <path d="M3.5,1.5 L7,7.5" />
            <line x1="0" y1="8" x2="0" y2="11.5" />
        </g>
    );
}

/* ── Steps: alternating high / low ───────────────────────── */
const STEPS: Array<{
    num: string;
    label: string;
    sub: string;
    tone: Tone;
    cx: number;
    cy: number;
    Icon: () => JSX.Element;
}> = [
    {
        num: '01',
        label: 'Sign Up',
        sub: '60-second setup',
        tone: 'teal',
        cx: 80,
        cy: 100,
        Icon: SignUpIcon,
    },
    {
        num: '02',
        label: 'Configure',
        sub: 'COA + loan products',
        tone: 'orange',
        cx: 220,
        cy: 165,
        Icon: ConfigureIcon,
    },
    {
        num: '03',
        label: 'Import Data',
        sub: 'Clients & history',
        tone: 'navy',
        cx: 360,
        cy: 100,
        Icon: ImportIcon,
    },
    {
        num: '04',
        label: 'Go Live',
        sub: 'Disburse & collect',
        tone: 'teal',
        cx: 500,
        cy: 165,
        Icon: GoLiveIcon,
    },
];

/* Connector: rounded tip of step i → rounded tip of step i+1 */
const CONNS = STEPS.slice(0, -1).map((s, i) => ({
    x1: s.cx + TIP,
    y1: s.cy,
    x2: STEPS[i + 1].cx - TIP,
    y2: STEPS[i + 1].cy,
}));

/* 4-point bezier keyframes for data-dot path following */
function bezierKF(x1: number, y1: number, x2: number, y2: number) {
    const mx = (x1 + x2) / 2;
    return [0, 1 / 3, 2 / 3, 1].map((t) => {
        const mt = 1 - t;
        return {
            x: parseFloat(
                (
                    mt ** 3 * x1 +
                    3 * mt ** 2 * t * mx +
                    3 * mt * t ** 2 * mx +
                    t ** 3 * x2
                ).toFixed(1),
            ),
            y: parseFloat(
                (
                    mt ** 3 * y1 +
                    3 * mt ** 2 * t * y1 +
                    3 * mt * t ** 2 * y2 +
                    t ** 3 * y2
                ).toFixed(1),
            ),
        };
    });
}

/* ── Flowing data dot along connector bezier ──────────────── */
function DataDot({
    conn,
    color,
    delay,
    inView,
}: {
    conn: { x1: number; y1: number; x2: number; y2: number };
    color: string;
    delay: number;
    inView: boolean;
}): JSX.Element {
    const pts = bezierKF(conn.x1, conn.y1, conn.x2, conn.y2);
    const kfTimes = [0, 1 / 3, 2 / 3, 1];
    return (
        <motion.circle
            r={2.8}
            fill={color}
            filter="url(#ofxDotGlow)"
            initial={{ cx: conn.x1, cy: conn.y1, opacity: 0 }}
            animate={
                inView
                    ? {
                          cx: pts.map((p) => p.x),
                          cy: pts.map((p) => p.y),
                          opacity: [0, 1, 1, 0],
                      }
                    : {}
            }
            transition={{
                cx: {
                    duration: 1.3,
                    delay,
                    repeat: Infinity,
                    repeatDelay: 3.5,
                    ease: 'easeInOut',
                    times: kfTimes,
                },
                cy: {
                    duration: 1.3,
                    delay,
                    repeat: Infinity,
                    repeatDelay: 3.5,
                    ease: 'easeInOut',
                    times: kfTimes,
                },
                opacity: {
                    duration: 1.3,
                    delay,
                    repeat: Infinity,
                    repeatDelay: 3.5,
                    times: [0, 0.15, 0.85, 1],
                },
            }}
        />
    );
}

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

export function OnboardingFlowIllustration({ 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 580 280"
            className={className}
            fill="none"
            aria-hidden="true"
        >
            <defs>
                {/* Slab top faces — light top-left → deep bottom-right */}
                <linearGradient id="ofxTopTeal" x1="0" y1="0" x2="0.7" y2="1">
                    <stop offset="0%" stopColor="#8BEDE5" />
                    <stop offset="50%" stopColor="#31B0AA" />
                    <stop offset="100%" stopColor="#0F6B6E" />
                </linearGradient>
                <linearGradient id="ofxSideTeal" x1="0" y1="0" x2="0" y2="1">
                    <stop offset="0%" stopColor="#0E4A57" />
                    <stop offset="100%" stopColor="#082C3A" />
                </linearGradient>

                <linearGradient id="ofxTopOrange" x1="0" y1="0" x2="0.7" y2="1">
                    <stop offset="0%" stopColor="#FFC493" />
                    <stop offset="50%" stopColor="#FA7A2E" />
                    <stop offset="100%" stopColor="#CC4A0B" />
                </linearGradient>
                <linearGradient id="ofxSideOrange" x1="0" y1="0" x2="0" y2="1">
                    <stop offset="0%" stopColor="#7A3208" />
                    <stop offset="100%" stopColor="#4A1C02" />
                </linearGradient>

                <linearGradient id="ofxTopNavy" x1="0" y1="0" x2="0.7" y2="1">
                    <stop offset="0%" stopColor="#88ADE0" />
                    <stop offset="50%" stopColor="#40639B" />
                    <stop offset="100%" stopColor="#1E3459" />
                </linearGradient>
                <linearGradient id="ofxSideNavy" x1="0" y1="0" x2="0" y2="1">
                    <stop offset="0%" stopColor="#1B2F52" />
                    <stop offset="100%" stopColor="#0E1B33" />
                </linearGradient>

                {/* Connector gradients — source tone → target tone */}
                {CONNS.map((c, i) => (
                    <linearGradient
                        key={i}
                        id={`ofxConn${i}`}
                        gradientUnits="userSpaceOnUse"
                        x1={c.x1}
                        y1={c.y1}
                        x2={c.x2}
                        y2={c.y2}
                    >
                        <stop
                            offset="0%"
                            stopColor={TONES[STEPS[i].tone].line}
                        />
                        <stop
                            offset="100%"
                            stopColor={TONES[STEPS[i + 1].tone].line}
                        />
                    </linearGradient>
                ))}

                {/* Data-dot glow */}
                <filter
                    id="ofxDotGlow"
                    x="-100%"
                    y="-100%"
                    width="300%"
                    height="300%"
                >
                    <feGaussianBlur stdDeviation="2.5" result="b" />
                    <feMerge>
                        <feMergeNode in="b" />
                        <feMergeNode in="SourceGraphic" />
                    </feMerge>
                </filter>

                <filter
                    id="ofxBlur3"
                    x="-60%"
                    y="-60%"
                    width="220%"
                    height="220%"
                >
                    <feGaussianBlur stdDeviation="2.5" />
                </filter>
                <filter
                    id="ofxBlur6"
                    x="-60%"
                    y="-60%"
                    width="220%"
                    height="220%"
                >
                    <feGaussianBlur stdDeviation="6" />
                </filter>

                {/* Shared clip for gloss + shimmer, local slab coords */}
                <clipPath id="ofxFaceClip">
                    <path d={SLAB_TOP} />
                </clipPath>
            </defs>

            {/* ── Connectors — drawn beneath slabs ──────────────── */}
            {CONNS.map((c, i) => {
                const mx = (c.x1 + c.x2) / 2;
                const d = `M${c.x1},${c.y1} C${mx},${c.y1} ${mx},${c.y2} ${c.x2},${c.y2}`;
                return (
                    <g key={i}>
                        <motion.path
                            d={d}
                            stroke={`url(#ofxConn${i})`}
                            strokeWidth="1.6"
                            fill="none"
                            initial={{ pathLength: 0, opacity: 0 }}
                            animate={
                                inView ? { pathLength: 1, opacity: 0.55 } : {}
                            }
                            transition={{
                                duration: 0.7,
                                delay: 0.55 + i * 0.22,
                                ease: 'easeOut',
                            }}
                        />
                        <motion.polygon
                            points={`${c.x2 + 2},${c.y2} ${c.x2 - 6},${c.y2 - 4.5} ${c.x2 - 6},${c.y2 + 4.5}`}
                            fill={TONES[STEPS[i + 1].tone].line}
                            initial={{ opacity: 0 }}
                            animate={inView ? { opacity: 0.75 } : {}}
                            transition={{
                                duration: 0.4,
                                delay: 1.05 + i * 0.22,
                            }}
                        />
                        {!reduce && (
                            <DataDot
                                conn={c}
                                color={TONES[STEPS[i + 1].tone].line}
                                delay={1.8 + i * 0.5}
                                inView={inView}
                            />
                        )}
                    </g>
                );
            })}

            {/* ── Floating glass slabs ──────────────────────────── */}
            {STEPS.map((step, i) => {
                const { cx, cy, tone, num, label, sub, Icon } = step;
                const t = TONES[tone];

                return (
                    <motion.g
                        key={num}
                        initial={{ opacity: 0, y: 18 }}
                        animate={inView ? { opacity: 1, y: 0 } : {}}
                        transition={{
                            duration: 0.55,
                            delay: 0.15 + i * 0.16,
                            ease: [0.34, 1.56, 0.64, 1],
                        }}
                    >
                        {/* Labels — static above the slab */}
                        <text
                            x={cx}
                            y={cy - QH - 34}
                            textAnchor="middle"
                            style={{ fill: 'hsl(var(--il-text))' }}
                            fontSize={9}
                            fontWeight={800}
                            letterSpacing="0.6"
                        >
                            {label.toUpperCase()}
                        </text>
                        <text
                            x={cx}
                            y={cy - QH - 21}
                            textAnchor="middle"
                            style={{ fill: 'hsl(var(--il-text))' }}
                            fontSize={6.5}
                            opacity={0.7}
                        >
                            {sub}
                        </text>

                        {/* Ground shadow + tone under-glow — static */}
                        <ellipse
                            cx={cx}
                            cy={cy + 53}
                            rx={44}
                            ry={7}
                            fill="#000"
                            opacity={0.16}
                            filter="url(#ofxBlur3)"
                        />
                        <ellipse
                            cx={cx}
                            cy={cy + 51}
                            rx={36}
                            ry={6}
                            fill={t.line}
                            opacity={0.13}
                            filter="url(#ofxBlur6)"
                        />

                        {/* Slab + badge + icon — gentle float */}
                        <motion.g
                            animate={
                                inView && !reduce
                                    ? { y: [0, -4, 0] }
                                    : undefined
                            }
                            transition={{
                                duration: 3.8 + i * 0.4,
                                repeat: Infinity,
                                ease: 'easeInOut',
                                delay: 1 + i * 0.35,
                            }}
                        >
                            <g transform={`translate(${cx} ${cy})`}>
                                {/* Ambient glow */}
                                <ellipse
                                    cx={0}
                                    cy={2}
                                    rx={62}
                                    ry={34}
                                    fill={t.line}
                                    opacity={0.12}
                                    filter="url(#ofxBlur6)"
                                />

                                {/* Side extrusion */}
                                <path d={SLAB_SIDE} fill={t.side} />

                                {/* Top face */}
                                <path d={SLAB_TOP} fill={t.top} />
                                <path
                                    d={SLAB_TOP}
                                    stroke="#fff"
                                    strokeWidth="0.9"
                                    opacity={0.22}
                                />

                                {/* Gloss + shimmer, clipped to the face */}
                                <g clipPath="url(#ofxFaceClip)">
                                    <ellipse
                                        cx={-16}
                                        cy={-9}
                                        rx={26}
                                        ry={11}
                                        fill="#fff"
                                        opacity={0.16}
                                        filter="url(#ofxBlur3)"
                                    />
                                    {!reduce && (
                                        <motion.rect
                                            y={-QH - 4}
                                            width={16}
                                            height={QH * 2 + 8}
                                            fill="#fff"
                                            opacity={0.2}
                                            initial={{ x: -70 }}
                                            animate={
                                                inView ? { x: [-70, 70] } : {}
                                            }
                                            transition={{
                                                duration: 1.2,
                                                delay: 1.0 + i * 0.38,
                                                repeat: Infinity,
                                                repeatDelay: 4.8,
                                                ease: [0.4, 0, 0.6, 1],
                                            }}
                                        />
                                    )}
                                </g>

                                {/* Lit edges — key light top-left */}
                                <path
                                    d="M-8.9,-24.5 L-49.1,-4.5"
                                    stroke="#fff"
                                    strokeWidth="1.3"
                                    opacity={0.3}
                                    strokeLinecap="round"
                                />
                                <path
                                    d="M8.9,-24.5 L49.1,-4.5"
                                    stroke="#fff"
                                    strokeWidth="0.6"
                                    opacity={0.1}
                                    strokeLinecap="round"
                                />

                                {/* Icon — centred on the face */}
                                <g transform="translate(0 -1)">
                                    <Icon />
                                </g>

                                {/* Glossy number badge at top vertex */}
                                <circle
                                    cx={0}
                                    cy={-QH}
                                    r={10}
                                    fill={t.top}
                                    stroke="#fff"
                                    strokeWidth="1"
                                    strokeOpacity={0.45}
                                />
                                <text
                                    x={0}
                                    y={-QH + 3.6}
                                    textAnchor="middle"
                                    fill="#fff"
                                    fontSize={7}
                                    fontWeight={800}
                                >
                                    {num}
                                </text>
                            </g>
                        </motion.g>
                    </motion.g>
                );
            })}
        </svg>
    );
}
