'use client';

import { useState } from 'react';
import Link from 'next/link';
import { Server, ArrowLeft, Eye, EyeOff, CheckCircle, XCircle, Loader, Save, Info, Wifi, AlertCircle } from 'lucide-react';
import { useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { usePageHeader } from '@client/contexts/PageHeaderContext';
import { useLanguage } from '@client/contexts/LanguageContext';
import { getSipFeature, testSipConnection } from '@client/api/sip';

type Transport = 'UDP' | 'TCP' | 'TLS';
type TestStatus = 'idle' | 'testing' | 'success' | 'failed';

/**
 * Validates a SIP server hostname or IPv4 address without nested regex
 * quantifiers (ReDoS-safe). Each label is checked individually so there
 * is no backtracking ambiguity.
 */
function isValidSipHost(val: string): boolean {
  if (!val || val.length > 253) return false;
  // IPv4: simple linear pattern, validate each octet value separately
  if (/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(val)) {
    return val.split('.').every((seg) => {
      const n = Number(seg);
      return Number.isInteger(n) && n >= 0 && n <= 255;
    });
  }
  // Hostname: split on '.' and validate each label independently —
  // no nested quantifiers, guaranteed linear scan time.
  const labels = val.split('.');
  if (labels.length < 2) return false;
  const tld = labels[labels.length - 1];
  if (!/^[a-zA-Z]{2,63}$/.test(tld)) return false;
  return labels.slice(0, -1).every(
    (label) =>
      label.length >= 1 &&
      label.length <= 63 &&
      /^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$/.test(label),
  );
}

interface FormErrors {
  displayName?: string;
  sipServer?: string;
  username?: string;
  password?: string;
  port?: string;
}

function FieldError({ message }: { message?: string }) {
  if (!message) return null;
  return (
    <p className="flex items-center gap-1 text-xs mt-1.5 font-medium" style={{ color: 'hsl(0, 84%, 44%)' }}>
      <AlertCircle size={12} />
      {message}
    </p>
  );
}

export default function AddSIPTrunkPage() {
  const { t } = useLanguage();
  const router = useRouter();
  usePageHeader(t('phoneNumbers.sip.title', "Add SIP Trunk"), t('phoneNumbers.sip.subtitle', "Connect your existing telephony provider to the AI voice agent"));
  const [featureChecked, setFeatureChecked] = useState(false);
  const [featureEnabled, setFeatureEnabled] = useState(false);
  const [testError, setTestError] = useState<string | null>(null);
  useEffect(() => {
    getSipFeature().then(s => { setFeatureEnabled(s.enabled); setFeatureChecked(true); });
  }, []);
  useEffect(() => {
    if (featureChecked && !featureEnabled) router.replace('/ai-agent-config/phone-numbers');
  }, [featureChecked, featureEnabled, router]);
  const [form, setForm] = useState({
    displayName: '',
    sipServer: '',
    username: '',
    password: '',
    port: '5060',
    transport: 'UDP' as Transport,
    active: true,
  });
  const [showPassword, setShowPassword] = useState(false);
  const [testStatus, setTestStatus] = useState<TestStatus>('idle');
  const [saved, setSaved] = useState(false);
  const [saving, setSaving] = useState(false);
  const [saveError, setSaveError] = useState<string | null>(null);
  const [errors, setErrors] = useState<FormErrors>({});
  const [touched, setTouched] = useState<Record<string, boolean>>({});

  const validators: Record<string, (val: string) => string | undefined> = {
    displayName: (v) => !v.trim() ? t('phoneNumbers.sip.errors.displayNameRequired', 'Display name is required') : undefined,
    sipServer: (v) => !v.trim() ? t('phoneNumbers.sip.errors.serverRequired', 'SIP server address is required') : !isValidSipHost(v.trim()) ? t('phoneNumbers.sip.errors.serverInvalid', 'Please enter a valid hostname or IP address') : undefined,
    username: (v) => !v.trim() ? t('phoneNumbers.sip.errors.usernameRequired', 'SIP username is required') : undefined,
    password: (v) => !v ? t('phoneNumbers.sip.errors.passwordRequired', 'SIP password is required') : v.length < 4 ? t('phoneNumbers.sip.errors.passwordTooShort', 'Password must be at least 4 characters') : undefined,
    port: (v) => !v ? t('phoneNumbers.sip.errors.portRequired', 'Port is required') : isNaN(Number(v)) || Number(v) < 1 || Number(v) > 65535 ? t('phoneNumbers.sip.errors.portInvalid', 'Port must be between 1 and 65535') : undefined,
  };

  const update = (field: string, value: string | boolean) => {
    setForm(prev => ({ ...prev, [field]: value }));
    if (typeof value === 'string' && touched[field]) {
      setErrors(prev => ({ ...prev, [field]: validators[field]?.(value) }));
    }
  };

  const handleBlur = (field: string) => {
    setTouched(prev => ({ ...prev, [field]: true }));
    setErrors(prev => ({ ...prev, [field]: validators[field]?.(form[field as keyof typeof form] as string) }));
  };

  const validate = (): boolean => {
    const newErrors: FormErrors = {};
    const newTouched: Record<string, boolean> = {};
    ['displayName', 'sipServer', 'username', 'password', 'port'].forEach(field => {
      newTouched[field] = true;
      const err = validators[field]?.(form[field as keyof typeof form] as string);
      if (err) newErrors[field as keyof FormErrors] = err;
    });
    setErrors(newErrors);
    setTouched(prev => ({ ...prev, ...newTouched }));
    return Object.keys(newErrors).length === 0;
  };

  const testConnection = async () => {
    if (!validate()) return;
    setTestStatus('testing');
    setTestError(null);
    try {
      const result = await testSipConnection({
        sip_server: form.sipServer.trim(),
        sip_username: form.username.trim(),
        sip_password: form.password,
        sip_port: Number(form.port) || 5060,
        sip_transport: form.transport,
      });
      if (result.ok) {
        setTestStatus('success');
      } else {
        setTestStatus('failed');
        setTestError(result.error || null);
      }
    } catch (e) {
      setTestStatus('failed');
      setTestError(e instanceof Error ? e.message : 'Test failed');
    }
  };

  const handleSave = async () => {
    if (!validate()) return;
    setSaving(true);
    setSaveError(null);
    try {
      const res = await fetch('/api/telephone/sip', {
        method: 'POST',
        credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          display_name: form.displayName.trim(),
          sip_server: form.sipServer.trim(),
          sip_username: form.username.trim(),
          sip_password: form.password,
          sip_port: Number(form.port) || 5060,
          sip_transport: form.transport,
        }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) throw new Error(data.error || 'Failed to save SIP trunk');
      setSaved(true);
      const newId = (data?.line?.id as string | undefined);
      const target = newId ? `/ai-agent-config/phone-numbers/${newId}` : '/ai-agent-config/phone-numbers';
      setTimeout(() => router.push(target), 800);
    } catch (e) {
      setSaveError(e instanceof Error ? e.message : 'Failed to save SIP trunk');
    } finally {
      setSaving(false);
    }
  };

  if (!featureChecked) return null;
  if (!featureEnabled) return null;

  const inputStyle = (field: string) => ({
    borderColor: touched[field] && errors[field as keyof FormErrors] ? 'hsl(0, 84%, 44%)' : undefined,
    boxShadow: touched[field] && errors[field as keyof FormErrors] ? '0 0 0 2px hsl(0, 84%, 44%, 0.15)' : undefined,
  });

  return (
    <>
      <div className="max-w-2xl">
        <Link href="/ai-agent-config/phone-numbers" className="flex items-center gap-2 text-sm mb-6" style={{ color: 'hsl(var(--muted-foreground))' }}>
          <ArrowLeft size={15} /> {t('phoneNumbers.sip.backLink', 'Back to Phone Numbers')}
        </Link>

        {/* Info banner */}
        <div className="flex items-start gap-3 p-4 rounded-xl mb-6" style={{ backgroundColor: 'hsl(var(--info-bg))', border: '1px solid hsl(var(--info-border))' }}>
          <Info size={16} style={{ color: 'hsl(var(--info))', flexShrink: 0, marginTop: 1 }} />
          <div>
            <p className="text-sm font-medium" style={{ color: 'hsl(var(--info))' }}>{t('phoneNumbers.sip.infoTitle', 'SIP Trunk Integration')}</p>
            <p className="text-xs mt-0.5 leading-relaxed" style={{ color: 'hsl(210, 100%, 35%)' }}>
              {t('phoneNumbers.sip.infoText', 'Use your existing SIP trunk from providers like Twilio, Vonage, Bandwidth, or any SIP-compatible provider. Your AI agent will use this number to make and receive calls.')}
            </p>
          </div>
        </div>

        <div className="rounded-2xl p-6" style={{ backgroundColor: 'hsl(var(--surface))', border: '1px solid hsl(var(--border))' }}>
          <h3 className="font-semibold text-sm mb-5" style={{ color: 'hsl(var(--foreground))' }}>{t('phoneNumbers.sip.configTitle', 'SIP Trunk Configuration')}</h3>
          <div className="space-y-4">
            <div>
              <label className="block text-xs font-semibold mb-1.5" style={{ color: 'hsl(var(--foreground-secondary))' }}>{t('phoneNumbers.sip.displayName', 'Display Name')} *</label>
              <input
                type="text"
                placeholder={t('phoneNumbers.sip.displayNamePlaceholder', "e.g. UK Branch SIP Trunk")}
                value={form.displayName}
                onChange={e => update('displayName', e.target.value)}
                onBlur={() => handleBlur('displayName')}
                className="input-field w-full"
                style={inputStyle('displayName')}
              />
              <FieldError message={touched.displayName ? errors.displayName : undefined} />
              {!errors.displayName && <p className="text-xs mt-1" style={{ color: 'hsl(var(--muted-foreground))' }}>{t('phoneNumbers.sip.displayNameHint', 'A friendly name to identify this trunk')}</p>}
            </div>

            <div>
              <label className="block text-xs font-semibold mb-1.5" style={{ color: 'hsl(var(--foreground-secondary))' }}>{t('phoneNumbers.sip.sipServer', 'SIP Server / Host')} *</label>
              <input
                type="text"
                placeholder={t('phoneNumbers.sip.sipServerPlaceholder', "e.g. sip.yourprovider.com")}
                value={form.sipServer}
                onChange={e => update('sipServer', e.target.value)}
                onBlur={() => handleBlur('sipServer')}
                className="input-field w-full font-mono"
                style={inputStyle('sipServer')}
              />
              <FieldError message={touched.sipServer ? errors.sipServer : undefined} />
            </div>

            <div className="grid grid-cols-2 gap-4">
              <div>
                <label className="block text-xs font-semibold mb-1.5" style={{ color: 'hsl(var(--foreground-secondary))' }}>{t('phoneNumbers.sip.username', 'Username')} *</label>
                <input
                  type="text"
                  placeholder={t('phoneNumbers.sip.usernamePlaceholder', "SIP username")}
                  value={form.username}
                  onChange={e => update('username', e.target.value)}
                  onBlur={() => handleBlur('username')}
                  className="input-field w-full font-mono"
                  style={inputStyle('username')}
                />
                <FieldError message={touched.username ? errors.username : undefined} />
              </div>
              <div>
                <label className="block text-xs font-semibold mb-1.5" style={{ color: 'hsl(var(--foreground-secondary))' }}>{t('phoneNumbers.sip.password', 'Password')} *</label>
                <div className="relative">
                  <input
                    type={showPassword ? 'text' : 'password'}
                    placeholder={t('phoneNumbers.sip.passwordPlaceholder', "SIP password")}
                    value={form.password}
                    onChange={e => update('password', e.target.value)}
                    onBlur={() => handleBlur('password')}
                    className="input-field w-full pr-10 font-mono"
                    style={inputStyle('password')}
                  />
                  <button
                    type="button"
                    className="absolute right-3 top-1/2 -translate-y-1/2"
                    onClick={() => setShowPassword(!showPassword)}
                  >
                    {showPassword ? <EyeOff size={14} style={{ color: 'hsl(var(--muted-foreground))' }} /> : <Eye size={14} style={{ color: 'hsl(var(--muted-foreground))' }} />}
                  </button>
                </div>
                <FieldError message={touched.password ? errors.password : undefined} />
              </div>
            </div>

            <div className="grid grid-cols-2 gap-4">
              <div>
                <label className="block text-xs font-semibold mb-1.5" style={{ color: 'hsl(var(--foreground-secondary))' }}>{t('phoneNumbers.sip.port', 'Port')}</label>
                <input
                  type="text"
                  placeholder="5060"
                  value={form.port}
                  onChange={e => update('port', e.target.value)}
                  onBlur={() => handleBlur('port')}
                  className="input-field w-full font-mono"
                  style={inputStyle('port')}
                />
                <FieldError message={touched.port ? errors.port : undefined} />
              </div>
              <div>
                <label className="block text-xs font-semibold mb-1.5" style={{ color: 'hsl(var(--foreground-secondary))' }}>{t('phoneNumbers.sip.transport', 'Transport Protocol')}</label>
                <select value={form.transport} onChange={e => update('transport', e.target.value)} className="input-field w-full">
                  <option value="UDP">UDP ({t('common.default', 'default')})</option>
                  <option value="TCP">TCP</option>
                  <option value="TLS">TLS ({t('phoneNumbers.sip.transportTls', 'encrypted')})</option>
                </select>
              </div>
            </div>

            {/* Active toggle */}
            <div className="flex items-center justify-between p-4 rounded-xl" style={{ backgroundColor: 'hsl(var(--muted))' }}>
              <div>
                <p className="text-sm font-medium" style={{ color: 'hsl(var(--foreground))' }}>{t('common.active', 'Active')}</p>
                <p className="text-xs" style={{ color: 'hsl(var(--muted-foreground))' }}>{t('phoneNumbers.sip.activeHint', 'Enable this SIP trunk for the AI agent')}</p>
              </div>
              <button
                onClick={() => update('active', !form.active)}
                className="relative inline-flex items-center w-11 h-6 rounded-full transition-colors"
                style={{ backgroundColor: form.active ? 'hsl(var(--primary))' : 'hsl(var(--border-strong))' }}
              >
                <span
                  className="inline-block w-4 h-4 bg-white rounded-full shadow transition-transform"
                  style={{ transform: form.active ? 'translateX(22px)' : 'translateX(3px)' }}
                />
              </button>
            </div>

            {/* Test connection */}
            <div className="p-4 rounded-xl" style={{ backgroundColor: 'hsl(var(--muted))', border: '1px solid hsl(var(--border))' }}>
              <div className="flex items-center justify-between mb-3">
                <div>
                  <p className="text-sm font-medium" style={{ color: 'hsl(var(--foreground))' }}>{t('phoneNumbers.sip.testTitle', 'Test Connection')}</p>
                  <p className="text-xs" style={{ color: 'hsl(var(--muted-foreground))' }}>{t('phoneNumbers.sip.testHint', 'Verify your SIP credentials before saving')}</p>
                </div>
                <button
                  className="btn-secondary text-sm"
                  onClick={testConnection}
                  disabled={testStatus === 'testing'}
                >
                  {testStatus === 'testing' ? (
                    <><Loader size={14} className="animate-spin" /> {t('common.testing', 'Testing...')}</>
                  ) : (
                    <><Wifi size={14} /> {t('phoneNumbers.sip.testButton', 'Test Connection')}</>
                  )}
                </button>
              </div>
              {testStatus === 'success' && (
                <div className="flex items-center gap-2 p-3 rounded-lg" style={{ backgroundColor: 'hsl(142, 72%, 96%)', border: '1px solid hsl(142, 72%, 85%)' }}>
                  <CheckCircle size={15} style={{ color: 'hsl(142, 72%, 29%)' }} />
                  <span className="text-xs font-medium" style={{ color: 'hsl(142, 72%, 29%)' }}>{t('phoneNumbers.sip.testSuccess', 'Connection successful! SIP trunk is reachable.')}</span>
                </div>
              )}
              {testStatus === 'failed' && (
                <div className="flex items-center gap-2 p-3 rounded-lg" style={{ backgroundColor: 'hsl(0, 84%, 97%)', border: '1px solid hsl(0, 84%, 85%)' }}>
                  <XCircle size={15} style={{ color: 'hsl(0, 84%, 44%)' }} />
                  <span className="text-xs font-medium" style={{ color: 'hsl(0, 84%, 44%)' }}>{testError || t('phoneNumbers.sip.testFailed', 'Connection failed. Check your server address and credentials.')}</span>
                </div>
              )}
            </div>

            {saveError && (
              <p className="text-xs font-medium" style={{ color: 'hsl(0, 84%, 44%)' }}>{saveError}</p>
            )}
            <div className="flex gap-3 pt-2">
              <button className="btn-primary flex-1" onClick={handleSave} disabled={saving}>
                {saving ? <Loader size={15} className="animate-spin" /> : <Save size={15} />}
                {saved ? t('common.saved', 'Saved!') : t('phoneNumbers.sip.saveButton', 'Save SIP Trunk')}
              </button>
              <Link href="/ai-agent-config/phone-numbers" className="btn-secondary">{t('common.cancel', 'Cancel')}</Link>
            </div>
          </div>
        </div>
      </div>
    </>
  );
}
