﻿// AI Отдел — отделы (departments) + переключатель отделов.
// Loaded after components.jsx, before screens.jsx.
// Member.id = уникальный employee_id (в т.ч. для БД). Member.portrait = ключ портрета (elena/mark/…).

const DEPARTMENTS = [
  {
    id: 'marketing', name: 'Маркетинг', icon: 'mega', tint: '#3B82F6',
    tagline: 'Стратегия, бренд, контент',
    workingIds: ['elena', 'dmitry', 'igor', 'lyudmila'],
    members: [
      { id: 'elena',    name: 'Елена',    role: 'Менеджер',   short: 'руководит',  specialty: 'координация команды, постановка и распределение задач', phase: 'data',     live: 'Распределяю задачу по команде…',   title: 'Запуск нового продукта' },
      { id: 'mark',     name: 'Марк',     role: 'Ресёрчер',   short: 'ресёрч',     specialty: 'web research, сбор источников, факт-чекинг',           phase: 'data',     live: 'Собираю web research по нише…',     title: 'Ресёрч рынка и конкурентов' },
      { id: 'lyudmila', name: 'Людмила',  role: 'Маркетолог', short: 'ЦА и оффер', specialty: 'портреты ЦА, офферы, JTBD, value proposition',         phase: 'analysis', live: 'Собираю ЦА и оффер…',               title: 'Портрет ЦА и оффер' },
      { id: 'dmitry',   name: 'Дмитрий',  role: 'Аналитик',   short: 'KPI',        specialty: 'юнит-экономика, KPI, риски, метрики',                  phase: 'analysis', live: 'Считаю риски и KPI…',               title: 'Юнит-экономика и KPI' },
      { id: 'igor',     name: 'Игорь',    role: 'Бренд',      short: 'бренд',      specialty: 'позиционирование, tone of voice, айдентика',           phase: 'generate', live: 'Формирую позиционирование бренда…', title: 'Позиционирование и бренд' },
      { id: 'kostya',   name: 'Костя',    role: 'SMM',        short: 'контент',    specialty: 'контент-план, рубрики, форматы для соцсетей',          phase: 'generate', live: 'Собираю контент-план…',            title: 'Контент-план на месяц' },
      { id: 'alina',    name: 'Алина',    role: 'Креатив',    short: 'идеи',       specialty: 'креативные концепции, нейминг, слоганы',               phase: 'generate', live: 'Генерирую идеи и слоганы…',         title: 'Креативная концепция' },
      { id: 'oleg',     name: 'Олег',     role: 'Директор',   short: 'стратегия',  specialty: 'стратегия, финальная сборка, утверждение',             phase: 'review',   live: 'Собираю финальный документ…',       title: 'Финальная стратегия' },
    ],
  },
  {
    id: 'programmers', name: 'Программисты', icon: 'code', tint: '#7C6BF5',
    tagline: 'Бэкенд, фронтенд, моб. разработка',
    workingIds: ['dmitry', 'mark', 'kostya', 'igor'],
    members: [
      { id: 'dmitry',   name: 'Антон',  role: 'Тимлид',    short: 'спринт',    specialty: 'планирование, код-ревью, архитектура решений', phase: 'data',     live: 'Планирую спринт команды…',        title: 'Спринт #14' },
      { id: 'mark',     name: 'Сергей', role: 'Backend',   short: 'API',       specialty: 'API, базы данных, бизнес-логика',              phase: 'generate', live: 'Пишу API для модуля оплат…',      title: 'Backend: модуль оплат' },
      { id: 'kostya',   name: 'Денис',  role: 'Frontend',  short: 'интерфейс', specialty: 'React, вёрстка, управление состоянием',        phase: 'generate', live: 'Верстаю дашборд…',                title: 'Frontend: дашборд' },
      { id: 'igor',     name: 'Павел',  role: 'DevOps',    short: 'CI/CD',     specialty: 'CI/CD, инфраструктура, мониторинг',            phase: 'analysis', live: 'Настраиваю пайплайн деплоя…',     title: 'CI/CD пайплайн' },
      { id: 'alina',    name: 'Юля',    role: 'Mobile',    short: 'iOS/And',   specialty: 'мобильные приложения, нативная разработка',    phase: 'generate', live: 'Делаю экран профиля…',            title: 'Мобильное приложение' },
      { id: 'lyudmila', name: 'Вера',   role: 'Аналитик',  short: 'требования',specialty: 'требования, ТЗ, user stories',                 phase: 'data',     live: 'Собираю требования к модулю…',    title: 'ТЗ на новый модуль' },
      { id: 'elena',    name: 'Ольга',  role: 'QA-инженер',short: 'тесты',     specialty: 'автотесты, регресс, баг-репорты',              phase: 'review',   live: 'Пишу автотесты для релиза…',      title: 'Тестирование релиза' },
      { id: 'oleg',     name: 'Роман',  role: 'Архитектор',short: 'система',   specialty: 'проектирование систем, схемы БД',              phase: 'review',   live: 'Проектирую схему базы данных…',   title: 'Архитектура системы' },
    ],
  },
  {
    id: 'web', name: 'Веб-разработка', icon: 'globe', tint: '#14B8A6',
    tagline: 'Сайты, лендинги, дизайн',
    workingIds: ['elena', 'dmitry', 'lyudmila', 'mark'],
    members: [
      { id: 'elena',    name: 'Марина', role: 'Веб-лид',     short: 'проект',  specialty: 'ведение веб-проектов, координация',     phase: 'data',     live: 'Распределяю задачи по сайту…',  title: 'Лендинг под ключ' },
      { id: 'mark',     name: 'Глеб',   role: 'SEO',         short: 'SEO',     specialty: 'семантика, оптимизация, перелинковка',  phase: 'data',     live: 'Собираю семантическое ядро…',   title: 'SEO-оптимизация' },
      { id: 'lyudmila', name: 'Дарья',  role: 'UX/UI',       short: 'макеты',  specialty: 'макеты, прототипы, дизайн-система',      phase: 'generate', live: 'Рисую макеты страниц…',         title: 'Дизайн сайта' },
      { id: 'dmitry',   name: 'Никита', role: 'Верстальщик', short: 'вёрстка', specialty: 'HTML/CSS, адаптив, анимации',           phase: 'generate', live: 'Верстаю главную страницу…',     title: 'Вёрстка лендинга' },
      { id: 'igor',     name: 'Артём',  role: 'Backend',     short: 'сервер',  specialty: 'CMS, интеграции, формы, платежи',       phase: 'analysis', live: 'Подключаю CMS…',                title: 'Интеграция CMS' },
      { id: 'kostya',   name: 'Влад',   role: 'Контент',     short: 'контент', specialty: 'наполнение, тексты, медиа',             phase: 'generate', live: 'Наполняю страницы контентом…',  title: 'Контент сайта' },
      { id: 'alina',    name: 'Лера',   role: 'Графика',     short: 'графика', specialty: 'иллюстрации, баннеры, иконки',          phase: 'generate', live: 'Готовлю иллюстрации…',          title: 'Графика и баннеры' },
      { id: 'oleg',     name: 'Егор',   role: 'QA',          short: 'тесты',   specialty: 'кроссбраузерность, адаптив, баги',      phase: 'review',   live: 'Проверяю адаптив на устройствах…', title: 'Тестирование вёрстки' },
    ],
  },
  {
    id: 'assistant', name: 'Бизнес-аналитика', icon: 'briefcase', tint: '#E0962B',
    tagline: 'Поиск идей пассивного дохода',
    workingIds: ['viktor', 'tatyana', 'maksim'],
    members: [
      { id: 'svetlana', portrait: 'elena',    name: 'Светлана', role: 'Лид-аналитик',  short: 'синтез',   specialty: 'критерии поиска, ранжирование идей, финальный синтез',     phase: 'data',     live: 'Разбираю запрос и критерии…',     title: 'Подборка идей' },
      { id: 'viktor',   portrait: 'mark',     name: 'Виктор',   role: 'Аналитик рынка', short: 'рынок',   specialty: 'тренды Telegram, спрос, объём ниш, сезонность',            phase: 'data',     live: 'Анализирую тренды рынка…',        title: 'Карта трендов' },
      { id: 'tatyana',  portrait: 'lyudmila', name: 'Татьяна',  role: 'Скаут идей',     short: 'идеи',    specialty: 'генерация идей ботов и каналов под монетизацию',           phase: 'generate', live: 'Генерю идеи ботов и каналов…',    title: 'Список идей' },
      { id: 'aleksey',  portrait: 'dmitry',   name: 'Алексей',  role: 'Разведка',       short: 'конкуренты', specialty: 'конкуренты в нише, аудитория, оценка дохода, свободные углы', phase: 'analysis', live: 'Изучаю конкурентов в нише…',  title: 'Разведка ниши' },
      { id: 'maksim',   portrait: 'igor',     name: 'Максим',   role: 'Монетизация',    short: 'деньги',  specialty: 'модели заработка, юнит-экономика, срок окупаемости',       phase: 'analysis', live: 'Считаю юнит-экономику…',          title: 'Модель монетизации' },
      { id: 'nika',     portrait: 'alina',    name: 'Ника',     role: 'Трафик-стратег', short: 'трафик',  specialty: 'привлечение аудитории, посевы, контент-воронка',          phase: 'generate', live: 'Планирую набор аудитории…',       title: 'План трафика' },
    ],
  },
];

// ── helpers ───────────────────────────────────────────────────
function getDept(id) { return DEPARTMENTS.find(d => d.id === id) || DEPARTMENTS[0]; }

// #4 — живой спринт активен для текущего отдела? Привязка по отделу, в котором
// спринт был запущен (live.department). Legacy-спринт без поля считаем marketing.
function _liveSprint(deptId) {
  const live = (typeof window !== 'undefined') ? window.AI_LIVE : null;
  if (!live || live.status !== 'running' || !live.employees || !Object.keys(live.employees).length) return null;
  const liveDept = live.department || 'marketing';
  return liveDept === deptId ? live : null;
}

function buildTeam(deptId, mode) {
  const d = getDept(deptId);
  // #4 — если идёт спринт, карточки берут реальные статусы/прогресс из window.AI_LIVE
  const live = _liveSprint(deptId);
  if (live) {
    return d.members.map(m => {
      const e = live.employees[m.id];
      return {
        ...m,
        task: e ? { phase: m.phase, live: e.status || m.live, title: m.title,
                    livePct: (typeof e.progress === 'number') ? e.progress : undefined } : null,
      };
    });
  }
  let workingIds = [];
  if (mode === 'mixed') workingIds = d.workingIds;
  if (mode === 'busy')  workingIds = d.members.map(m => m.id);
  return d.members.map(m => ({
    ...m,
    task: workingIds.includes(m.id) ? { phase: m.phase, live: m.live, title: m.title } : null,
  }));
}

function getMember(deptId, empId) {
  const d = getDept(deptId);
  return d.members.find(m => m.id === empId) || d.members[0];
}
function getTask(deptId, empId) {
  const m = getMember(deptId, empId);
  const live = _liveSprint(deptId);
  if (live && live.employees[empId]) {
    const e = live.employees[empId];
    return { phase: m.phase, live: e.status || m.live, title: m.title,
             livePct: (typeof e.progress === 'number') ? e.progress : undefined };
  }
  return { phase: m.phase, live: m.live, title: m.title };
}
function isFem(name) { const c = name.trim().slice(-1); return c === 'а' || c === 'я'; }

const _TIMES = ['10:42', '10:35', '10:21', '09:55', '09:12'];
function getActivity(deptId) {
  const d = getDept(deptId);
  return d.members.slice(0, 3).map((m, i) => {
    const f = isFem(m.name);
    return {
      id: m.id, portrait: m.portrait || m.id, name: m.name,
      text: i === 0 ? `завершил${f ? 'а' : ''} «${m.title}»`
          : i === 1 ? m.live.replace(/[…\.]+$/, '').toLowerCase()
          : `приступил${f ? 'а' : ''} к задаче`,
      time: _TIMES[i],
      tag: i === 0 ? 'Готово' : i === 1 ? 'В работе' : null,
    };
  });
}
function getDone(deptId) {
  const d = getDept(deptId);
  return d.members.slice(-2).map((m, i) => ({ id: m.id, portrait: m.portrait || m.id, title: m.title, time: ['09:42', '08:18'][i] }));
}
function getNotifications(deptId) {
  const d = getDept(deptId);
  const whens = ['только что', '7 мин назад', '21 мин назад', 'час назад', '2 ч назад'];
  return d.members.slice(0, 5).map((m, i) => {
    const f = isFem(m.name);
    return {
      id: m.id, portrait: m.portrait || m.id, name: m.name,
      text: i % 2 ? m.live.replace(/[…\.]+$/, '').toLowerCase() : `завершил${f ? 'а' : ''} «${m.title}»`,
      tag: i === 0 ? 'Готово' : i === 1 ? 'Проверка' : null,
      unread: i < 2, when: whens[i],
    };
  });
}
function getThread(deptId, empId) {
  const m = getMember(deptId, empId);
  return [
    { from: 'them', t: `Привет! Я ${m.name}, ${m.role.toLowerCase()}. Беру на себя: ${m.specialty}.`, when: '10:30' },
    { from: 'me',   t: 'Отлично, приступай 👍', when: '10:31' },
    { from: 'them', t: m.live, when: '10:33' },
  ];
}

// ── Switcher UI ───────────────────────────────────────────────

// Title-area trigger shown on Home header
function DeptTrigger({ T, nav, style }) {
  const d = getDept(nav.dept);
  return (
    <div>
      <div style={{ fontSize: 12.5, color: T.mute, fontWeight: 500 }}>Доброе утро,</div>
      {style === 'sheet' ? (
        <Tap onClick={() => nav.openDeptSheet()}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 9, marginTop: 2 }}>
            <div style={{
              width: 30, height: 30, borderRadius: 9, flexShrink: 0,
              background: `${d.tint}1F`, display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}>{I[d.icon](d.tint)}</div>
            <h1 style={{ margin: 0, fontSize: 23, fontWeight: 800, letterSpacing: -0.7, color: T.ink, whiteSpace: 'nowrap' }}>{d.name}</h1>
            <div style={{
              width: 22, height: 22, borderRadius: 7, background: T.card,
              border: `1px solid ${T.line}`, display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}>{I.chevDown(T.mute)}</div>
          </div>
        </Tap>
      ) : (
        <h1 style={{ margin: '2px 0 0', fontSize: 24, fontWeight: 800, letterSpacing: -0.8, color: T.ink, whiteSpace: 'nowrap' }}>{d.name}</h1>
      )}
    </div>
  );
}

// Below-header strip for chips/tabs styles
function DeptStrip({ T, nav, style }) {
  if (style === 'sheet') return null;
  const active = nav.dept;

  if (style === 'chips') {
    return (
      <div className="phone-scroll" style={{
        display: 'flex', gap: 8, padding: '4px 16px 2px', overflowX: 'auto',
      }}>
        {DEPARTMENTS.map(d => {
          const on = d.id === active;
          return (
            <Tap key={d.id} onClick={() => nav.setDept(d.id)}>
              <div style={{
                display: 'flex', alignItems: 'center', gap: 6, whiteSpace: 'nowrap',
                padding: '7px 13px 7px 10px', borderRadius: 99,
                background: on ? d.tint : T.card,
                border: `1px solid ${on ? d.tint : T.line}`,
                boxShadow: on ? `0 8px 18px -10px ${d.tint}AA` : 'none',
              }}>
                {I[d.icon](on ? '#fff' : T.mute)}
                <span style={{ fontSize: 12.5, fontWeight: 700, color: on ? '#fff' : T.ink, letterSpacing: -0.1 }}>{d.name}</span>
              </div>
            </Tap>
          );
        })}
      </div>
    );
  }

  // tabs — underline indicator
  return (
    <div className="phone-scroll" style={{
      display: 'flex', gap: 18, padding: '8px 22px 0', overflowX: 'auto',
      borderBottom: `1px solid ${T.divider}`,
    }}>
      {DEPARTMENTS.map(d => {
        const on = d.id === active;
        return (
          <Tap key={d.id} onClick={() => nav.setDept(d.id)}>
            <div style={{
              display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6,
              paddingBottom: 8, whiteSpace: 'nowrap',
            }}>
              <span style={{
                fontSize: 13, fontWeight: on ? 800 : 600,
                color: on ? d.tint : T.mute, letterSpacing: -0.2,
              }}>{d.name}</span>
              <div style={{
                height: 3, width: '100%', borderRadius: 3,
                background: on ? d.tint : 'transparent',
              }} />
            </div>
          </Tap>
        );
      })}
    </div>
  );
}

// Bottom-sheet picker overlay (rendered at phone level)
function DeptSheet({ T, nav }) {
  if (!nav.deptSheetOpen) return null;
  return (
    <div style={{ position: 'absolute', inset: 0, zIndex: 120 }}>
      <div className="sheet-backdrop" onClick={() => nav.closeDeptSheet()} style={{
        position: 'absolute', inset: 0, background: 'rgba(8,6,20,0.42)',
      }} />
      <div className="dept-sheet" style={{
        position: 'absolute', left: 0, right: 0, bottom: 0,
        background: T.bg, borderRadius: '26px 26px 0 0',
        padding: '10px 14px 30px',
        boxShadow: '0 -20px 50px -10px rgba(0,0,0,0.4)',
      }}>
        <div style={{
          width: 40, height: 5, borderRadius: 99, background: T.divider,
          margin: '4px auto 14px',
        }} />
        <div style={{ fontSize: 12, fontWeight: 700, color: T.mute, letterSpacing: 0.4, textTransform: 'uppercase', padding: '0 4px 10px' }}>
          Переключить отдел
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          {DEPARTMENTS.map(d => {
            const on = d.id === nav.dept;
            const working = d.workingIds.length;
            return (
              <Tap key={d.id} onClick={() => { nav.setDept(d.id); nav.closeDeptSheet(); }}>
                <div style={{
                  display: 'flex', alignItems: 'center', gap: 12,
                  padding: 14, borderRadius: 16,
                  background: on ? `${d.tint}12` : T.card,
                  border: `1px solid ${on ? d.tint : T.line}`,
                }}>
                  <div style={{
                    width: 44, height: 44, borderRadius: 13, flexShrink: 0,
                    background: `${d.tint}1F`, display: 'flex', alignItems: 'center', justifyContent: 'center',
                  }}>{I[d.icon](d.tint)}</div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 15, fontWeight: 700, color: T.ink, letterSpacing: -0.2 }}>{d.name}</div>
                    <div style={{ fontSize: 11.5, color: T.mute, marginTop: 1 }}>{d.tagline}</div>
                    <div style={{ marginTop: 7, display: 'flex', alignItems: 'center', gap: 8 }}>
                      {/* mini avatar stack */}
                      <div style={{ display: 'flex' }}>
                        {d.members.slice(0, 4).map((m, i) => (
                          <div key={m.id} style={{
                            width: 20, height: 20, borderRadius: 20, overflow: 'hidden',
                            marginLeft: i ? -7 : 0, boxShadow: `0 0 0 1.5px ${on ? `${d.tint}12` : T.card}`,
                            background: T.portraitBg,
                          }}>
                            <img src={PORTRAIT[m.id]} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
                          </div>
                        ))}
                      </div>
                      <span style={{ fontSize: 10.5, color: d.tint, fontWeight: 700 }}>{working} в работе</span>
                      <span style={{ fontSize: 10.5, color: T.mute }}>· {d.members.length} в команде</span>
                    </div>
                  </div>
                  {on && (
                    <div style={{
                      width: 22, height: 22, borderRadius: 22, background: d.tint, flexShrink: 0,
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                    }}>
                      <svg width="12" height="12" viewBox="0 0 24 24" fill="none"><path d="M5 12l5 5L20 7" stroke="#fff" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"/></svg>
                    </div>
                  )}
                </div>
              </Tap>
            );
          })}
        </div>
      </div>
    </div>
  );
}


function ProjectsBottomSheet({ T, nav, currentSlug, onSelect, onClose }) {
  const [projects, setProjects] = React.useState([]);
  const [search, setSearch] = React.useState('');
  const [loading, setLoading] = React.useState(false);
  var [showCreate, setShowCreate] = React.useState(false);
  var [newName, setNewName] = React.useState('');
  var [creating, setCreating] = React.useState(false);
  var [delTarget, setDelTarget] = React.useState(null);
  var [deleting, setDeleting] = React.useState(false);

  function loadProjects() {
    if (!window.AI_API || !window.AI_API.getToken()) return;
    setLoading(true);
    window.AI_API.syncProjects().then(function(res) {
      if (res && Array.isArray(res)) {
        var list = res.map(function(p) { return { slug: p.slug, name: p.name }; });
        setProjects(list);
        var cur = list.find(function(p) { return p.slug === currentSlug; });
        if (cur) localStorage.setItem('ai_project_name', cur.name);
      }
    }).catch(function() {
      window.AI_API.getProjects().then(function(res) {
        if (res) {
          var list = res.map(function(p) { return { slug: p.slug, name: p.name }; });
          setProjects(list);
          var cur = list.find(function(p) { return p.slug === currentSlug; });
          if (cur) localStorage.setItem('ai_project_name', cur.name);
        }
      }).catch(function() {});
    }).finally(function() { setLoading(false); });
  }

  React.useEffect(function() { loadProjects(); }, []);

  function confirmDelete() {
    if (!delTarget || deleting) return;
    setDeleting(true);
    window.AI_API.deleteProject(delTarget.slug).then(function(res) {
      // drop from local list immediately; if it was the active project, switch away
      setProjects(function(list) { return list.filter(function(p) { return p.slug !== delTarget.slug; }); });
      if (delTarget.slug === currentSlug && res && typeof onSelect === 'function') {
        var nextSlug = (res && res.active_project_slug) || null;
        if (nextSlug) onSelect(nextSlug);
      }
      nav.toast('Проект «' + delTarget.name + '» удалён');
      setDelTarget(null);
    }).catch(function() {
      nav.toast('Не удалось удалить — попробуй снова');
    }).finally(function() { setDeleting(false); });
  }

  var filtered = projects.filter(function(p) {
    return !search || p.name.toLowerCase().indexOf(search.toLowerCase()) !== -1;
  });

  return (
    <React.Fragment>
      <div onClick={onClose} className="sheet-backdrop" style={{
        position: 'fixed', inset: 0, zIndex: 200,
        background: 'rgba(0,0,0,0.4)', backdropFilter: 'blur(4px)',
        WebkitBackdropFilter: 'blur(4px)',
      }} />
      <div className="dept-sheet" style={{
        position: 'fixed', bottom: 0, left: 0, right: 0, zIndex: 201,
        background: T.card, borderRadius: '20px 20px 0 0',
        padding: '0 0 40px', maxHeight: '75vh', display: 'flex', flexDirection: 'column',
      }}>
        <div style={{ display: 'flex', justifyContent: 'center', padding: '12px 0 4px' }}>
          <div style={{ width: 36, height: 4, borderRadius: 4, background: T.line }} />
        </div>
        <div style={{ padding: '8px 18px 12px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
          <div>
            <div style={{ fontSize: 18, fontWeight: 800, color: T.ink, letterSpacing: -0.5 }}>Проект</div>
            <div style={{ fontSize: 12, color: T.mute, marginTop: 2 }}>Контекст для всех отделов</div>
          </div>
          <Tap onClick={function() { setShowCreate(true); setNewName(''); }}>
            <div style={{
              display: 'flex', alignItems: 'center', gap: 5,
              padding: '7px 12px', borderRadius: 99,
              background: T.accent + '18', color: T.accent, fontSize: 13, fontWeight: 700,
            }}>
              <svg width="13" height="13" viewBox="0 0 24 24" fill="none">
                <path d="M12 5v14M5 12h14" stroke={T.accent} strokeWidth="2.2" strokeLinecap="round"/>
              </svg>
              Новый
            </div>
          </Tap>
        </div>
        <div style={{ padding: '0 14px 10px' }}>
          <input
            value={search}
            onChange={function(e) { setSearch(e.target.value); }}
            placeholder="Поиск проекта..."
            style={{
              width: '100%', boxSizing: 'border-box',
              padding: '10px 14px', borderRadius: 12,
              background: T.bg, border: '1px solid ' + T.line,
              fontSize: 14, color: T.ink, fontFamily: 'inherit', outline: 'none',
            }}
          />
        </div>
        <div style={{ flex: 1, overflowY: 'auto', padding: '0 14px' }}>
          {loading && <div style={{ textAlign: 'center', padding: 24, color: T.mute, fontSize: 13 }}>Загрузка...</div>}
          {!loading && filtered.length === 0 && <div style={{ textAlign: 'center', padding: 24, color: T.mute, fontSize: 13 }}>Нет проектов</div>}
          {filtered.map(function(p, i) {
            var active = p.slug === currentSlug || p.name.toLowerCase() === currentSlug;
            return (
              <Tap key={p.slug + i} onClick={function() { onSelect(p.slug); }}>
                <div style={{
                  display: 'flex', alignItems: 'center', gap: 12,
                  padding: '12px 8px',
                  borderBottom: i < filtered.length - 1 ? '1px solid ' + T.divider : 'none',
                }}>
                  <div style={{
                    width: 38, height: 38, borderRadius: 10, flexShrink: 0,
                    background: active ? T.accent + '20' : T.bg,
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                  }}>
                    <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
                      <path d="M3 7a2 2 0 012-2h4l2 2h8a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V7z" stroke={active ? T.accent : T.mute} strokeWidth="1.7" strokeLinecap="round"/>
                    </svg>
                  </div>
                  <div style={{ flex: 1 }}>
                    <div style={{ fontSize: 15, fontWeight: 700, color: T.ink }}>{p.name}</div>
                    <div style={{ fontSize: 12, color: T.mute, marginTop: 1 }}>{p.slug}</div>
                  </div>
                  <div
                    onClick={function(e) { e.stopPropagation(); setDelTarget(p); }}
                    style={{
                      width: 32, height: 32, borderRadius: 9, flexShrink: 0, marginRight: 2,
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                    }}>
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
                      <path d="M4 7h16M9 7V5a1 1 0 011-1h4a1 1 0 011 1v2m-9 0v12a2 2 0 002 2h6a2 2 0 002-2V7M10 11v6M14 11v6" stroke={T.mute} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
                    </svg>
                  </div>
                  {active && (
                    <div style={{
                      width: 24, height: 24, borderRadius: 24, background: T.accent,
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                    }}>
                      <svg width="13" height="13" viewBox="0 0 24 24" fill="none">
                        <path d="M5 13l4 4L19 7" stroke="#fff" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/>
                      </svg>
                    </div>
                  )}
                </div>
              </Tap>
            );
          })}
        </div>
      </div>
      {showCreate && (
        <div onClick={function() { if (!creating) setShowCreate(false); }} style={{
          position: 'fixed', inset: 0, zIndex: 300,
          background: 'rgba(0,0,0,0.5)', backdropFilter: 'blur(8px)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          padding: '0 24px',
        }}>
          <div onClick={function(e) { e.stopPropagation(); }} style={{
            background: T.card, borderRadius: 20, padding: '24px 20px',
            width: '100%', maxWidth: 340,
          }}>
            <div style={{ fontSize: 18, fontWeight: 800, color: T.ink, marginBottom: 16 }}>Новый проект</div>
            <input
              value={newName}
              onChange={function(e) { setNewName(e.target.value); }}
              placeholder="Название проекта..."
              autoFocus
              style={{
                width: '100%', boxSizing: 'border-box',
                padding: '12px 14px', borderRadius: 12,
                background: T.bg, border: '1px solid ' + T.line,
                fontSize: 15, color: T.ink, fontFamily: 'inherit', outline: 'none',
                marginBottom: 8,
              }}
            />
            <div style={{ fontSize: 11, color: T.mute, marginBottom: 16 }}>
              Создаст папку на GDrive с подпапками и файлами
            </div>
            <Tap onClick={function() {
              if (!newName.trim() || creating || !window.AI_API || !window.AI_API.getToken()) return;
              setCreating(true);
              window.AI_API.createProject(newName.trim()).then(function(res) {
                setCreating(false);
                setShowCreate(false);
                onClose();
                onSelect(res.slug, res.name);
                nav.toast('Проект "' + res.name + '" создан! 🎉');
              }).catch(function(err) {
                setCreating(false);
                var msg = err && err.status === 409
                  ? 'Проект с таким именем уже существует'
                  : 'Ошибка создания — попробуй снова';
                nav.toast(msg);
              });
            }}>
              <div style={{
                background: newName.trim() && !creating ? T.accent : T.line,
                borderRadius: 12, padding: '13px',
                textAlign: 'center', fontSize: 15, fontWeight: 700,
                color: newName.trim() && !creating ? '#fff' : T.mute,
              }}>{creating ? 'Создаю...' : 'Создать'}</div>
            </Tap>
            {!creating && (
              <Tap onClick={function() { setShowCreate(false); }}>
                <div style={{ textAlign: 'center', marginTop: 12, color: T.mute, fontSize: 14 }}>Отмена</div>
              </Tap>
            )}
          </div>
        </div>
      )}
      {delTarget && (
        <div onClick={function() { if (!deleting) setDelTarget(null); }} style={{
          position: 'fixed', inset: 0, zIndex: 300,
          background: 'rgba(0,0,0,0.5)', backdropFilter: 'blur(8px)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          padding: '0 24px',
        }}>
          <div onClick={function(e) { e.stopPropagation(); }} style={{
            background: T.card, borderRadius: 20, padding: '24px 20px',
            width: '100%', maxWidth: 340,
          }}>
            <div style={{ fontSize: 18, fontWeight: 800, color: T.ink, marginBottom: 10 }}>Удалить проект?</div>
            <div style={{ fontSize: 14, color: T.ink, marginBottom: 6 }}>
              «{delTarget.name}»
            </div>
            <div style={{ fontSize: 12, color: T.mute, marginBottom: 18, lineHeight: 1.4 }}>
              Папка уйдёт в Корзину Google Drive (можно вернуть ~30 дней), а чаты и спринты проекта в приложении удалятся.
            </div>
            <Tap onClick={confirmDelete}>
              <div style={{
                background: deleting ? T.line : '#E5484D',
                borderRadius: 12, padding: '13px',
                textAlign: 'center', fontSize: 15, fontWeight: 700,
                color: deleting ? T.mute : '#fff',
              }}>{deleting ? 'Удаляю...' : 'Удалить'}</div>
            </Tap>
            {!deleting && (
              <Tap onClick={function() { setDelTarget(null); }}>
                <div style={{ textAlign: 'center', marginTop: 12, color: T.mute, fontSize: 14 }}>Отмена</div>
              </Tap>
            )}
          </div>
        </div>
      )}
    </React.Fragment>
  );
}

Object.assign(window, {
  DEPARTMENTS, getDept, buildTeam, getMember, getTask,
  getActivity, getDone, getNotifications, getThread,
  DeptTrigger, DeptStrip, DeptSheet, ProjectsBottomSheet,
});
