"use client";

import { useEffect, useRef } from "react";

type Point = { x: number; y: number };

class FieldWave {
  private offset = Math.random() * 1000;
  private speed = 0.35 + Math.random() * 0.35;
  private amplitude = 12 + Math.random() * 14;
  private frequency = 0.008 + Math.random() * 0.008;

  constructor(private readonly y: number) {}

  update() {
    this.offset += this.speed;
  }

  draw(ctx: CanvasRenderingContext2D, width: number) {
    ctx.beginPath();
    ctx.moveTo(0, this.y);
    for (let x = 0; x <= width; x += 6) {
      ctx.lineTo(x, this.y + Math.sin((x + this.offset) * this.frequency) * this.amplitude);
    }
    ctx.strokeStyle = "rgba(187, 247, 208, 0.18)";
    ctx.lineWidth = 2;
    ctx.stroke();
  }
}

class SensorNode {
  readonly radius = 3.5;
  pulsePhase = Math.random() * Math.PI * 2;
  pulseSpeed = 0.025 + Math.random() * 0.02;
  connections: SensorNode[] = [];

  constructor(
    readonly x: number,
    readonly y: number,
  ) {}

  update() {
    this.pulsePhase += this.pulseSpeed;
  }

  drawConnections(ctx: CanvasRenderingContext2D) {
    for (const node of this.connections) {
      const gradient = ctx.createLinearGradient(this.x, this.y, node.x, node.y);
      gradient.addColorStop(0, "rgba(34, 197, 94, 0.18)");
      gradient.addColorStop(0.5, "rgba(56, 189, 248, 0.2)");
      gradient.addColorStop(1, "rgba(250, 204, 21, 0.12)");
      ctx.beginPath();
      ctx.moveTo(this.x, this.y);
      ctx.lineTo(node.x, node.y);
      ctx.strokeStyle = gradient;
      ctx.lineWidth = 1;
      ctx.stroke();
    }
  }

  draw(ctx: CanvasRenderingContext2D) {
    const pulse = Math.sin(this.pulsePhase) * 0.5 + 0.5;
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius + pulse * 7, 0, Math.PI * 2);
    ctx.strokeStyle = `rgba(187, 247, 208, ${0.18 + pulse * 0.28})`;
    ctx.lineWidth = 1.5;
    ctx.stroke();

    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
    ctx.fillStyle = `rgba(240, 253, 244, ${0.75 + pulse * 0.25})`;
    ctx.fill();
  }
}

class DataParticle {
  private life = 0;
  private readonly maxLife = 60 + Math.random() * 50;
  private readonly size = 1.6 + Math.random() * 2;
  private readonly color = ["34, 197, 94", "56, 189, 248", "250, 204, 21"][Math.floor(Math.random() * 3)];
  private readonly vx: number;
  private readonly vy: number;

  constructor(
    private x: number,
    private y: number,
  ) {
    const angle = -Math.PI / 2 + (Math.random() - 0.5) * 0.7;
    const speed = 1.1 + Math.random() * 1.9;
    this.vx = Math.cos(angle) * speed;
    this.vy = Math.sin(angle) * speed;
  }

  update() {
    this.x += this.vx;
    this.y += this.vy;
    this.life += 1;
  }

  draw(ctx: CanvasRenderingContext2D) {
    const alpha = 1 - this.life / this.maxLife;
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
    ctx.fillStyle = `rgba(${this.color}, ${alpha * 0.8})`;
    ctx.fill();
  }

  isDead() {
    return this.life >= this.maxLife;
  }
}

class Drone {
  private x: number;
  private y: number;
  private target: Point;
  private rotor = 0;
  private trail: Point[] = [];

  constructor(private bounds: { width: number; height: number }) {
    this.x = Math.random() * bounds.width;
    this.y = Math.random() * bounds.height * 0.55;
    this.target = this.pickTarget();
  }

  resize(bounds: { width: number; height: number }) {
    this.bounds = bounds;
    this.target = this.pickTarget();
  }

  private pickTarget(): Point {
    return {
      x: this.bounds.width * (0.12 + Math.random() * 0.76),
      y: this.bounds.height * (0.12 + Math.random() * 0.55),
    };
  }

  update() {
    const dx = this.target.x - this.x;
    const dy = this.target.y - this.y;
    const distance = Math.hypot(dx, dy);
    if (distance < 16) this.target = this.pickTarget();
    this.x += (dx / Math.max(distance, 1)) * 0.9;
    this.y += (dy / Math.max(distance, 1)) * 0.9;
    this.rotor += 0.35;
    this.trail.push({ x: this.x, y: this.y });
    if (this.trail.length > 28) this.trail.shift();
  }

  draw(ctx: CanvasRenderingContext2D) {
    ctx.beginPath();
    this.trail.forEach((point, index) => {
      if (index === 0) ctx.moveTo(point.x, point.y);
      else ctx.lineTo(point.x, point.y);
    });
    ctx.strokeStyle = "rgba(125, 211, 252, 0.32)";
    ctx.lineWidth = 1.5;
    ctx.stroke();

    ctx.save();
    ctx.translate(this.x, this.y);
    ctx.strokeStyle = "rgba(240, 253, 250, 0.85)";
    ctx.fillStyle = "rgba(14, 165, 233, 0.8)";
    ctx.lineWidth = 1.5;
    ctx.fillRect(-9, -4, 18, 8);
    for (const [rx, ry] of [[-12, -9], [12, -9], [-12, 9], [12, 9]]) {
      ctx.beginPath();
      ctx.ellipse(rx, ry, 7, 2 + Math.sin(this.rotor) * 0.8, 0, 0, Math.PI * 2);
      ctx.stroke();
    }
    ctx.beginPath();
    ctx.arc(0, 0, 26 + Math.sin(this.rotor * 0.5) * 4, 0, Math.PI * 2);
    ctx.strokeStyle = "rgba(125, 211, 252, 0.18)";
    ctx.stroke();
    ctx.restore();
  }
}

function connectSensors(nodes: SensorNode[]) {
  for (const node of nodes) {
    node.connections = nodes
      .filter((other) => other !== node)
      .map((other) => ({ other, distance: Math.hypot(other.x - node.x, other.y - node.y) }))
      .filter((item) => item.distance < 190)
      .sort((a, b) => a.distance - b.distance)
      .slice(0, 2)
      .map((item) => item.other);
  }
}

export function SmartFieldBackground() {
  const canvasRef = useRef<HTMLCanvasElement>(null);

  useEffect(() => {
    const canvas = canvasRef.current;
    const ctx = canvas?.getContext("2d");
    if (!canvas || !ctx) return;

    let waves: FieldWave[] = [];
    let sensors: SensorNode[] = [];
    let particles: DataParticle[] = [];
    let drones: Drone[] = [];
    let animationId = 0;

    const resizeCanvas = () => {
      const ratio = window.devicePixelRatio || 1;
      canvas.width = window.innerWidth * ratio;
      canvas.height = window.innerHeight * ratio;
      canvas.style.width = `${window.innerWidth}px`;
      canvas.style.height = `${window.innerHeight}px`;
      ctx.setTransform(ratio, 0, 0, ratio, 0, 0);

      const width = window.innerWidth;
      const height = window.innerHeight;
      waves = Array.from({ length: 8 }, (_, index) => new FieldWave((height / 9) * (index + 1)));
      sensors = [];
      const gridSize = width < 640 ? 170 : 150;
      for (let x = gridSize * 0.7; x < width; x += gridSize) {
        for (let y = gridSize * 0.7; y < height; y += gridSize) {
          sensors.push(new SensorNode(x + (Math.random() - 0.5) * 42, y + (Math.random() - 0.5) * 42));
        }
      }
      connectSensors(sensors);
      drones = drones.length ? drones : [new Drone({ width, height }), new Drone({ width, height })];
      drones.forEach((drone) => drone.resize({ width, height }));
      particles = [];
    };

    const drawGrid = () => {
      const width = window.innerWidth;
      const height = window.innerHeight;
      ctx.strokeStyle = "rgba(220, 252, 231, 0.08)";
      ctx.lineWidth = 1;
      for (let x = 0; x < width; x += 56) {
        ctx.beginPath();
        ctx.moveTo(x, 0);
        ctx.lineTo(x + height * 0.35, height);
        ctx.stroke();
      }
    };

    const animate = () => {
      ctx.fillStyle = "rgba(6, 78, 59, 0.1)";
      ctx.fillRect(0, 0, window.innerWidth, window.innerHeight);

      waves.forEach((wave) => {
        wave.update();
        wave.draw(ctx, window.innerWidth);
      });
      sensors.forEach((sensor) => sensor.drawConnections(ctx));
      sensors.forEach((sensor) => {
        sensor.update();
        sensor.draw(ctx);
      });

      if (Math.random() < 0.22 && sensors.length) {
        const sensor = sensors[Math.floor(Math.random() * sensors.length)];
        particles.push(new DataParticle(sensor.x, sensor.y));
      }
      particles.forEach((particle) => {
        particle.update();
        particle.draw(ctx);
      });
      particles = particles.filter((particle) => !particle.isDead());

      drones.forEach((drone) => {
        drone.update();
        drone.draw(ctx);
      });
      drawGrid();
      animationId = requestAnimationFrame(animate);
    };

    resizeCanvas();
    window.addEventListener("resize", resizeCanvas);
    animate();

    return () => {
      window.removeEventListener("resize", resizeCanvas);
      cancelAnimationFrame(animationId);
    };
  }, []);

  return (
    <>
      <div className="fixed inset-0 h-screen w-screen bg-[radial-gradient(circle_at_20%_20%,rgba(34,197,94,0.95),transparent_30%),radial-gradient(circle_at_80%_30%,rgba(59,130,246,0.72),transparent_28%),radial-gradient(circle_at_50%_82%,rgba(234,179,8,0.45),transparent_30%),linear-gradient(135deg,#064e3b,#15803d,#22c55e)] dark:bg-[linear-gradient(135deg,#020617,#111827,#134e4a)]" />
      <canvas ref={canvasRef} className="fixed inset-0 h-screen w-screen opacity-[0.72] mix-blend-screen" />
      <div className="fixed inset-0 h-screen w-screen bg-gradient-to-b from-emerald-950/35 via-transparent to-emerald-950/35 dark:from-gray-950/50 dark:via-transparent dark:to-gray-950/60" />
      <div className="fixed bottom-0 left-0 right-0 h-36 bg-gradient-to-t from-emerald-950/55 to-transparent dark:from-gray-950/75" />
    </>
  );
}
