'use client';

import { useState, useEffect, useCallback } from 'react';
import { Phone, CheckCircle, XCircle, Link2, Copy, Bot, ToggleLeft, ToggleRight, Mic, FileText, Settings, ChevronDown, ChevronUp, PhoneOutgoing, X, PhoneForwarded, Building2 } from 'lucide-react';
import { toast } from 'sonner';
import { getTwilioSettings, connectTwilio, disconnectTwilio as disconnectTwilioApi, assignAgent, toggleNumberActive, updateNumberSettings, makeOutboundCall } from '@client/api/telephone';
import { listAgents } from '@client/api/ai-agents';
import { listBranches } from '@client/api/branches';
import { useLanguage } from '@client/contexts/LanguageContext';
import type { TelephoneSettings, PhoneNumber } from '@client/api/telephone';
import type { AiAgent } from '@client/api/ai-agents';
import type { Branch } from '@client/api/branches';

type TFn = (key: string, fallback?: string, vars?: Record<string, string | number>) => string;

export default function TwilioTab() {
  const { t } = useLanguage();
  const [settings, setSettings] = useState<TelephoneSettings | null>(null);
  const [numbers, setNumbers] = useState<PhoneNumber[]>([]);
  const [agents, setAgents] = useState<AiAgent[]>([]);
  const [branches, setBranches] = useState<Branch[]>([]);
  const [loading, setLoading] = useState(true);
  const [connecting, setConnecting] = useState(false);
  const [showConnect, setShowConnect] = useState(false);
  const [accountSid, setAccountSid] = useState('');
  const [authToken, setAuthToken] = useState('');
  const [expandedNumber, setExpandedNumber] = useState<string | null>(null);

  const webhookBase = typeof window !== 'undefined' ? window.location.origin : '';

  const fetchData = useCallback(async () => {
    setLoading(true);
    try {
      const [twilioRes, agentRes, branchRes] = await Promise.all([
        getTwilioSettings(),
        listAgents(),
        listBranches({ limit: '100' }),
      ]);
      setSettings(twilioRes.settings);
      setNumbers(twilioRes.numbers || []);
      setAgents(agentRes.agents || []);
      setBranches(branchRes.branches || []);
    } catch (err: unknown) {
      toast.error(t('telephone.failedToLoad', 'Failed to load: {{error}}', { error: err instanceof Error ? err.message : '' }));
    } finally {
      setLoading(false);
    }
  }, [t]);

  useEffect(() => { fetchData(); }, [fetchData]);

  const handleConnect = async () => {
    if (!accountSid.trim() || !authToken.trim()) {
      toast.error(t('telephone.twilioCredentialsRequired', 'Both Account SID and Auth Token are required'));
      return;
    }
    setConnecting(true);
    try {
      const res = await connectTwilio(accountSid.trim(), authToken.trim());
      if (res.connected) {
        toast.success(t('telephone.twilioConnectedSuccess', 'Twilio connected successfully'));
        setShowConnect(false);
        setAccountSid('');
        setAuthToken('');
        fetchData();
      } else {
        toast.error(res.error || t('telephone.failedToConnect', 'Failed to connect'));
      }
    } catch (err: unknown) {
      toast.error(err instanceof Error ? err.message : t('telephone.connectionFailed', 'Connection failed'));
    } finally {
      setConnecting(false);
    }
  };

  const handleDisconnect = async () => {
    try {
      await disconnectTwilioApi();
      toast.success(t('telephone.twilioDisconnected', 'Twilio disconnected'));
      fetchData();
    } catch (err: unknown) {
      toast.error(err instanceof Error ? err.message : t('telephone.failed', 'Failed'));
    }
  };

  const [showCallDialog, setShowCallDialog] = useState(false);
  const [callTo, setCallTo] = useState('');
  const [callFromId, setCallFromId] = useState('');
  const [calling, setCalling] = useState(false);

  const copyToClipboard = (text: string) => {
    navigator.clipboard.writeText(text);
    toast.success(t('telephone.copiedToClipboard', 'Copied to clipboard'));
  };

  if (loading) {
    return (
      <div className="space-y-4">
        {[1, 2, 3].map(i => (
          <div key={i} className="card p-5 animate-pulse">
            <div className="h-4 rounded w-1/3 mb-3" style={{ backgroundColor: 'hsl(var(--muted))' }} />
            <div className="h-3 rounded w-2/3" style={{ backgroundColor: 'hsl(var(--muted))' }} />
          </div>
        ))}
      </div>
    );
  }

  const handleMakeCall = async () => {
    if (!callTo.trim() || !callFromId) { toast.error(t('telephone.outboundCallMissingInfo', 'Enter a number and select a from number')); return; }
    setCalling(true);
    try {
      const res = await makeOutboundCall(callTo.trim(), callFromId);
      if (res.success) {
        toast.success(t('telephone.callInitiated', 'Call initiated (SID: {{sid}}...)', { sid: res.callSid?.slice(0, 12) ?? '' }));
        setShowCallDialog(false);
        setCallTo('');
      }
    } catch (err: unknown) {
      toast.error(err instanceof Error ? err.message : t('telephone.failedToMakeCall', 'Failed to make call'));
    } finally {
      setCalling(false);
    }
  };

  const isConnected = settings?.twilio_connected ?? false;
  const activeNumbers = numbers.filter(n => n.is_active);

  return (
    <div className="space-y-5">
      <ConnectionCard
        t={t}
        isConnected={isConnected}
        settings={settings}
        showConnect={showConnect}
        setShowConnect={setShowConnect}
        accountSid={accountSid}
        setAccountSid={setAccountSid}
        authToken={authToken}
        setAuthToken={setAuthToken}
        connecting={connecting}
        onConnect={handleConnect}
        onDisconnect={handleDisconnect}
      />

      {isConnected && activeNumbers.length > 0 && (
        <div className="card p-5">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-2">
              <PhoneOutgoing size={16} style={{ color: 'hsl(var(--primary))' }} />
              <h3 className="font-semibold" style={{ color: 'hsl(var(--foreground))' }}>{t('telephone.outboundCalls', 'Outbound Calls')}</h3>
            </div>
            <button className="btn-primary text-xs" onClick={() => setShowCallDialog(true)}>
              <PhoneOutgoing size={13} /> {t('telephone.makeCall', 'Make Call')}
            </button>
          </div>
          {showCallDialog && (
            <div className="mt-4 border rounded-xl p-4 space-y-3" style={{ borderColor: 'hsl(var(--primary))' }}>
              <div className="flex items-center justify-between">
                <span className="text-sm font-medium" style={{ color: 'hsl(var(--foreground))' }}>{t('telephone.newOutboundCall', 'New Outbound Call')}</span>
                <button className="btn-ghost p-1" onClick={() => setShowCallDialog(false)}><X size={14} /></button>
              </div>
              <div>
                <label className="label-base">{t('telephone.toNumber', 'To Number')}</label>
                <input className="input-base" placeholder="+1234567890" value={callTo} onChange={e => setCallTo(e.target.value)} />
              </div>
              <div>
                <label className="label-base">{t('telephone.fromNumber', 'From Number')}</label>
                <select className="input-base" value={callFromId} onChange={e => setCallFromId(e.target.value)}>
                  <option value="">{t('telephone.selectNumber', 'Select a number')}</option>
                  {activeNumbers.map(n => <option key={n.id} value={n.id}>{n.number}</option>)}
                </select>
              </div>
              <button className="btn-primary text-sm w-full" onClick={handleMakeCall} disabled={calling}>
                {calling ? t('telephone.calling', 'Calling...') : t('telephone.callNow', 'Call Now')}
              </button>
            </div>
          )}
        </div>
      )}

      <WebhookCard t={t} webhookBase={webhookBase} copyToClipboard={copyToClipboard} />

      <PhoneNumbersCard
        t={t}
        numbers={numbers}
        agents={agents}
        branches={branches}
        isConnected={isConnected}
        expandedNumber={expandedNumber}
        setExpandedNumber={setExpandedNumber}
        setNumbers={setNumbers}
      />
    </div>
  );
}

function ConnectionCard({ t, isConnected, settings, showConnect, setShowConnect, accountSid, setAccountSid, authToken, setAuthToken, connecting, onConnect, onDisconnect }: {
  t: TFn; isConnected: boolean; settings: TelephoneSettings | null; showConnect: boolean; setShowConnect: (v: boolean) => void;
  accountSid: string; setAccountSid: (v: string) => void; authToken: string; setAuthToken: (v: string) => void;
  connecting: boolean; onConnect: () => void; onDisconnect: () => void;
}) {
  return (
    <div className="card p-5">
      <div className="flex items-center justify-between mb-4">
        <div className="flex items-center gap-3">
          <div className="w-10 h-10 rounded-xl flex items-center justify-center"
            style={{ backgroundColor: isConnected ? 'hsl(var(--success-bg))' : 'hsl(var(--muted))' }}>
            <Phone size={20} style={{ color: isConnected ? 'hsl(var(--success))' : 'hsl(var(--muted-foreground))' }} />
          </div>
          <div>
            <h3 className="font-semibold" style={{ color: 'hsl(var(--foreground))' }}>{t('telephone.twilioConnection', 'Twilio Connection')}</h3>
            <div className="flex items-center gap-1.5 mt-0.5">
              {isConnected ? (
                <>
                  <CheckCircle size={12} style={{ color: 'hsl(var(--success))' }} />
                  <span className="text-xs font-medium" style={{ color: 'hsl(var(--success))' }}>
                    {t('telephone.connected', 'Connected')} {settings?.twilio_account_sid_hint ? `(${settings.twilio_account_sid_hint})` : ''}
                  </span>
                </>
              ) : (
                <>
                  <XCircle size={12} style={{ color: 'hsl(var(--muted-foreground))' }} />
                  <span className="text-xs" style={{ color: 'hsl(var(--muted-foreground))' }}>{t('telephone.notConnected', 'Not connected')}</span>
                </>
              )}
            </div>
          </div>
        </div>
        {isConnected ? (
          <button className="btn-secondary text-xs" onClick={onDisconnect}>{t('telephone.disconnect', 'Disconnect')}</button>
        ) : (
          <button className="btn-primary text-xs" onClick={() => setShowConnect(true)}>{t('telephone.connectTwilio', 'Connect Twilio')}</button>
        )}
      </div>

      {showConnect && !isConnected && (
        <div className="border rounded-xl p-4 space-y-3" style={{ borderColor: 'hsl(var(--primary))' }}>
          <div>
            <label className="label-base">{t('telephone.accountSid', 'Account SID')}</label>
            <input className="input-base" placeholder={t('telephone.accountSidPlaceholder', 'ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')}
              value={accountSid} onChange={e => setAccountSid(e.target.value)} />
          </div>
          <div>
            <label className="label-base">{t('telephone.authToken', 'Auth Token')}</label>
            <input className="input-base" type="password" placeholder={t('telephone.authTokenPlaceholder', 'Your Twilio Auth Token')}
              value={authToken} onChange={e => setAuthToken(e.target.value)} />
          </div>
          <p className="text-xs" style={{ color: 'hsl(var(--muted-foreground))' }}>
            {t('telephone.credentialsDesc', 'Credentials are verified with Twilio and stored encrypted. The connection can be disconnected at any time which clears stored credentials.')}
          </p>
          <div className="flex gap-2">
            <button className="btn-primary text-sm flex-1" onClick={onConnect} disabled={connecting}>
              {connecting ? t('telephone.verifying', 'Verifying...') : t('telephone.connect', 'Connect')}
            </button>
            <button className="btn-secondary text-sm" onClick={() => setShowConnect(false)}>{t('telephone.cancel', 'Cancel')}</button>
          </div>
        </div>
      )}
    </div>
  );
}

function WebhookCard({ t, webhookBase, copyToClipboard }: { t: TFn; webhookBase: string; copyToClipboard: (t: string) => void }) {
  return (
    <div className="card p-5">
      <div className="flex items-center gap-2 mb-4">
        <Link2 size={16} style={{ color: 'hsl(var(--primary))' }} />
        <h3 className="font-semibold" style={{ color: 'hsl(var(--foreground))' }}>{t('telephone.webhookUrls', 'Webhook URLs')}</h3>
      </div>
      <p className="text-xs mb-3" style={{ color: 'hsl(var(--muted-foreground))' }}>
        {t('telephone.webhookDesc', 'These webhooks are automatically configured when you assign an agent to a number. For manual setup, use these URLs in your Twilio Console.')}
      </p>
      <div className="space-y-3">
        {[
          { label: t('telephone.voiceWebhook', 'Voice Webhook (POST)'), url: `${webhookBase}/api/webhooks/twilio/voice` },
          { label: t('telephone.statusCallback', 'Call Status Callback (POST)'), url: `${webhookBase}/api/webhooks/twilio/status` },
        ].map(wh => (
          <div key={wh.label} className="flex items-center gap-3 p-3 rounded-lg" style={{ backgroundColor: 'hsl(var(--muted))' }}>
            <div className="flex-1 min-w-0">
              <p className="text-xs font-medium" style={{ color: 'hsl(var(--muted-foreground))' }}>{wh.label}</p>
              <code className="text-xs break-all" style={{ color: 'hsl(var(--primary))' }}>{wh.url}</code>
            </div>
            <button className="btn-ghost p-1.5 shrink-0" onClick={() => copyToClipboard(wh.url)} title={t('telephone.copyUrl', 'Copy URL')}>
              <Copy size={13} style={{ color: 'hsl(var(--primary))' }} />
            </button>
          </div>
        ))}
      </div>
    </div>
  );
}

function PhoneNumbersCard({ t, numbers, agents, branches, isConnected, expandedNumber, setExpandedNumber, setNumbers }: {
  t: TFn; numbers: PhoneNumber[]; agents: AiAgent[]; branches: Branch[]; isConnected: boolean;
  expandedNumber: string | null; setExpandedNumber: (v: string | null) => void;
  setNumbers: React.Dispatch<React.SetStateAction<PhoneNumber[]>>;
}) {
  const handleAssign = async (num: PhoneNumber, agentId: string | null) => {
    try {
      await assignAgent(num.id, agentId);
      setNumbers(prev => prev.map(n => n.id === num.id ? { ...n, assigned_agent_id: agentId, assigned_agent_name: agentId ? agents.find(a => a.id === agentId)?.name || null : null } : n));
      toast.success(t('telephone.agentAssignmentUpdated', 'Agent assignment updated'));
    } catch (err: unknown) {
      toast.error(err instanceof Error ? err.message : t('telephone.failedToAssignAgent', 'Failed to assign agent'));
    }
  };

  const handleToggle = async (num: PhoneNumber) => {
    try {
      await toggleNumberActive(num.id, !num.is_active);
      setNumbers(prev => prev.map(n => n.id === num.id ? { ...n, is_active: !n.is_active } : n));
      toast.success(num.is_active ? t('telephone.numberDeactivated', 'Number deactivated') : t('telephone.numberActivated', 'Number activated'));
    } catch (err: unknown) {
      toast.error(err instanceof Error ? err.message : t('telephone.failedToToggle', 'Failed to toggle'));
    }
  };

  const handleUpdateSettings = async (num: PhoneNumber, field: string, value: unknown) => {
    try {
      const data = { [field]: value };
      const res = await updateNumberSettings(num.id, data);
      if (res.numbers) setNumbers(res.numbers);
      toast.success(t('telephone.settingUpdated', 'Setting updated'));
    } catch (err: unknown) {
      toast.error(err instanceof Error ? err.message : t('telephone.failedToUpdate', 'Failed to update'));
    }
  };

  return (
    <div className="card p-5">
      <div className="flex items-center gap-2 mb-4">
        <Phone size={16} style={{ color: 'hsl(var(--primary))' }} />
        <h3 className="font-semibold" style={{ color: 'hsl(var(--foreground))' }}>{t('telephone.phoneNumbers', 'Phone Numbers')}</h3>
        {numbers.length > 0 && (
          <span className="text-xs px-1.5 py-0.5 rounded-full" style={{ backgroundColor: 'hsl(var(--muted))', color: 'hsl(var(--muted-foreground))' }}>
            {numbers.length}
          </span>
        )}
      </div>

      {numbers.length === 0 ? (
        <div className="text-center py-8" style={{ color: 'hsl(var(--muted-foreground))' }}>
          <Phone size={28} className="mx-auto mb-2 opacity-30" />
          <p className="text-sm font-medium">{t('telephone.noPhoneNumbers', 'No phone numbers')}</p>
          <p className="text-xs mt-1">
            {isConnected
              ? t('telephone.twilioSyncDesc', 'Your Twilio numbers will be synced automatically. Purchase numbers in the Twilio Console.')
              : t('telephone.connectTwilioFirstDesc', 'Connect Twilio first to sync and manage your phone numbers.')}
          </p>
        </div>
      ) : (
        <div className="space-y-3">
          {numbers.map(num => (
            <div key={num.id} className="rounded-lg" style={{ backgroundColor: 'hsl(var(--muted))' }}>
              <div className="flex items-center gap-3 p-3">
                <div className="flex-1 min-w-0">
                  <p className="text-sm font-medium" style={{ color: 'hsl(var(--foreground))' }}>{num.number}</p>
                  <div className="flex items-center gap-2 flex-wrap">
                    {num.display_name && <span className="text-xs" style={{ color: 'hsl(var(--muted-foreground))' }}>{num.display_name}</span>}
                    {num.branch_id && branches.length > 0 && (
                      <span className="flex items-center gap-0.5 text-xs px-1.5 py-0.5 rounded-full"
                        style={{ backgroundColor: 'hsl(var(--primary) / 0.1)', color: 'hsl(var(--primary))' }}>
                        <Building2 size={10} />
                        {branches.find(b => b.id === num.branch_id)?.name ?? t('telephone.branch', 'Branch')}
                      </span>
                    )}
                  </div>
                </div>
                <div className="flex items-center gap-2">
                  <Bot size={13} style={{ color: 'hsl(var(--muted-foreground))' }} />
                  <select className="input-base text-xs py-1 max-w-[160px]"
                    value={num.assigned_agent_id || ''}
                    onChange={(e) => handleAssign(num, e.target.value || null)}>
                    <option value="">{t('telephone.noAgentAssigned', 'No agent assigned')}</option>
                    {agents.map(a => <option key={a.id} value={a.id}>{a.name}</option>)}
                  </select>
                  <button onClick={() => handleToggle(num)} title={num.is_active ? t('telephone.deactivate', 'Deactivate') : t('telephone.activate', 'Activate')}>
                    {num.is_active
                      ? <ToggleRight size={22} style={{ color: 'hsl(var(--success))' }} />
                      : <ToggleLeft size={22} style={{ color: 'hsl(var(--muted-foreground))' }} />}
                  </button>
                  <button className="btn-ghost p-1" onClick={() => setExpandedNumber(expandedNumber === num.id ? null : num.id)} title={t('telephone.callSettings', 'Call settings')}>
                    <Settings size={14} style={{ color: 'hsl(var(--muted-foreground))' }} />
                    {expandedNumber === num.id ? <ChevronUp size={10} /> : <ChevronDown size={10} />}
                  </button>
                </div>
              </div>

              {expandedNumber === num.id && (
                <div className="px-3 pb-3 pt-0 space-y-3 border-t" style={{ borderColor: 'hsl(var(--border))' }}>
                  <div className="pt-3 flex flex-col sm:flex-row gap-4">
                    <label className="flex items-center gap-2 cursor-pointer">
                      <Mic size={14} style={{ color: 'hsl(var(--muted-foreground))' }} />
                      <span className="text-xs" style={{ color: 'hsl(var(--foreground))' }}>{t('telephone.callRecording', 'Call Recording')}</span>
                      <button onClick={() => handleUpdateSettings(num, 'call_recording', !num.call_recording)}>
                        {num.call_recording
                          ? <ToggleRight size={20} style={{ color: 'hsl(var(--success))' }} />
                          : <ToggleLeft size={20} style={{ color: 'hsl(var(--muted-foreground))' }} />}
                      </button>
                    </label>
                    <label className="flex items-center gap-2 cursor-pointer">
                      <FileText size={14} style={{ color: 'hsl(var(--muted-foreground))' }} />
                      <span className="text-xs" style={{ color: 'hsl(var(--foreground))' }}>{t('telephone.callTranscription', 'Call Transcription')}</span>
                      <button onClick={() => handleUpdateSettings(num, 'call_transcription', !num.call_transcription)}>
                        {num.call_transcription
                          ? <ToggleRight size={20} style={{ color: 'hsl(var(--success))' }} />
                          : <ToggleLeft size={20} style={{ color: 'hsl(var(--muted-foreground))' }} />}
                      </button>
                    </label>
                  </div>
                  {branches.length > 0 && (
                    <div>
                      <label className="flex items-center gap-1 mb-1">
                        <Building2 size={14} style={{ color: 'hsl(var(--muted-foreground))' }} />
                        <span className="text-xs" style={{ color: 'hsl(var(--foreground))' }}>{t('telephone.branchAssignment', 'Branch Assignment')}</span>
                      </label>
                      <select
                        className="input-base text-xs"
                        value={num.branch_id || ''}
                        onChange={(e) => handleUpdateSettings(num, 'branch_id', e.target.value || null)}
                      >
                        <option value="">{t('telephone.allBranches', 'All branches (restaurant-wide)')}</option>
                        {branches.map(b => (
                          <option key={b.id} value={b.id}>{b.name}</option>
                        ))}
                      </select>
                      <p className="text-xs mt-1" style={{ color: 'hsl(var(--muted-foreground))' }}>
                        {t('telephone.branchAssignmentDesc', 'Orders and bookings from calls on this number will be attributed to the selected branch.')}
                      </p>
                    </div>
                  )}
                  <div>
                    <label className="flex items-center gap-1 mb-1">
                      <PhoneForwarded size={14} style={{ color: 'hsl(var(--muted-foreground))' }} />
                      <span className="text-xs" style={{ color: 'hsl(var(--foreground))' }}>{t('telephone.fallbackNumber', 'Fallback / Transfer Number')}</span>
                    </label>
                    <input className="input-base text-xs"
                      placeholder={t('telephone.fallbackPlaceholder', '+1234567890 — calls transfer here on escalation')}
                      defaultValue={num.fallback_number || ''}
                      onBlur={(e) => {
                        const val = e.target.value.trim() || null;
                        if (val !== (num.fallback_number || null)) {
                          handleUpdateSettings(num, 'fallback_number', val);
                        }
                      }}
                    />
                  </div>
                </div>
              )}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}
