import { useState, useEffect, useRef } from 'react';
import api from '../lib/api';
import {
  PhoneCall,
  PhoneOff,
  Send,
  Volume2,
  VolumeX,
  Sparkles,
  PhoneForwarded,
  Clock,
} from 'lucide-react';
import { motion } from 'framer-motion';

interface CompanyOption {
  _id: string;
  companyName: string;
  twilioPhoneNumber?: string;
}

interface SimMessage {
  role: 'agent' | 'caller' | 'system';
  text: string;
  latencyMs?: number;
}

const VoiceSimulator = () => {
  const [companies, setCompanies] = useState<CompanyOption[]>([]);
  const [selectedCompanyId, setSelectedCompanyId] = useState<string>('');
  const [sessionId, setSessionId] = useState<string | null>(null);
  const [companyName, setCompanyName] = useState<string>('');
  const [messages, setMessages] = useState<SimMessage[]>([]);
  const [inputText, setInputText] = useState('');
  const [processing, setProcessing] = useState(false);
  const [voiceEnabled, setVoiceEnabled] = useState(true);

  const [outboundPhone, setOutboundPhone] = useState('');
  const [outboundStatus, setOutboundStatus] = useState('');
  const [outboundLoading, setOutboundLoading] = useState(false);
  const chatEndRef = useRef<HTMLDivElement | null>(null);

  useEffect(() => {
    let active = true;
    api
      .get<CompanyOption[]>('/company')
      .then((res) => {
        if (!active) return;
        setCompanies(res.data);
        if (res.data.length > 0) setSelectedCompanyId(res.data[0]._id);
      })
      .catch((err) => console.error('Failed to load companies', err));
    return () => {
      active = false;
    };
  }, []);

  const speakTextInBrowser = (text: string) => {
    if (!voiceEnabled || typeof window === 'undefined' || !('speechSynthesis' in window)) return;
    window.speechSynthesis.cancel();
    const utterance = new SpeechSynthesisUtterance(text);
    utterance.rate = 1.02;
    utterance.pitch = 1.0;
    window.speechSynthesis.speak(utterance);
  };

  const handleStartCall = async () => {
    try {
      setProcessing(true);
      const res = await api.post('/simulator/start', { companyId: selectedCompanyId });
      setSessionId(res.data.sessionId);
      setCompanyName(res.data.companyName);
      setMessages([{ role: 'agent', text: res.data.greeting }]);
      speakTextInBrowser(res.data.greeting);
    } catch (err) {
      console.error('Failed to start simulator call', err);
    } finally {
      setProcessing(false);
    }
  };

  const handleEndCall = async () => {
    if (!sessionId) return;
    if (typeof window !== 'undefined' && 'speechSynthesis' in window) {
      window.speechSynthesis.cancel();
    }
    try {
      await api.post('/simulator/end', { sessionId });
    } catch (err) {
      console.error('Failed to end simulator call', err);
    }
    setMessages((prev) => [...prev, { role: 'system', text: 'Call ended and saved to Call Logs.' }]);
    setSessionId(null);
  };

  const handleSendTurn = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!sessionId || !inputText.trim() || processing) return;

    const userText = inputText.trim();
    setInputText('');

    // Barge-in: immediately stop any ongoing speech when user sends new message
    if (typeof window !== 'undefined' && 'speechSynthesis' in window) {
      window.speechSynthesis.cancel();
    }

    setMessages((prev) => [...prev, { role: 'caller', text: userText }]);
    setProcessing(true);

    try {
      const res = await api.post('/simulator/turn', {
        sessionId,
        transcript: userText,
        synthesizeAudio: false,
      });

      const reply: string = res.data.response;
      const latencyMs: number = res.data.latencyMs;
      const action = res.data.action;

      setMessages((prev) => [...prev, { role: 'agent', text: reply, latencyMs }]);
      speakTextInBrowser(reply);

      if (action && action.name) {
        setMessages((prev) => [
          ...prev,
          {
            role: 'system',
            text: `Tool Executed: ${action.name} (${JSON.stringify(action.input)})`,
          },
        ]);
      }
      chatEndRef.current?.scrollIntoView({ behavior: 'smooth' });
    } catch (err) {
      console.error('Failed to process turn', err);
    } finally {
      setProcessing(false);
    }
  };

  const handleOutboundCall = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!outboundPhone.trim()) return;
    setOutboundLoading(true);
    setOutboundStatus('');
    try {
      const res = await api.post('/simulator/outbound-call', {
        toPhoneNumber: outboundPhone.trim(),
        companyId: selectedCompanyId,
      });
      setOutboundStatus(res.data.message || 'Outbound test call initiated!');
    } catch (err: unknown) {
      const msg = (err as { response?: { data?: { error?: string } } })?.response?.data?.error;
      setOutboundStatus(msg || 'Failed to place outbound call.');
    } finally {
      setOutboundLoading(false);
    }
  };

  return (
    <div className="space-y-8 pb-12">
      <div className="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4">
        <div>
          <h1 className="text-2xl font-bold text-white tracking-tight flex items-center gap-2">
            <Sparkles className="w-6 h-6 text-indigo-400" />
            AI Voice Assistant Simulator & Test Call
          </h1>
          <p className="mt-1 text-sm text-slate-400">
            Test your company's AI receptionist, domain knowledge, appointment booking, and barge-in live in the browser or trigger a real phone call.
          </p>
        </div>

        <div className="flex items-center gap-3">
          <select
            value={selectedCompanyId}
            onChange={(e) => setSelectedCompanyId(e.target.value)}
            disabled={!!sessionId}
            className="px-4 py-2 bg-slate-900 border border-slate-700 rounded-xl text-sm font-medium text-white"
          >
            {companies.map((c) => (
              <option key={c._id} value={c._id}>
                {c.companyName}
              </option>
            ))}
          </select>

          <button
            onClick={() => setVoiceEnabled(!voiceEnabled)}
            className="p-2.5 rounded-xl bg-white/5 border border-white/10 text-slate-300 hover:text-white"
            title={voiceEnabled ? 'Mute Browser Voice' : 'Unmute Browser Voice'}
          >
            {voiceEnabled ? <Volume2 className="w-5 h-5 text-indigo-400" /> : <VolumeX className="w-5 h-5" />}
          </button>
        </div>
      </div>

      <div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
        {/* Interactive Browser Simulator */}
        <div className="lg:col-span-2 bg-white/[0.02] border border-white/10 rounded-2xl p-6 flex flex-col h-[540px]">
          <div className="flex items-center justify-between pb-4 mb-4 border-b border-white/10">
            <div className="flex items-center gap-3">
              <div
                className={`w-3 h-3 rounded-full ${
                  sessionId ? 'bg-emerald-500 animate-pulse' : 'bg-slate-600'
                }`}
              />
              <span className="text-sm font-semibold text-white">
                {sessionId ? `Live Call Connected — ${companyName}` : 'Ready to Start Test Call'}
              </span>
            </div>

            {!sessionId ? (
              <button
                onClick={handleStartCall}
                disabled={processing}
                className="flex items-center gap-2 px-4 py-2 bg-emerald-600 hover:bg-emerald-500 text-white rounded-xl text-sm font-semibold transition-colors shadow-lg shadow-emerald-500/20"
              >
                <PhoneCall className="w-4 h-4" />
                Start Browser Call
              </button>
            ) : (
              <button
                onClick={handleEndCall}
                className="flex items-center gap-2 px-4 py-2 bg-rose-600 hover:bg-rose-500 text-white rounded-xl text-sm font-semibold transition-colors"
              >
                <PhoneOff className="w-4 h-4" />
                Hang Up
              </button>
            )}
          </div>

          <div className="flex-1 overflow-y-auto space-y-4 pr-2">
            {messages.length === 0 ? (
              <div className="h-full flex flex-col items-center justify-center text-center text-slate-500 px-6">
                <PhoneCall className="w-12 h-12 mb-3 opacity-20" />
                <p className="text-sm font-medium text-slate-300">
                  Click "Start Browser Call" to test your AI receptionist immediately
                </p>
                <p className="text-xs mt-1 max-w-md">
                  Try asking about your company's services, testing out-of-domain questions, or asking to book an appointment for tomorrow at 10:00.
                </p>
              </div>
            ) : (
              messages.map((m, idx) => (
                <motion.div
                  key={idx}
                  initial={{ opacity: 0, y: 6 }}
                  animate={{ opacity: 1, y: 0 }}
                  className={`flex flex-col ${
                    m.role === 'caller'
                      ? 'items-end'
                      : m.role === 'system'
                      ? 'items-center'
                      : 'items-start'
                  }`}
                >
                  {m.role === 'system' ? (
                    <span className="px-3 py-1 rounded-full bg-indigo-500/10 border border-indigo-500/20 text-indigo-300 text-xs font-mono">
                      {m.text}
                    </span>
                  ) : (
                    <>
                      <div className="flex items-center gap-2 mb-1">
                        <span className="text-[11px] font-semibold uppercase tracking-wider text-slate-400">
                          {m.role === 'agent' ? 'AI Receptionist' : 'You (Caller)'}
                        </span>
                        {m.latencyMs !== undefined && (
                          <span className="text-[10px] text-emerald-400 flex items-center gap-0.5">
                            <Clock className="w-2.5 h-2.5" /> {m.latencyMs}ms
                          </span>
                        )}
                      </div>
                      <div
                        className={`px-4 py-3 rounded-2xl max-w-[82%] text-sm ${
                          m.role === 'agent'
                            ? 'bg-slate-800 text-slate-100 border border-white/10 rounded-tl-sm'
                            : 'bg-indigo-600 text-white rounded-tr-sm'
                        }`}
                      >
                        {m.text}
                      </div>
                    </>
                  )}
                </motion.div>
              ))
            )}
            <div ref={chatEndRef} />
          </div>

          <form onSubmit={handleSendTurn} className="pt-4 mt-4 border-t border-white/10 flex gap-3">
            <input
              type="text"
              disabled={!sessionId || processing}
              value={inputText}
              onChange={(e) => setInputText(e.target.value)}
              placeholder={
                sessionId
                  ? 'Speak/type what the caller says (e.g. "Can I book an appointment tomorrow at 11:00?")'
                  : 'Start a call first...'
              }
              className="flex-1 px-4 py-3 bg-slate-900 border border-slate-700 rounded-xl text-sm text-white placeholder:text-slate-500 outline-none focus:ring-2 focus:ring-indigo-500 disabled:opacity-50"
            />
            <button
              type="submit"
              disabled={!sessionId || !inputText.trim() || processing}
              className="px-5 py-3 bg-indigo-600 hover:bg-indigo-500 disabled:opacity-50 text-white rounded-xl text-sm font-medium flex items-center gap-2 transition-colors"
            >
              <Send className="w-4 h-4" />
              Send
            </button>
          </form>
        </div>

        {/* Outbound Phone Call Trigger */}
        <div className="bg-white/[0.02] border border-white/10 rounded-2xl p-6 flex flex-col justify-between">
          <div>
            <div className="w-12 h-12 rounded-xl bg-indigo-500/10 border border-indigo-500/20 flex items-center justify-center text-indigo-400 mb-4">
              <PhoneForwarded className="w-6 h-6" />
            </div>
            <h3 className="text-lg font-bold text-white mb-2">Call My Phone (Live PSTN Test)</h3>
            <p className="text-sm text-slate-400 leading-relaxed mb-6">
              Want to experience the exact phone audio quality, 350ms human pick-up pause, and instant barge-in on your mobile phone? Enter your number below to have the AI agent call you via Twilio.
            </p>

            <form onSubmit={handleOutboundCall} className="space-y-4">
              <div>
                <label className="block text-xs font-medium text-slate-400 mb-1.5">
                  Your Phone Number (E.164 format)
                </label>
                <input
                  type="text"
                  required
                  value={outboundPhone}
                  onChange={(e) => setOutboundPhone(e.target.value)}
                  placeholder="+1234567890"
                  className="w-full px-4 py-3 bg-slate-900 border border-slate-700 rounded-xl text-sm text-white outline-none focus:ring-2 focus:ring-indigo-500"
                />
              </div>

              <button
                type="submit"
                disabled={outboundLoading || !outboundPhone.trim()}
                className="w-full py-3 bg-gradient-to-r from-indigo-600 to-purple-600 hover:from-indigo-500 hover:to-purple-500 disabled:opacity-50 text-white rounded-xl text-sm font-semibold transition-all shadow-lg shadow-indigo-500/20"
              >
                {outboundLoading ? 'Dialing via Twilio...' : 'Trigger Live Phone Call'}
              </button>
            </form>

            {outboundStatus && (
              <div className="mt-4 p-3 rounded-xl bg-white/5 border border-white/10 text-xs text-slate-300">
                {outboundStatus}
              </div>
            )}
          </div>

          <div className="mt-8 p-4 rounded-xl bg-indigo-500/5 border border-indigo-500/10 text-xs text-slate-400 space-y-1.5">
            <p className="font-semibold text-indigo-300">Active Capabilities in Call:</p>
            <p>• Strict Company Domain Guardrails</p>
            <p>• Hybrid Vector + Keyword RAG Memory</p>
            <p>• Live Calendar Availability & Booking</p>
            <p>• Department Call Forwarding</p>
          </div>
        </div>
      </div>
    </div>
  );
};

export default VoiceSimulator;
