'use client';

import * as React from 'react';
import { Modal } from '@/components/ui/Modal';
import { Button } from '@/components/ui/Button';
import { Slider } from '@/components/ui/Slider';
import { cn } from '@/lib/utils/cn';
import type {
  DelayParameters,
  ReverbParameters,
  ChorusParameters,
  FlangerParameters,
  PhaserParameters,
} from '@/lib/audio/effects/time-based';

export type TimeBasedType = 'delay' | 'reverb' | 'chorus' | 'flanger' | 'phaser';

export type TimeBasedParameters =
  | (DelayParameters & { type: 'delay' })
  | (ReverbParameters & { type: 'reverb' })
  | (ChorusParameters & { type: 'chorus' })
  | (FlangerParameters & { type: 'flanger' })
  | (PhaserParameters & { type: 'phaser' });

export interface EffectPreset {
  name: string;
  parameters: Partial<DelayParameters | ReverbParameters | ChorusParameters | FlangerParameters | PhaserParameters>;
}

export interface TimeBasedParameterDialogProps {
  open: boolean;
  onClose: () => void;
  effectType: TimeBasedType;
  onApply: (params: TimeBasedParameters) => void;
}

const EFFECT_LABELS: Record<TimeBasedType, string> = {
  delay: 'Delay/Echo',
  reverb: 'Reverb',
  chorus: 'Chorus',
  flanger: 'Flanger',
  phaser: 'Phaser',
};

const EFFECT_DESCRIPTIONS: Record<TimeBasedType, string> = {
  delay: 'Creates echo effects by repeating the audio signal',
  reverb: 'Simulates acoustic space and ambience',
  chorus: 'Thickens sound by adding modulated copies',
  flanger: 'Creates sweeping comb-filter effect',
  phaser: 'Creates a phase-shifting swoosh effect',
};

const PRESETS: Record<TimeBasedType, EffectPreset[]> = {
  delay: [
    { name: 'Short Slap', parameters: { time: 80, feedback: 0.2, mix: 0.3 } },
    { name: 'Medium Echo', parameters: { time: 250, feedback: 0.4, mix: 0.4 } },
    { name: 'Long Echo', parameters: { time: 500, feedback: 0.5, mix: 0.5 } },
    { name: 'Ping Pong', parameters: { time: 375, feedback: 0.6, mix: 0.4 } },
  ],
  reverb: [
    { name: 'Small Room', parameters: { roomSize: 0.3, damping: 0.5, mix: 0.2 } },
    { name: 'Medium Hall', parameters: { roomSize: 0.6, damping: 0.3, mix: 0.3 } },
    { name: 'Large Hall', parameters: { roomSize: 0.8, damping: 0.2, mix: 0.4 } },
    { name: 'Cathedral', parameters: { roomSize: 1.0, damping: 0.1, mix: 0.5 } },
  ],
  chorus: [
    { name: 'Subtle', parameters: { rate: 0.5, depth: 0.2, delay: 20, mix: 0.3 } },
    { name: 'Classic', parameters: { rate: 1.0, depth: 0.5, delay: 25, mix: 0.5 } },
    { name: 'Deep', parameters: { rate: 1.5, depth: 0.7, delay: 30, mix: 0.6 } },
    { name: 'Lush', parameters: { rate: 0.8, depth: 0.6, delay: 35, mix: 0.7 } },
  ],
  flanger: [
    { name: 'Subtle', parameters: { rate: 0.3, depth: 0.3, feedback: 0.2, delay: 2, mix: 0.4 } },
    { name: 'Classic', parameters: { rate: 0.5, depth: 0.5, feedback: 0.4, delay: 3, mix: 0.5 } },
    { name: 'Jet', parameters: { rate: 0.2, depth: 0.7, feedback: 0.6, delay: 1.5, mix: 0.6 } },
    { name: 'Extreme', parameters: { rate: 1.0, depth: 0.8, feedback: 0.7, delay: 2.5, mix: 0.7 } },
  ],
  phaser: [
    { name: 'Gentle', parameters: { rate: 0.4, depth: 0.3, feedback: 0.2, stages: 4, mix: 0.4 } },
    { name: 'Classic', parameters: { rate: 0.6, depth: 0.5, feedback: 0.4, stages: 6, mix: 0.5 } },
    { name: 'Deep', parameters: { rate: 0.3, depth: 0.7, feedback: 0.5, stages: 8, mix: 0.6 } },
    { name: 'Vintage', parameters: { rate: 0.5, depth: 0.6, feedback: 0.6, stages: 4, mix: 0.7 } },
  ],
};

export function TimeBasedParameterDialog({
  open,
  onClose,
  effectType,
  onApply,
}: TimeBasedParameterDialogProps) {
  const [parameters, setParameters] = React.useState<TimeBasedParameters>(() => {
    if (effectType === 'delay') {
      return { type: 'delay', time: 250, feedback: 0.4, mix: 0.4 };
    } else if (effectType === 'reverb') {
      return { type: 'reverb', roomSize: 0.6, damping: 0.3, mix: 0.3 };
    } else if (effectType === 'chorus') {
      return { type: 'chorus', rate: 1.0, depth: 0.5, delay: 25, mix: 0.5 };
    } else if (effectType === 'flanger') {
      return { type: 'flanger', rate: 0.5, depth: 0.5, feedback: 0.4, delay: 3, mix: 0.5 };
    } else {
      return { type: 'phaser', rate: 0.6, depth: 0.5, feedback: 0.4, stages: 6, mix: 0.5 };
    }
  });

  const canvasRef = React.useRef<HTMLCanvasElement>(null);

  // Get appropriate presets for this effect type
  const presets = PRESETS[effectType] || [];

  // Update parameters when effect type changes
  React.useEffect(() => {
    if (effectType === 'delay') {
      setParameters({ type: 'delay', time: 250, feedback: 0.4, mix: 0.4 });
    } else if (effectType === 'reverb') {
      setParameters({ type: 'reverb', roomSize: 0.6, damping: 0.3, mix: 0.3 });
    } else if (effectType === 'chorus') {
      setParameters({ type: 'chorus', rate: 1.0, depth: 0.5, delay: 25, mix: 0.5 });
    } else if (effectType === 'flanger') {
      setParameters({ type: 'flanger', rate: 0.5, depth: 0.5, feedback: 0.4, delay: 3, mix: 0.5 });
    } else {
      setParameters({ type: 'phaser', rate: 0.6, depth: 0.5, feedback: 0.4, stages: 6, mix: 0.5 });
    }
  }, [effectType]);

  // Draw visualization
  React.useEffect(() => {
    if (!open || !canvasRef.current) return;

    const canvas = canvasRef.current;
    const ctx = canvas.getContext('2d');
    if (!ctx) return;

    // Get actual dimensions
    const rect = canvas.getBoundingClientRect();
    const dpr = window.devicePixelRatio || 1;

    // Ensure canvas has dimensions before drawing
    if (rect.width === 0 || rect.height === 0) return;

    // Set actual size in memory
    canvas.width = rect.width * dpr;
    canvas.height = rect.height * dpr;

    // Normalize coordinate system
    ctx.scale(dpr, dpr);

    // Clear canvas
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    const width = rect.width;
    const height = rect.height;

    // Clear with background
    ctx.fillStyle = getComputedStyle(canvas).getPropertyValue('background-color') || '#1a1a1a';
    ctx.fillRect(0, 0, width, height);

    if (effectType === 'delay') {
      // Draw delay echoes
      const delayParams = parameters as DelayParameters & { type: 'delay' };
      const maxTime = 2000; // ms
      const echoCount = 5;

      ctx.strokeStyle = 'rgba(128, 128, 128, 0.3)';
      ctx.lineWidth = 1;
      ctx.setLineDash([2, 2]);
      for (let i = 0; i <= 4; i++) {
        const x = (i / 4) * width;
        ctx.beginPath();
        ctx.moveTo(x, 0);
        ctx.lineTo(x, height);
        ctx.stroke();
      }
      ctx.setLineDash([]);

      let gain = 1.0;
      for (let i = 0; i < echoCount; i++) {
        const x = (i * delayParams.time / maxTime) * width;
        const barHeight = height * gain * 0.8;
        const y = (height - barHeight) / 2;

        ctx.fillStyle = `rgba(59, 130, 246, ${gain})`;
        ctx.fillRect(x - 3, y, 6, barHeight);

        gain *= delayParams.feedback;
        if (gain < 0.01) break;
      }
    } else if (effectType === 'reverb') {
      // Draw reverb decay
      const reverbParams = parameters as ReverbParameters & { type: 'reverb' };
      const decayTime = reverbParams.roomSize * 3000; // ms

      ctx.strokeStyle = '#3b82f6';
      ctx.lineWidth = 2;
      ctx.beginPath();

      for (let x = 0; x < width; x++) {
        const time = (x / width) * 3000;
        const decay = Math.exp(-time / (decayTime * (1 - reverbParams.damping * 0.5)));
        const y = height / 2 + (height / 2 - 20) * (1 - decay);

        if (x === 0) ctx.moveTo(x, y);
        else ctx.lineTo(x, y);
      }
      ctx.stroke();

      // Draw reference line
      ctx.strokeStyle = 'rgba(128, 128, 128, 0.3)';
      ctx.lineWidth = 1;
      ctx.setLineDash([5, 5]);
      ctx.beginPath();
      ctx.moveTo(0, height / 2);
      ctx.lineTo(width, height / 2);
      ctx.stroke();
      ctx.setLineDash([]);
    } else {
      // Draw LFO waveform for chorus, flanger, phaser
      let rate = 1.0;
      let depth = 0.5;

      if (effectType === 'chorus') {
        const chorusParams = parameters as ChorusParameters & { type: 'chorus' };
        rate = chorusParams.rate;
        depth = chorusParams.depth;
      } else if (effectType === 'flanger') {
        const flangerParams = parameters as FlangerParameters & { type: 'flanger' };
        rate = flangerParams.rate;
        depth = flangerParams.depth;
      } else if (effectType === 'phaser') {
        const phaserParams = parameters as PhaserParameters & { type: 'phaser' };
        rate = phaserParams.rate;
        depth = phaserParams.depth;
      }

      ctx.strokeStyle = '#3b82f6';
      ctx.lineWidth = 2;
      ctx.beginPath();

      const cycles = rate * 2; // Show 2 seconds worth
      for (let x = 0; x < width; x++) {
        const phase = (x / width) * cycles * 2 * Math.PI;
        const lfo = Math.sin(phase);
        const y = height / 2 - (lfo * depth * height * 0.4);

        if (x === 0) ctx.moveTo(x, y);
        else ctx.lineTo(x, y);
      }
      ctx.stroke();

      // Draw center line
      ctx.strokeStyle = 'rgba(128, 128, 128, 0.3)';
      ctx.lineWidth = 1;
      ctx.setLineDash([5, 5]);
      ctx.beginPath();
      ctx.moveTo(0, height / 2);
      ctx.lineTo(width, height / 2);
      ctx.stroke();
      ctx.setLineDash([]);
    }

  }, [parameters, effectType, open]);

  const handleApply = () => {
    onApply(parameters);
    onClose();
  };

  const handlePresetClick = (preset: EffectPreset) => {
    setParameters((prev) => ({
      ...prev,
      ...preset.parameters,
    }));
  };

  return (
    <Modal
      open={open}
      onClose={onClose}
      title={EFFECT_LABELS[effectType] || 'Time-Based Effect'}
      description={EFFECT_DESCRIPTIONS[effectType]}
      size="lg"
      footer={
        <>
          <Button variant="outline" onClick={onClose}>
            Cancel
          </Button>
          <Button onClick={handleApply}>
            Apply Effect
          </Button>
        </>
      }
    >
      <div className="space-y-4">
        {/* Visualization */}
        <div className="space-y-2">
          <label className="text-sm font-medium text-foreground">
            {effectType === 'delay' && 'Echo Pattern'}
            {effectType === 'reverb' && 'Reverb Decay'}
            {(effectType === 'chorus' || effectType === 'flanger' || effectType === 'phaser') && 'Modulation (LFO)'}
          </label>
          <canvas
            ref={canvasRef}
            className="w-full h-32 border border-border rounded bg-background"
          />
        </div>

        {/* Presets */}
        {presets.length > 0 && (
          <div className="space-y-2">
            <label className="text-sm font-medium text-foreground">
              Presets
            </label>
            <div className="grid grid-cols-2 gap-2">
              {presets.map((preset) => (
                <Button
                  key={preset.name}
                  variant="outline"
                  size="sm"
                  onClick={() => handlePresetClick(preset)}
                  className="justify-start"
                >
                  {preset.name}
                </Button>
              ))}
            </div>
          </div>
        )}

        {/* Effect-specific parameters */}
        {effectType === 'delay' && (
          <>
            {/* Delay Time */}
            <div className="space-y-2">
              <label className="text-sm font-medium text-foreground flex justify-between">
                <span>Delay Time</span>
                <span className="text-muted-foreground font-mono">
                  {((parameters as DelayParameters).time ?? 250).toFixed(0)} ms
                </span>
              </label>
              <Slider
                value={[((parameters as DelayParameters).time ?? 250)]}
                onValueChange={([value]) =>
                  setParameters((prev) => ({ ...prev, time: value }))
                }
                min={10}
                max={2000}
                step={10}
                className="w-full"
              />
            </div>

            {/* Feedback */}
            <div className="space-y-2">
              <label className="text-sm font-medium text-foreground flex justify-between">
                <span>Feedback</span>
                <span className="text-muted-foreground font-mono">
                  {(((parameters as DelayParameters).feedback ?? 0.4) * 100).toFixed(0)}%
                </span>
              </label>
              <Slider
                value={[((parameters as DelayParameters).feedback ?? 0.4)]}
                onValueChange={([value]) =>
                  setParameters((prev) => ({ ...prev, feedback: value }))
                }
                min={0}
                max={0.95}
                step={0.01}
                className="w-full"
              />
            </div>
          </>
        )}

        {effectType === 'reverb' && (
          <>
            {/* Room Size */}
            <div className="space-y-2">
              <label className="text-sm font-medium text-foreground flex justify-between">
                <span>Room Size</span>
                <span className="text-muted-foreground font-mono">
                  {(((parameters as ReverbParameters).roomSize ?? 0.6) * 100).toFixed(0)}%
                </span>
              </label>
              <Slider
                value={[((parameters as ReverbParameters).roomSize ?? 0.6)]}
                onValueChange={([value]) =>
                  setParameters((prev) => ({ ...prev, roomSize: value }))
                }
                min={0.1}
                max={1}
                step={0.01}
                className="w-full"
              />
            </div>

            {/* Damping */}
            <div className="space-y-2">
              <label className="text-sm font-medium text-foreground flex justify-between">
                <span>Damping</span>
                <span className="text-muted-foreground font-mono">
                  {(((parameters as ReverbParameters).damping ?? 0.3) * 100).toFixed(0)}%
                </span>
              </label>
              <Slider
                value={[((parameters as ReverbParameters).damping ?? 0.3)]}
                onValueChange={([value]) =>
                  setParameters((prev) => ({ ...prev, damping: value }))
                }
                min={0}
                max={1}
                step={0.01}
                className="w-full"
              />
            </div>
          </>
        )}

        {effectType === 'chorus' && (
          <>
            {/* Rate */}
            <div className="space-y-2">
              <label className="text-sm font-medium text-foreground flex justify-between">
                <span>Rate</span>
                <span className="text-muted-foreground font-mono">
                  {((parameters as ChorusParameters).rate ?? 1.0).toFixed(2)} Hz
                </span>
              </label>
              <Slider
                value={[((parameters as ChorusParameters).rate ?? 1.0)]}
                onValueChange={([value]) =>
                  setParameters((prev) => ({ ...prev, rate: value }))
                }
                min={0.1}
                max={5}
                step={0.1}
                className="w-full"
              />
            </div>

            {/* Depth */}
            <div className="space-y-2">
              <label className="text-sm font-medium text-foreground flex justify-between">
                <span>Depth</span>
                <span className="text-muted-foreground font-mono">
                  {(((parameters as ChorusParameters).depth ?? 0.5) * 100).toFixed(0)}%
                </span>
              </label>
              <Slider
                value={[((parameters as ChorusParameters).depth ?? 0.5)]}
                onValueChange={([value]) =>
                  setParameters((prev) => ({ ...prev, depth: value }))
                }
                min={0}
                max={1}
                step={0.01}
                className="w-full"
              />
            </div>

            {/* Base Delay */}
            <div className="space-y-2">
              <label className="text-sm font-medium text-foreground flex justify-between">
                <span>Base Delay</span>
                <span className="text-muted-foreground font-mono">
                  {((parameters as ChorusParameters).delay ?? 25).toFixed(1)} ms
                </span>
              </label>
              <Slider
                value={[((parameters as ChorusParameters).delay ?? 25)]}
                onValueChange={([value]) =>
                  setParameters((prev) => ({ ...prev, delay: value }))
                }
                min={5}
                max={50}
                step={0.5}
                className="w-full"
              />
            </div>
          </>
        )}

        {effectType === 'flanger' && (
          <>
            {/* Rate */}
            <div className="space-y-2">
              <label className="text-sm font-medium text-foreground flex justify-between">
                <span>Rate</span>
                <span className="text-muted-foreground font-mono">
                  {((parameters as FlangerParameters).rate ?? 0.5).toFixed(2)} Hz
                </span>
              </label>
              <Slider
                value={[((parameters as FlangerParameters).rate ?? 0.5)]}
                onValueChange={([value]) =>
                  setParameters((prev) => ({ ...prev, rate: value }))
                }
                min={0.1}
                max={5}
                step={0.1}
                className="w-full"
              />
            </div>

            {/* Depth */}
            <div className="space-y-2">
              <label className="text-sm font-medium text-foreground flex justify-between">
                <span>Depth</span>
                <span className="text-muted-foreground font-mono">
                  {(((parameters as FlangerParameters).depth ?? 0.5) * 100).toFixed(0)}%
                </span>
              </label>
              <Slider
                value={[((parameters as FlangerParameters).depth ?? 0.5)]}
                onValueChange={([value]) =>
                  setParameters((prev) => ({ ...prev, depth: value }))
                }
                min={0}
                max={1}
                step={0.01}
                className="w-full"
              />
            </div>

            {/* Feedback */}
            <div className="space-y-2">
              <label className="text-sm font-medium text-foreground flex justify-between">
                <span>Feedback</span>
                <span className="text-muted-foreground font-mono">
                  {(((parameters as FlangerParameters).feedback ?? 0.4) * 100).toFixed(0)}%
                </span>
              </label>
              <Slider
                value={[((parameters as FlangerParameters).feedback ?? 0.4)]}
                onValueChange={([value]) =>
                  setParameters((prev) => ({ ...prev, feedback: value }))
                }
                min={0}
                max={0.95}
                step={0.01}
                className="w-full"
              />
            </div>

            {/* Base Delay */}
            <div className="space-y-2">
              <label className="text-sm font-medium text-foreground flex justify-between">
                <span>Base Delay</span>
                <span className="text-muted-foreground font-mono">
                  {((parameters as FlangerParameters).delay ?? 3).toFixed(1)} ms
                </span>
              </label>
              <Slider
                value={[((parameters as FlangerParameters).delay ?? 3)]}
                onValueChange={([value]) =>
                  setParameters((prev) => ({ ...prev, delay: value }))
                }
                min={0.5}
                max={10}
                step={0.1}
                className="w-full"
              />
            </div>
          </>
        )}

        {effectType === 'phaser' && (
          <>
            {/* Rate */}
            <div className="space-y-2">
              <label className="text-sm font-medium text-foreground flex justify-between">
                <span>Rate</span>
                <span className="text-muted-foreground font-mono">
                  {((parameters as PhaserParameters).rate ?? 0.6).toFixed(2)} Hz
                </span>
              </label>
              <Slider
                value={[((parameters as PhaserParameters).rate ?? 0.6)]}
                onValueChange={([value]) =>
                  setParameters((prev) => ({ ...prev, rate: value }))
                }
                min={0.1}
                max={5}
                step={0.1}
                className="w-full"
              />
            </div>

            {/* Depth */}
            <div className="space-y-2">
              <label className="text-sm font-medium text-foreground flex justify-between">
                <span>Depth</span>
                <span className="text-muted-foreground font-mono">
                  {(((parameters as PhaserParameters).depth ?? 0.5) * 100).toFixed(0)}%
                </span>
              </label>
              <Slider
                value={[((parameters as PhaserParameters).depth ?? 0.5)]}
                onValueChange={([value]) =>
                  setParameters((prev) => ({ ...prev, depth: value }))
                }
                min={0}
                max={1}
                step={0.01}
                className="w-full"
              />
            </div>

            {/* Feedback */}
            <div className="space-y-2">
              <label className="text-sm font-medium text-foreground flex justify-between">
                <span>Feedback</span>
                <span className="text-muted-foreground font-mono">
                  {(((parameters as PhaserParameters).feedback ?? 0.4) * 100).toFixed(0)}%
                </span>
              </label>
              <Slider
                value={[((parameters as PhaserParameters).feedback ?? 0.4)]}
                onValueChange={([value]) =>
                  setParameters((prev) => ({ ...prev, feedback: value }))
                }
                min={0}
                max={0.95}
                step={0.01}
                className="w-full"
              />
            </div>

            {/* Stages */}
            <div className="space-y-2">
              <label className="text-sm font-medium text-foreground flex justify-between">
                <span>Stages</span>
                <span className="text-muted-foreground font-mono">
                  {((parameters as PhaserParameters).stages ?? 6).toFixed(0)}
                </span>
              </label>
              <Slider
                value={[((parameters as PhaserParameters).stages ?? 6)]}
                onValueChange={([value]) =>
                  setParameters((prev) => ({ ...prev, stages: Math.floor(value) }))
                }
                min={2}
                max={12}
                step={1}
                className="w-full"
              />
            </div>
          </>
        )}

        {/* Mix (common to all) */}
        <div className="space-y-2">
          <label className="text-sm font-medium text-foreground flex justify-between">
            <span>Mix (Dry/Wet)</span>
            <span className="text-muted-foreground font-mono">
              {((parameters.mix ?? 0.5) * 100).toFixed(0)}%
            </span>
          </label>
          <Slider
            value={[(parameters.mix ?? 0.5)]}
            onValueChange={([value]) =>
              setParameters((prev) => ({ ...prev, mix: value }))
            }
            min={0}
            max={1}
            step={0.01}
            className="w-full"
          />
          <div className="flex justify-between text-xs text-muted-foreground">
            <span>0% (Dry)</span>
            <span>100% (Wet)</span>
          </div>
        </div>
      </div>
    </Modal>
  );
}
