/* Bot — 20 простых вопросов и ответов (детектор по ключевым словам).
   Exports: botReply(userText) -> string | null, BOT_HINTS: string[],
            useChatBot(thread, setThread) -> { sendUser(text), sendAttach(file) }
   Also: useCallState() — эмуляция аудио/видео-звонков с продолжительностью,
         звуком "вызова" (без реального аудио, только pulse), и автоматическим
         "ответом собеседника" через 2 сек.
*/

const BOT_QA = [
  // 1
  { match: /(привет|здравств|добрый день|добрый вечер|hi|hello)/i,
    reply: 'Здравствуйте! На связи бот‑диспетчер ВД. Задайте вопрос по расписанию, грузу или экипажу.' },
  // 2
  { match: /(как дела|как жизнь|how are you)/i,
    reply: 'Всё штатно: 14 рейсов в воздухе, 3 на погрузке. Чем помочь?' },
  // 3
  { match: /(расписан|слот|вылет|график)/i,
    reply: 'Сегодня 27 рейсов. Ближайший: ULY→DXB, RA‑82045, вылет 15:10 UTC. Подробнее — в #ops‑dispatch.' },
  // 4
  { match: /(погод|ветер|метео|метар|taf)/i,
    reply: 'ULY: ясно, ветер 230°/6 м/с, видимость 10+ км. DXB: дымка, 31 °C, ветер 290°/4 уз.' },
  // 5
  { match: /(груз|манифест|тонна|вес|багаж)/i,
    reply: 'Средняя загрузка по парку Ан‑124 сегодня — 87 т. По RA‑82045 манифест подписан, ЦТ в норме.' },
  // 6
  { match: /(экипаж|пилот|командир|капитан)/i,
    reply: 'Командир ВС — Иван Аксёнов, 2П — Сергей Кузьмин, БИ — Дмитрий Романов. Предполётный брифинг в 13:40.' },
  // 7
  { match: /(документ|инструкц|регламент|sop|пособи)/i,
    reply: 'Свежая версия SOP‑124/r.18 лежит в канале #crew‑an124 → «Файлы». Ретенция 365 дней.' },
  // 8
  { match: /(dlp|политик|классифик|дсп|конфиденц)/i,
    reply: 'Политика CLS‑AUTO v17: ПУБ · ДСП · К · С. Пересылка «К» во внешние чаты блокируется DLP.' },
  // 9
  { match: /(запрос контакт|запросить контакт|добавить контакт)/i,
    reply: 'Запрос отправляется руководителю сотрудника. Каскад согласования — до 2 уровней, SLA 4 ч.' },
  // 10
  { match: /(отпуск|больничн|отгул)/i,
    reply: 'Заявления — в портале HR. Чат‑бот создаёт черновик: пришлите даты в формате ДД.ММ–ДД.ММ.' },
  // 11
  { match: /(зарплат|аванс|расчётн)/i,
    reply: 'Расчётный лист доступен в личном кабинете. Аванс — 20 числа, окончательный — 5 числа.' },
  // 12
  { match: /(vpn|впн|доступ|пароль)/i,
    reply: 'Сброс пароля — через #it‑helpdesk или команду /reset. VPN‑клиент: VD‑GlobalProtect.' },
  // 13
  { match: /(баг|ошибк|не работает|проблем|глюч)/i,
    reply: 'Опишите проблему одним сообщением — создам тикет в Service Desk. Приоритет уточним по SLA.' },
  // 14
  { match: /(матрица|разрешен|permission|права)/i,
    reply: 'Матрица отдел×отдел — во вкладке «Разрешения». Красная ячейка — запрет, серая — требует запроса.' },
  // 15
  { match: /(спасибо|благодар|thx|thanks)/i,
    reply: 'Всегда пожалуйста 🙂 Работаем.' },
  // 16
  { match: /(время|сколько времени|который час)/i,
    reply: () => `По Москве сейчас ${new Date().toLocaleTimeString('ru-RU',{hour:'2-digit',minute:'2-digit'})}. UTC — ${new Date().toUTCString().slice(17,22)}.` },
  // 17
  { match: /(курс|доллар|евро|рубл)/i,
    reply: 'Курсы корпоративного дня: USD 92.4, EUR 99.8, CNY 12.7. Обновление — в 10:00 МСК.' },
  // 18
  { match: /(адрес|офис|где|куда ехать)/i,
    reply: 'Штаб‑квартира: Ульяновск, Центр‑Аэро, Аэропорт Восточный. Пропуск — у охраны, терминал B.' },
  // 19
  { match: /(контакт|телефон|связ)/i,
    reply: 'Круглосуточный OCC: +7 (8422) 20‑77‑77, внутренний 7777. Для срочных — канал #ops‑dispatch.' },
  // 20
  { match: /(помощ|help|что умее|команд)/i,
    reply: 'Спросите про: расписание, погоду, груз, экипаж, документы, DLP, запросы контактов, отпуск, VPN, время, курсы, офис, контакты.' },
];

const BOT_HINTS = [
  'Расписание на сегодня?',
  'Погода в DXB?',
  'Статус рейса RA‑82045',
  'Кто командир экипажа?',
  'Правила DLP для «К»',
  'Как запросить контакт?',
  'Сброс пароля VPN',
  'Матрица разрешений',
  'Который час по UTC?',
  'Курсы валют',
];

function botReply(text) {
  if (!text) return null;
  for (const qa of BOT_QA) {
    if (qa.match.test(text)) {
      return typeof qa.reply === 'function' ? qa.reply(text) : qa.reply;
    }
  }
  // fallback
  return 'Принял. Уточните, пожалуйста: какой рейс / отдел / документ имеется в виду? Или спросите «помощь».';
}

// Хук: добавляет к setThread возможность получать ответ бота.
// Возвращает { sendUser, isTyping } — sendUser сразу добавляет сообщение
// пользователя и через ~900ms — ответ «собеседника».
function useChatBot(setThread, { enabled=true, delay=900 }={}) {
  const [isTyping, setTyping] = React.useState(false);
  const timers = React.useRef([]);
  React.useEffect(() => () => timers.current.forEach(clearTimeout), []);

  const sendUser = React.useCallback((text) => {
    const t = (text||'').trim(); if (!t) return;
    const now = new Date().toTimeString().slice(0,5);
    const mineId = 'm_'+Date.now();
    setThread(list => [...list, { id:mineId, who:'me', time:now, text:t, status:'sent' }]);
    // mark read shortly
    timers.current.push(setTimeout(() => {
      setThread(list => list.map(x => x.id===mineId ? {...x, status:'read'} : x));
    }, 500));
    if (!enabled) return;
    // typing indicator + bot reply
    setTyping(true);
    timers.current.push(setTimeout(() => {
      const r = botReply(t);
      setTyping(false);
      if (!r) return;
      setThread(list => [...list, { who:'u_bot', time:new Date().toTimeString().slice(0,5), text:r }]);
    }, delay));
  }, [setThread, enabled, delay]);

  return { sendUser, isTyping };
}

// Хук для эмуляции звонка: { inCall, kind, elapsed, status, start(kind), end() }
// status: 'dialing' → 'connected' → 'ended'
function useCallState() {
  const [kind, setKind] = React.useState(null); // 'audio' | 'video' | null
  const [status, setStatus] = React.useState('idle');
  const [elapsed, setElapsed] = React.useState(0);
  const dialTimer = React.useRef(null);
  const tickTimer = React.useRef(null);

  const start = React.useCallback((k='audio') => {
    clearTimeout(dialTimer.current); clearInterval(tickTimer.current);
    setKind(k); setStatus('dialing'); setElapsed(0);
    dialTimer.current = setTimeout(() => {
      setStatus('connected');
      tickTimer.current = setInterval(() => setElapsed(e=>e+1), 1000);
    }, 2000);
  }, []);
  const end = React.useCallback(() => {
    clearTimeout(dialTimer.current); clearInterval(tickTimer.current);
    setStatus('ended');
    setTimeout(() => { setKind(null); setStatus('idle'); setElapsed(0); }, 800);
  }, []);
  React.useEffect(() => () => {
    clearTimeout(dialTimer.current); clearInterval(tickTimer.current);
  }, []);

  return { kind, status, elapsed, inCall: kind!==null && status!=='idle', start, end };
}

// Visual overlay for call (used inside chat views)
function CallOverlay({ call, peerName, compact=false }) {
  if (!call.kind) return null;
  const { status, elapsed, kind, end } = call;
  const mm = String(Math.floor(elapsed/60)).padStart(2,'0');
  const ss = String(elapsed%60).padStart(2,'0');
  const label = status==='dialing' ? 'Вызов…' : status==='connected' ? `${mm}:${ss}` : 'Завершено';
  return (
    <div style={{ position:'absolute', top: compact?46:58, left:'50%', transform:'translateX(-50%)',
      background:'var(--t-accent)', color:'#fff', padding:'6px 12px', borderRadius:999,
      display:'flex', gap:8, alignItems:'center', fontSize:12, zIndex:20,
      boxShadow:'var(--t-shadow-lg)' }}>
      <span style={{ width:7, height:7, borderRadius:'50%',
        background: status==='dialing'?'#FFD27A':'var(--t-ok)',
        animation:'pulse 1.2s infinite' }}/>
      <Icon name={kind==='video'?'video':'phone'} size={12}/>
      <span className="mono">{label}</span>
      <span>· {peerName}</span>
      <button onClick={end} style={{ background:'var(--t-danger)', color:'#fff',
        borderRadius:999, padding:'2px 8px', fontSize:11 }}>Завершить</button>
    </div>
  );
}

// Suggestion chips under the composer — clicks call onPick(text)
function BotHints({ onPick, compact=false }) {
  const [show, setShow] = React.useState(true);
  if (!show) return null;
  return (
    <div style={{ padding: compact?'4px 10px 2px':'4px 14px 2px',
      display:'flex', gap:6, overflowX:'auto', alignItems:'center',
      borderTop:'.5px solid var(--t-hairline-soft)' }}>
      <span style={{ fontSize:10, color:'var(--t-fg-tertiary)', textTransform:'uppercase',
        letterSpacing:'.08em', flexShrink:0 }}>Бот ·</span>
      {BOT_HINTS.slice(0, compact?4:7).map(h => (
        <button key={h} onClick={()=>onPick(h)} style={{
          background:'var(--t-accent-soft)', color:'var(--t-accent-fg)',
          border:'.5px solid var(--t-hairline-soft)',
          borderRadius:12, padding:'3px 9px', fontSize:11, whiteSpace:'nowrap', flexShrink:0 }}>{h}</button>
      ))}
      <button onClick={()=>setShow(false)} title="Скрыть"
        style={{ color:'var(--t-fg-tertiary)', padding:'0 4px', flexShrink:0 }}>
        <Icon name="x" size={11}/></button>
    </div>
  );
}

// Typing indicator bubble
function TypingBubble({ name='Бот' }) {
  return (
    <div style={{ alignSelf:'flex-start', display:'flex', flexDirection:'column', gap:2 }}>
      <div style={{ fontSize:11, color:'var(--t-fg-tertiary)', fontWeight:600, marginLeft:12 }}>{name}</div>
      <div style={{ background:'var(--t-bubble-them)', color:'var(--t-bubble-them-fg)',
        borderRadius:18, padding:'8px 14px', display:'inline-flex', gap:4 }}>
        {[0,1,2].map(i => (
          <span key={i} style={{ width:6, height:6, borderRadius:'50%',
            background:'var(--t-fg-tertiary)',
            animation:`typingDot 1.1s ${i*0.15}s infinite ease-in-out` }}/>
        ))}
      </div>
    </div>
  );
}

// Inject keyframes once
if (typeof document !== 'undefined' && !document.getElementById('vd-typing-keyframes')) {
  const s = document.createElement('style');
  s.id = 'vd-typing-keyframes';
  s.textContent = `
    @keyframes typingDot { 0%,80%,100% { transform: translateY(0); opacity:.35 }
      40% { transform: translateY(-3px); opacity: 1 } }
  `;
  document.head.appendChild(s);
}

Object.assign(window, { botReply, BOT_HINTS, useChatBot, useCallState, CallOverlay, BotHints, TypingBubble });
