import { ChatBgVariants } from './types';
import { rainFall } from './animRain.css';

// anim-rain — "Digital Rain" — a premium take on the Matrix code-rain motif.
//
// Concept: sparse vertical columns of falling glyph-streaks. Each streak is a
// soft vertical gradient that fades from a brighter LEADING glyph (the drop's
// head) up into a dim trailing tail, punctuated by a scatter of faint monospace
// glyph marks so it reads as CODE rather than plain stripes. It floats over a
// near-black base carrying a subtle green phosphor cast and a gentle vignette.
// Columns are deliberately sparse (only a handful across the 260px-wide tile)
// so the reading area breathes and text always wins the contrast fight.
//
// SEAMLESS TILING + PAN — the streak SVG tile is 260×200. Its content is
// authored to wrap top↔bottom: each streak's gradient and glyphs are placed so
// the tile is vertically continuous, and the animation (see animRain.css.ts)
// pans this first layer down by EXACTLY one tile height (200px) per cycle, so
// the "fall" loops with no seam. The base / vignette layers are 100% 100% and
// stay fixed (the keyframe holds them at '0 0').
//
// ANIMATION-STRIP SAFETY — getChatBg removes `animation` for reduced-motion /
// pause-animations users, so the non-animation properties below already read as
// a finished, gorgeous STATIC rain: a frozen frame of streaks over the base.
//
// CSP / Tauri-safe: inline SVG via encodeURIComponent (NOT base64). oklch used
// throughout; alphas kept low so both themes stay WCAG-AA-friendly for text.

// One vertical streak-column, colour-parameterised. Placed at x within a
// 260-wide tile. `head` is the bright leading-glyph colour, `tail` the dim
// trailing colour, `glyph` the colour of the riding monospace glyph ticks.
const streak = (
  x: number,
  headY: number, // y of the leading glyph (drop head)
  len: number, // trailing tail length upward
  head: string,
  tail: string,
  glyph: string,
): string => {
  const topY = headY - len;
  const id = `g${x}_${headY}`; // unique even when two columns share an x
  // Vertical fade: transparent at the tail top → tail colour → bright head.
  const grad = `
<linearGradient id='${id}' x1='0' y1='${topY}' x2='0' y2='${headY}' gradientUnits='userSpaceOnUse'>
<stop offset='0' stop-color='${tail}' stop-opacity='0'/>
<stop offset='0.55' stop-color='${tail}'/>
<stop offset='1' stop-color='${head}'/>
</linearGradient>`;
  // The streak body is a soft, slightly-blurred vertical bar.
  const bar = `<rect x='${x - 3}' y='${topY}' width='6' height='${len}' rx='3' fill='url(#${id})'/>`;
  // A few monospace glyph ticks riding the column (short horizontal dashes).
  const ticks = [0.22, 0.45, 0.68, 0.86]
    .map((f, i) => {
      const gy = Math.round(topY + len * f);
      const gw = i % 2 === 0 ? 5 : 3;
      const op = i === 3 ? '0.9' : '0.5';
      return `<rect x='${x - gw / 2}' y='${gy}' width='${gw}' height='1.4' rx='0.7' fill='${glyph}' fill-opacity='${op}'/>`;
    })
    .join('');
  // The leading glyph: a brighter small square cap at the head.
  const cap = `<rect x='${x - 2.5}' y='${headY - 3}' width='5' height='5' rx='1' fill='${head}'/>`;
  return grad + bar + ticks + cap;
};

// Full 260×200 tile. Columns are wrapped vertically: a column whose head sits
// low in the tile has its tail running off the top, and a companion column
// re-enters that space, so panning by one tile height reads as continuous fall.
const tile = (head: string, tail: string, glyph: string): string => {
  const cols = [
    streak(24, 150, 140, head, tail, glyph),
    streak(78, 60, 120, head, tail, glyph),
    streak(122, 196, 160, head, tail, glyph), // head near bottom → tail wraps up
    streak(122, 40, 160, head, tail, glyph), // partner near top completes the wrap
    streak(178, 110, 100, head, tail, glyph),
    streak(232, 176, 130, head, tail, glyph),
  ].join('');
  const svg = `<svg xmlns='http://www.w3.org/2000/svg' width='260' height='200' viewBox='0 0 260 200'><defs></defs>${cols}</svg>`;
  return `url("data:image/svg+xml,${encodeURIComponent(svg)}")`;
};

export const animRain: ChatBgVariants = {
  // Dark: phosphor-green streaks on deep near-black with a faint green cast.
  dark: {
    backgroundColor: 'oklch(0.16 0.02 150)',
    backgroundImage: [
      // 1) the falling streak columns (this is the panned layer)
      tile(
        'oklch(0.75 0.14 150 / 0.5)', // head — bright phosphor glyph
        'oklch(0.68 0.12 150 / 0.28)', // tail — dim phosphor
        'oklch(0.82 0.1 150 / 0.5)', // glyph ticks — brightest
      ),
      // 2) soft top-down phosphor haze so the rain has atmosphere
      'linear-gradient(180deg, oklch(0.24 0.04 150 / 0.55) 0%, transparent 40%)',
      // 3) subtle green cast pooling toward the bottom
      'radial-gradient(120% 90% at 50% 100%, oklch(0.28 0.05 150 / 0.45) 0%, transparent 60%)',
      // 4) vignette — quiet the corners so the reading column stays clean
      'radial-gradient(140% 140% at 50% 45%, transparent 60%, oklch(0.1 0.02 150 / 0.6) 100%)',
    ].join(','),
    backgroundSize: ['260px 200px', '100% 100%', '100% 100%', '100% 100%'].join(','),
    backgroundPosition: ['0 0', '0 0', '0 0', '0 0'].join(','),
    animation: `${rainFall} 12s linear infinite`,
  },

  // Light: soft teal-grey streaks on a pale cool base — elegant, never neon.
  light: {
    backgroundColor: 'oklch(0.97 0.008 165)',
    backgroundImage: [
      tile(
        'oklch(0.55 0.07 165 / 0.4)', // head — soft teal-grey drop
        'oklch(0.62 0.05 165 / 0.22)', // tail — faint teal-grey
        'oklch(0.5 0.06 165 / 0.42)', // glyph ticks
      ),
      // gentle cool wash from the top
      'linear-gradient(180deg, oklch(0.94 0.015 175 / 0.6) 0%, transparent 42%)',
      // faint teal pooling at the bottom edge
      'radial-gradient(120% 90% at 50% 100%, oklch(0.9 0.02 170 / 0.5) 0%, transparent 60%)',
      // soft vignette in cool grey
      'radial-gradient(140% 140% at 50% 45%, transparent 62%, oklch(0.88 0.02 165 / 0.5) 100%)',
    ].join(','),
    backgroundSize: ['260px 200px', '100% 100%', '100% 100%', '100% 100%'].join(','),
    backgroundPosition: ['0 0', '0 0', '0 0', '0 0'].join(','),
    animation: `${rainFall} 12s linear infinite`,
  },
};
