import { useEffect, useRef } from 'react';
import { X } from 'lucide-react';
import { Dialog, DialogOverlay, DialogPortal } from '@/components/ui/dialog';
import * as DialogPrimitive from '@radix-ui/react-dialog';
import { cardStyle } from '@/components/Card';
import type { TaskInfo } from 'apps/Chat';
import { usePi } from '@/Screens/Dashboard/Chat/usePi';
import { EmbeddableChat } from '@/Screens/Dashboard/Chat/EmbeddableChat';
import { useVisiblePiModels } from '@/state/useModels';
import { useSettings } from '@/state/useSettings';
import type { TaskSummary } from 'apps/FileBrowser';

const playDing = () => {
  const ctx = new AudioContext();
  const t = ctx.currentTime;

  const play = (freq: number, start: number, dur: number) => {
    const osc = ctx.createOscillator();
    const gain = ctx.createGain();
    osc.type = 'sine';
    osc.frequency.setValueAtTime(freq, t + start);
    gain.gain.setValueAtTime(0.8, t + start);
    gain.gain.setValueAtTime(0.8, t + start + dur * 0.6);
    gain.gain.exponentialRampToValueAtTime(0.001, t + start + dur);
    osc.connect(gain).connect(ctx.destination);
    osc.start(t + start);
    osc.stop(t + start + dur);
  };

  play(880, 0, 0.4);
  play(1100, 0.25, 0.4);
  play(1320, 0.5, 0.6);

  setTimeout(() => ctx.close(), 1500);
};

type PiMonoInnerProps = {
  defaultInput: string;
  cwd: { root?: string; path: string };
  initialModel: string | null;
  taskInfo: TaskInfo;
};

const PiMonoInner = ({
  defaultInput,
  cwd,
  initialModel,
  taskInfo,
}: PiMonoInnerProps) => {
  const chat = usePi(undefined, initialModel, { replaceUrl: false, taskInfo });
  const models = useVisiblePiModels();

  const wasGenerating = useRef(false);
  useEffect(() => {
    if (wasGenerating.current && !chat.isGenerating) playDing();
    wasGenerating.current = chat.isGenerating;
  }, [chat.isGenerating]);

  return (
    <EmbeddableChat
      chat={chat}
      availableModels={models}
      defaultInput={defaultInput}
      cwd={cwd}
      className="flex-1 min-h-0"
    />
  );
};

type TaskRunnerModalProps = {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  task: TaskSummary;
  entryName?: string;
  entryType?: 'file' | 'directory';
  cwd?: { root?: string; path: string };
  promptOverride?: string;
};

export const TaskRunnerModal = ({ open, onOpenChange, task, entryName, entryType, cwd = { path: '' }, promptOverride }: TaskRunnerModalProps) => {
  const { settings } = useSettings();
  const taskSettings = settings.tasks;
  const defaultInput = promptOverride
    ?? (entryName && entryType
      ? `Read the task instructions at ${task.filePath} and execute them on the ${entryType}: ${entryName}`
      : `Read the task instructions at ${task.filePath} and execute them`);
  const taskInfo: TaskInfo = { taskName: task.name, taskDirName: task.dirName, entryName: entryName ?? '', entryType: entryType ?? 'file' };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogPortal>
        <DialogOverlay className="z-[700] bg-black/60 backdrop-blur-sm" />
        <DialogPrimitive.Content
          onOpenAutoFocus={(ev) => ev.preventDefault()}
          className="fixed left-[50%] top-[50%] z-[700] translate-x-[-50%] translate-y-[-50%] flex flex-col overflow-hidden rounded-xl border-2 border-duck-dark/30 shadow-2xl w-[90vw] max-w-3xl h-[80vh] duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95"
          style={cardStyle()}
        >
          {/* Header */}
          <div className="shrink-0 flex items-center gap-3 px-5 py-3 border-b border-duck-dark/10 bg-background/60">
            <div className="flex-1 min-w-0">
              <span className="text-sm font-semibold text-duck-dark truncate block">{task.name}</span>
              <span className="text-xs text-duck-dark/50 truncate block">{entryName}</span>
            </div>
            <DialogPrimitive.Close className="p-1.5 rounded-md text-duck-dark/40 hover:text-duck-dark hover:bg-duck-dark/5 transition-colors cursor-pointer">
              <X className="h-4 w-4" />
            </DialogPrimitive.Close>
          </div>

          {/* Chat */}
          <PiMonoInner
            key="pi"
            defaultInput={defaultInput}
            cwd={cwd}
            initialModel={taskSettings.defaultProvider === 'pi' ? taskSettings.defaultModel : null}
            taskInfo={taskInfo}
          />
        </DialogPrimitive.Content>
      </DialogPortal>
    </Dialog>
  );
};
