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

const ease = [0.16, 1, 0.3, 1] as const;

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

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

const TONES: Record<
    Tone,
    { line: string; deep: string; top: string; body: string }
> = {
    platform: {
        line: TEAL_LINE,
        deep: '#0D3350',
        top: 'url(#dbxTopPlat)',
        body: 'url(#dbxBodyPlat)',
    },
    teal: {
        line: TEAL_LINE,
        deep: '#093A40',
        top: 'url(#dbxTopTeal)',
        body: 'url(#dbxBodyTeal)',
    },
    orange: {
        line: ORANGE_LINE,
        deep: '#732A04',
        top: 'url(#dbxTopOrange)',
        body: 'url(#dbxBodyOrange)',
    },
    navy: {
        line: NAVY_LINE,
        deep: '#16294A',
        top: 'url(#dbxTopNavy)',
        body: 'url(#dbxBodyNavy)',
    },
};

/* ── Scene layout ─────────────────────────────────────────── */
const CX = 200,
    CY = 118; // central platform DB
const C_BOT = 151; // connector start (below central DB)

const TENANTS: Array<{ cx: number; cy: number; tone: Tone; label: string }> = [
    { cx: 80, cy: 285, tone: 'teal', label: 'Kilimo' },
    { cx: 200, cy: 308, tone: 'orange', label: 'Maziwa' },
    { cx: 320, cy: 285, tone: 'navy', label: 'Savana' },
];

/* Cubic bezier keyframes for packet path following */
function connKF(x1: number, y1: number, x2: number, y2: number) {
    const p1 = { x: x1, y: y1 + 45 };
    const p2 = { x: x2, y: y2 - 55 };
    return [0, 1 / 3, 2 / 3, 1].map((t) => {
        const mt = 1 - t;
        return {
            x: parseFloat(
                (
                    mt ** 3 * x1 +
                    3 * mt ** 2 * t * p1.x +
                    3 * mt * t ** 2 * p2.x +
                    t ** 3 * x2
                ).toFixed(1),
            ),
            y: parseFloat(
                (
                    mt ** 3 * y1 +
                    3 * mt ** 2 * t * p1.y +
                    3 * mt * t ** 2 * p2.y +
                    t ** 3 * y2
                ).toFixed(1),
            ),
        };
    });
}

/* ── Glossy 3D database cylinder ──────────────────────────── */
function GlassDb({
    cx,
    cy,
    w,
    h,
    tone,
    label,
    delay,
    index,
    inView,
    reduce,
}: {
    cx: number;
    cy: number;
    w: number;
    h: number;
    tone: Tone;
    label: string;
    delay: number;
    index: number;
    inView: boolean;
    reduce: boolean;
}): JSX.Element {
    const t = TONES[tone];
    const rx = w / 2;
    const ry = rx * 0.32;
    const yTop = cy - h / 2 + ry; // top ellipse centre
    const yBot = cy + h / 2 - ry; // bottom arc centre
    const grooves = [0.48, 0.82].map((f) => yTop + (yBot - yTop) * f);

    return (
        <motion.g
            initial={{ opacity: 0, y: 16 }}
            animate={inView ? { opacity: 1, y: 0 } : {}}
            transition={{ duration: 0.55, delay, ease }}
        >
            {/* Ground shadow + tone glow — static */}
            <ellipse
                cx={cx}
                cy={cy + h / 2 + 7}
                rx={rx * 1.15}
                ry={6}
                fill="#000"
                opacity={0.16}
                filter="url(#dbxBlur3)"
            />
            <ellipse
                cx={cx}
                cy={cy + h / 2 + 5}
                rx={rx * 0.95}
                ry={5}
                fill={t.line}
                opacity={0.12}
                filter="url(#dbxBlur6)"
            />

            {/* Cylinder — gentle float */}
            <motion.g
                animate={inView && !reduce ? { y: [0, -3, 0] } : undefined}
                transition={{
                    duration: 4 + index * 0.4,
                    repeat: Infinity,
                    ease: 'easeInOut',
                    delay: 1 + index * 0.35,
                }}
            >
                {/* Ambient glow */}
                <ellipse
                    cx={cx}
                    cy={cy}
                    rx={rx + 16}
                    ry={h / 2 + 12}
                    fill={t.line}
                    opacity={0.1}
                    filter="url(#dbxBlur6)"
                />

                {/* Body with rounded bottom */}
                <path
                    d={`M${cx - rx},${yTop} V${yBot} A${rx},${ry} 0 0 0 ${cx + rx},${yBot} V${yTop} Z`}
                    fill={t.body}
                />

                {/* Disk grooves */}
                {grooves.map((gy, i) => (
                    <path
                        key={i}
                        d={`M${cx - rx},${gy} A${rx},${ry} 0 0 0 ${cx + rx},${gy}`}
                        stroke={t.deep}
                        strokeWidth="1"
                        opacity={0.35}
                    />
                ))}

                {/* Gloss streak down the lit side */}
                <rect
                    x={cx - rx * 0.62}
                    y={yTop + 2}
                    width={6.5}
                    height={yBot - yTop}
                    rx={3}
                    fill="#fff"
                    opacity={0.16}
                    filter="url(#dbxBlur3)"
                />

                {/* Top face */}
                <ellipse cx={cx} cy={yTop} rx={rx} ry={ry} fill={t.top} />
                <ellipse
                    cx={cx}
                    cy={yTop}
                    rx={rx}
                    ry={ry}
                    stroke="#fff"
                    strokeWidth="0.8"
                    opacity={0.25}
                />
                {/* Top-face sheen */}
                <ellipse
                    cx={cx - rx * 0.32}
                    cy={yTop - ry * 0.25}
                    rx={rx * 0.42}
                    ry={ry * 0.45}
                    fill="#fff"
                    opacity={0.3}
                    filter="url(#dbxBlur3)"
                />

                {/* Label on the body */}
                <text
                    x={cx}
                    y={cy + h * 0.14}
                    textAnchor="middle"
                    fill="#fff"
                    fontSize={8}
                    fontWeight={800}
                    letterSpacing="1"
                    opacity={0.92}
                >
                    {label.toUpperCase()}
                </text>
            </motion.g>
        </motion.g>
    );
}

/* ── Data packet travelling along a connector ─────────────── */
function Packet({
    x1,
    y1,
    x2,
    y2,
    color,
    delay,
    inView,
}: {
    x1: number;
    y1: number;
    x2: number;
    y2: number;
    color: string;
    delay: number;
    inView: boolean;
}): JSX.Element {
    const pts = connKF(x1, y1, x2, y2);
    const kfTimes = [0, 1 / 3, 2 / 3, 1];
    return (
        <motion.circle
            r={2.8}
            fill={color}
            filter="url(#dbxGlow)"
            initial={{ cx: x1, cy: 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.4,
                    delay,
                    repeat: Infinity,
                    repeatDelay: 3.4,
                    ease: 'easeInOut',
                    times: kfTimes,
                },
                cy: {
                    duration: 1.4,
                    delay,
                    repeat: Infinity,
                    repeatDelay: 3.4,
                    ease: 'easeInOut',
                    times: kfTimes,
                },
                opacity: {
                    duration: 1.4,
                    delay,
                    repeat: Infinity,
                    repeatDelay: 3.4,
                    times: [0, 0.15, 0.85, 1],
                },
            }}
        />
    );
}

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

export function DatabaseIsolationIllustration({ 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 400 400"
            className={className}
            fill="none"
            aria-hidden="true"
        >
            <defs>
                {/* Cylinder bodies — horizontal sheen: dark edge → highlight → dark edge */}
                <linearGradient id="dbxBodyPlat" x1="0" y1="0" x2="1" y2="0">
                    <stop offset="0%" stopColor="#0F4A64" />
                    <stop offset="25%" stopColor="#5FD3DE" />
                    <stop offset="55%" stopColor="#1F8CA0" />
                    <stop offset="100%" stopColor="#0D3350" />
                </linearGradient>
                <linearGradient id="dbxTopPlat" x1="0" y1="0" x2="0.7" y2="1">
                    <stop offset="0%" stopColor="#8FE9EF" />
                    <stop offset="55%" stopColor="#2CA0B2" />
                    <stop offset="100%" stopColor="#136079" />
                </linearGradient>

                <linearGradient id="dbxBodyTeal" x1="0" y1="0" x2="1" y2="0">
                    <stop offset="0%" stopColor="#0E5A60" />
                    <stop offset="25%" stopColor="#6FE0D8" />
                    <stop offset="55%" stopColor="#2AA49E" />
                    <stop offset="100%" stopColor="#093A40" />
                </linearGradient>
                <linearGradient id="dbxTopTeal" x1="0" y1="0" x2="0.7" y2="1">
                    <stop offset="0%" stopColor="#9FF0E8" />
                    <stop offset="55%" stopColor="#3BB5AE" />
                    <stop offset="100%" stopColor="#12706F" />
                </linearGradient>

                <linearGradient id="dbxBodyOrange" x1="0" y1="0" x2="1" y2="0">
                    <stop offset="0%" stopColor="#98400C" />
                    <stop offset="25%" stopColor="#FFB27A" />
                    <stop offset="55%" stopColor="#F0702A" />
                    <stop offset="100%" stopColor="#732A04" />
                </linearGradient>
                <linearGradient id="dbxTopOrange" x1="0" y1="0" x2="0.7" y2="1">
                    <stop offset="0%" stopColor="#FFD2A8" />
                    <stop offset="55%" stopColor="#F8853C" />
                    <stop offset="100%" stopColor="#C24709" />
                </linearGradient>

                <linearGradient id="dbxBodyNavy" x1="0" y1="0" x2="1" y2="0">
                    <stop offset="0%" stopColor="#24406B" />
                    <stop offset="25%" stopColor="#9FBEE8" />
                    <stop offset="55%" stopColor="#4A6DA5" />
                    <stop offset="100%" stopColor="#16294A" />
                </linearGradient>
                <linearGradient id="dbxTopNavy" x1="0" y1="0" x2="0.7" y2="1">
                    <stop offset="0%" stopColor="#AECBEF" />
                    <stop offset="55%" stopColor="#587BB3" />
                    <stop offset="100%" stopColor="#2A4470" />
                </linearGradient>

                {/* Connector gradients — platform teal → tenant tone */}
                {TENANTS.map((t, i) => (
                    <linearGradient
                        key={i}
                        id={`dbxConn${i}`}
                        gradientUnits="userSpaceOnUse"
                        x1={CX}
                        y1={C_BOT}
                        x2={t.cx}
                        y2={t.cy - 30}
                    >
                        <stop offset="0%" stopColor={TEAL_LINE} />
                        <stop offset="100%" stopColor={TONES[t.tone].line} />
                    </linearGradient>
                ))}

                <filter
                    id="dbxGlow"
                    x="-80%"
                    y="-80%"
                    width="260%"
                    height="260%"
                >
                    <feGaussianBlur stdDeviation="3" result="blur" />
                    <feMerge>
                        <feMergeNode in="blur" />
                        <feMergeNode in="SourceGraphic" />
                    </feMerge>
                </filter>
                <filter
                    id="dbxBlur3"
                    x="-60%"
                    y="-60%"
                    width="220%"
                    height="220%"
                >
                    <feGaussianBlur stdDeviation="2.5" />
                </filter>
                <filter
                    id="dbxBlur6"
                    x="-60%"
                    y="-60%"
                    width="220%"
                    height="220%"
                >
                    <feGaussianBlur stdDeviation="6" />
                </filter>
            </defs>

            {/* ── Captions ──────────────────────────────────────── */}
            <motion.text
                x={CX}
                y={66}
                textAnchor="middle"
                style={{ fill: 'hsl(var(--il-text))' }}
                fontSize={9}
                fontWeight={800}
                letterSpacing="1.4"
                initial={{ opacity: 0 }}
                animate={inView ? { opacity: 0.85 } : {}}
                transition={{ duration: 0.5, delay: 0.4 }}
            >
                CENTRAL REGISTRY
            </motion.text>
            <motion.text
                x={CX}
                y={378}
                textAnchor="middle"
                style={{ fill: 'hsl(var(--il-text))' }}
                fontSize={8.5}
                letterSpacing="0.5"
                initial={{ opacity: 0 }}
                animate={inView ? { opacity: 0.6 } : {}}
                transition={{ duration: 0.5, delay: 1.4 }}
            >
                Each tenant&apos;s data is fully isolated
            </motion.text>

            {/* ── Security pills ────────────────────────────────── */}
            <motion.g
                initial={{ opacity: 0, x: -8 }}
                animate={inView ? { opacity: 1, x: 0 } : {}}
                transition={{ duration: 0.5, delay: 1.5, ease }}
            >
                <rect
                    x={30}
                    y={52}
                    width={78}
                    height={22}
                    rx={11}
                    fill={TEAL_LINE}
                    fillOpacity={0.08}
                    stroke={TEAL_LINE}
                    strokeWidth="1"
                    strokeOpacity={0.5}
                />
                <text
                    x={69}
                    y={66.5}
                    textAnchor="middle"
                    style={{ fill: 'hsl(var(--il-text))' }}
                    fontSize={7}
                    fontWeight={700}
                    letterSpacing="0.6"
                    opacity={0.85}
                >
                    ZERO LEAKAGE
                </text>
            </motion.g>
            <motion.g
                initial={{ opacity: 0, x: 8 }}
                animate={inView ? { opacity: 1, x: 0 } : {}}
                transition={{ duration: 0.5, delay: 1.55, ease }}
            >
                <rect
                    x={306}
                    y={52}
                    width={64}
                    height={22}
                    rx={11}
                    fill={ORANGE_LINE}
                    fillOpacity={0.08}
                    stroke={ORANGE_LINE}
                    strokeWidth="1"
                    strokeOpacity={0.5}
                />
                <text
                    x={338}
                    y={66.5}
                    textAnchor="middle"
                    style={{ fill: 'hsl(var(--il-text))' }}
                    fontSize={7.5}
                    fontWeight={700}
                    letterSpacing="0.8"
                    opacity={0.85}
                >
                    AES-256
                </text>
            </motion.g>

            {/* ── Connectors — beneath the cylinders ────────────── */}
            {TENANTS.map((t, i) => {
                const x2 = t.cx,
                    y2 = t.cy - 30;
                const d = `M${CX},${C_BOT} C${CX},${C_BOT + 45} ${x2},${y2 - 55} ${x2},${y2}`;
                return (
                    <g key={t.label}>
                        <motion.path
                            d={d}
                            stroke={`url(#dbxConn${i})`}
                            strokeWidth="1.5"
                            fill="none"
                            initial={{ pathLength: 0, opacity: 0 }}
                            animate={
                                inView ? { pathLength: 1, opacity: 0.5 } : {}
                            }
                            transition={{
                                duration: 0.7,
                                delay: 0.5 + i * 0.15,
                                ease,
                            }}
                        />
                        <motion.polygon
                            points={`${x2},${y2 + 2} ${x2 - 4.5},${y2 - 6} ${x2 + 4.5},${y2 - 6}`}
                            fill={TONES[t.tone].line}
                            initial={{ opacity: 0 }}
                            animate={inView ? { opacity: 0.75 } : {}}
                            transition={{
                                duration: 0.4,
                                delay: 1.0 + i * 0.15,
                            }}
                        />
                        {!reduce && (
                            <Packet
                                x1={CX}
                                y1={C_BOT}
                                x2={x2}
                                y2={y2}
                                color={TONES[t.tone].line}
                                delay={1.6 + i * 1.0}
                                inView={inView}
                            />
                        )}
                    </g>
                );
            })}

            {/* ── Isolation dividers between tenants ────────────── */}
            {[140, 260].map((x, i) => (
                <motion.line
                    key={i}
                    x1={x}
                    y1={242}
                    x2={x}
                    y2={348}
                    style={{ stroke: 'hsl(var(--il-text))' }}
                    strokeWidth="1"
                    strokeDasharray="1 6"
                    strokeLinecap="round"
                    initial={{ pathLength: 0, opacity: 0 }}
                    animate={inView ? { pathLength: 1, opacity: 0.3 } : {}}
                    transition={{ duration: 0.5, delay: 0.9 + i * 0.08, ease }}
                />
            ))}

            {/* ── Central platform DB + shield chip ─────────────── */}
            <GlassDb
                cx={CX}
                cy={CY}
                w={92}
                h={58}
                tone="platform"
                label="Platform"
                delay={0.15}
                index={0}
                inView={inView}
                reduce={reduce}
            />
            <motion.g
                transform={`translate(${CX + 38} ${CY + 22})`}
                initial={{ opacity: 0, scale: 0 }}
                animate={inView ? { opacity: 1, scale: 1 } : {}}
                transition={{
                    duration: 0.45,
                    delay: 1.1,
                    ease: [0.34, 1.56, 0.64, 1],
                }}
                style={{ transformOrigin: '0 0' }}
            >
                {!reduce && (
                    <motion.circle
                        r={13}
                        fill="none"
                        stroke={ORANGE_LINE}
                        strokeWidth="1"
                        initial={{ opacity: 0 }}
                        animate={
                            inView
                                ? { opacity: [0, 0.5, 0], r: [13, 22, 13] }
                                : {}
                        }
                        transition={{
                            duration: 2.6,
                            repeat: Infinity,
                            delay: 2,
                            ease: 'easeInOut',
                        }}
                    />
                )}
                <circle
                    r={13}
                    fill="url(#dbxTopOrange)"
                    stroke="#fff"
                    strokeWidth="1"
                    strokeOpacity={0.45}
                />
                <g
                    stroke="#fff"
                    strokeWidth="1.6"
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    fill="none"
                >
                    <path d="M0,-7.5 L5.8,-5.2 L5.8,-0.5 C5.8,3.6 3,6.3 0,7.5 C-3,6.3 -5.8,3.6 -5.8,-0.5 L-5.8,-5.2 Z" />
                    <polyline points="-2.6,-0.5 -0.7,1.9 3.2,-2.4" />
                </g>
            </motion.g>

            {/* ── Tenant DBs + lock chips ───────────────────────── */}
            {TENANTS.map((t, i) => (
                <GlassDb
                    key={t.label}
                    cx={t.cx}
                    cy={t.cy}
                    w={68}
                    h={46}
                    tone={t.tone}
                    label={t.label}
                    delay={0.55 + i * 0.15}
                    index={i + 1}
                    inView={inView}
                    reduce={reduce}
                />
            ))}
            {TENANTS.map((t, i) => (
                <motion.g
                    key={t.label}
                    transform={`translate(${t.cx + 24} ${t.cy + 18})`}
                    initial={{ opacity: 0, scale: 0 }}
                    animate={inView ? { opacity: 1, scale: 1 } : {}}
                    transition={{
                        duration: 0.4,
                        delay: 1.15 + i * 0.12,
                        ease: [0.34, 1.56, 0.64, 1],
                    }}
                    style={{ transformOrigin: '0 0' }}
                >
                    <circle
                        r={8.5}
                        fill={TONES[t.tone].top}
                        stroke="#fff"
                        strokeWidth="0.9"
                        strokeOpacity={0.4}
                    />
                    <path
                        d="M-2,-1.2 L-2,-3 Q0,-5 2,-3 L2,-1.2"
                        stroke="#fff"
                        strokeWidth="1.4"
                        fill="none"
                        strokeLinecap="round"
                    />
                    <rect
                        x={-3.5}
                        y={-1.2}
                        width={7}
                        height={5.4}
                        rx={1.2}
                        fill="#fff"
                    />
                    <circle cx={0} cy={1.4} r={1} fill={TONES[t.tone].deep} />
                </motion.g>
            ))}
        </svg>
    );
}
