// Общие UI-компоненты

// ---------- расписание приёмов пищи ----------
// Ориентировочно по тому, что видно в 1С (Ужин 16:40 в скринах) и по типовому
// графику пищеблока. Если у заказчика свой график — поправим тут.
const MEAL_SCHEDULE = [
  { name: 'Буфет',      start: '06:30', end: '07:30' },
  { name: 'Завтрак',    start: '07:30', end: '09:00' },
  { name: 'Буфет зав',  start: '09:00', end: '10:30' },
  { name: 'Обед',       start: '11:00', end: '13:00' },
  { name: 'Буфет обед', start: '13:00', end: '14:30' },
  { name: 'Полдник',    start: '15:00', end: '16:00' },
  { name: 'Ужин',       start: '16:40', end: '18:00' },
  { name: 'Буфет ужин', start: '18:00', end: '19:00' },
];

function _toMin(hhmm) { const [h, m] = hhmm.split(':').map(Number); return h * 60 + m; }
function _fmtMin(m) {
  if (m < 0) return '0 мин';
  if (m < 60) return m + ' мин';
  const h = Math.floor(m / 60), r = m % 60;
  return r === 0 ? `${h} ч` : `${h} ч ${r} мин`;
}

// Принимает Date, возвращает { current, next, minutesToNext, phase }.
function getMealStatus(now) {
  const cur = now.getHours() * 60 + now.getMinutes();
  let current = null, next = null;
  for (const m of MEAL_SCHEDULE) {
    const s = _toMin(m.start), e = _toMin(m.end);
    if (cur >= s && cur < e) current = m;
    if (cur < s && !next) next = m;
  }
  const minutesToNext = next ? _toMin(next.start) - cur : null;
  return {
    current, next, minutesToNext,
    phase: current ? 'active' : (next ? 'before' : 'after'),
  };
}

// Hook: тикает раз в 30 секунд, чтобы UI обновлял часы и переход к след. приёму пищи.
function useNow() {
  const [now, setNow] = React.useState(() => new Date());
  React.useEffect(() => {
    const id = setInterval(() => setNow(new Date()), 30 * 1000);
    return () => clearInterval(id);
  }, []);
  return now;
}

// Компонент в шапке: «Сейчас: Обед · до 13:00» либо «До обеда: 47 мин».
function MealClock({ tone = 'light' }) {
  const now = useNow();
  const status = getMealStatus(now);
  const time = now.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' });

  let primary, secondary;
  if (status.phase === 'active') {
    primary = `Сейчас · ${status.current.name}`;
    secondary = `до ${status.current.end}`;
  } else if (status.phase === 'before') {
    primary = `До · ${status.next.name}`;
    secondary = _fmtMin(status.minutesToNext);
  } else {
    primary = 'Смена окончена';
    secondary = '';
  }

  const fg = tone === 'dark' ? '#fff' : '#111';
  const sub = tone === 'dark' ? '#bbb' : '#555';
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 16, fontFamily: 'inherit' }}>
      <div style={{ textAlign: 'right' }}>
        <div style={{ fontSize: 13, color: sub, fontWeight: 600 }}>{primary}</div>
        <div style={{ fontSize: 16, color: fg, fontWeight: 800 }}>{secondary}</div>
      </div>
      <div style={{
        padding: '8px 14px', background: '#111', color: '#fff',
        borderRadius: 10, fontSize: 22, fontWeight: 800, letterSpacing: 1,
        fontVariantNumeric: 'tabular-nums',
      }}>{time}</div>
    </div>
  );
}

// «Не обновлялось N мин» — для случаев, когда бэкенд недоступен.
function StaleBadge() {
  useKitchenStore();
  const now = useNow();
  const meta = window.KITCHEN_META;
  if (!meta || !meta.generatedAt) return null;
  const ageMin = Math.floor((now.getTime() - new Date(meta.generatedAt).getTime()) / 60000);
  if (ageMin < 5) return null; // свежее 5 мин — не пугаем
  const cached = meta.fromCache;
  return (
    <div style={{
      position: 'fixed', top: 12, left: '50%', transform: 'translateX(-50%)',
      background: ageMin > 30 ? '#B8420F' : '#7a5a0f',
      color: '#fff', padding: '6px 14px', borderRadius: 999,
      fontSize: 13, fontWeight: 700, zIndex: 9000,
      boxShadow: '0 4px 12px rgba(0,0,0,0.2)',
    }}>
      {cached ? '⚠ Кеш · ' : '⚠ '}Не обновлялось {ageMin} мин
    </div>
  );
}

const ROLE_COLORS = {
  cook:     { main: '#E85D1E', dark: '#B8420F', soft: '#FFE4D6', name: 'Повар' },
  store:    { main: '#1D6FBF', dark: '#134B82', soft: '#D6E7F8', name: 'Кладовщик' },
  packer:   { main: '#0E7C3A', dark: '#0A5A2A', soft: '#DCF4E5', name: 'Фасовщик' },
  kitchen:  { main: '#7A2DB8', dark: '#4E1781', soft: '#EEE0FA', name: 'Кухонный сотрудник' },
};

function RoleHeader({ color, title, subtitle, onBack, right }) {
  const c = ROLE_COLORS[color];
  return (
    <header style={{
      display: 'flex', alignItems: 'center', gap: 24,
      padding: '20px 32px',
      background: '#fff',
      borderBottom: `6px solid ${c.main}`,
      flexShrink: 0,
    }}>
      <button
        onClick={onBack}
        style={{
          display: 'flex', alignItems: 'center', gap: 10,
          padding: '14px 22px',
          background: c.soft, color: c.dark,
          border: `2px solid ${c.main}`, borderRadius: 12,
          fontSize: 18, fontWeight: 700, cursor: 'pointer',
          fontFamily: 'inherit',
        }}
      >
        <span style={{ fontSize: 22 }}>←</span> Сменить роль
      </button>
      <div style={{
        width: 56, height: 56, borderRadius: 14,
        background: c.main, color: 'white',
        display: 'grid', placeItems: 'center',
        fontSize: 28, fontWeight: 800,
      }}>{c.name[0]}</div>
      <div style={{ flex: 1 }}>
        {window.KITCHEN_BRANCH && (
          <div style={{ fontSize: 12, fontWeight: 700, letterSpacing: 1, color: '#888', textTransform: 'uppercase', marginBottom: 2 }}>
            Площадка · <span style={{ color: '#111' }}>{window.KITCHEN_BRANCH.name}</span>
          </div>
        )}
        <h1 style={{ margin: 0, fontSize: 32, fontWeight: 800, color: '#111' }}>{title}</h1>
        {subtitle && <div style={{ fontSize: 18, color: '#555', marginTop: 4 }}>{subtitle}</div>}
      </div>
      <MealClock />
      {right}
    </header>
  );
}

function Pill({ children, color = '#666', bg = '#eee', size = 'md' }) {
  const sizes = {
    sm: { fs: 13, pad: '3px 10px' },
    md: { fs: 15, pad: '5px 12px' },
    lg: { fs: 17, pad: '7px 16px' },
  };
  const s = sizes[size];
  return (
    <span style={{
      display: 'inline-block',
      padding: s.pad, fontSize: s.fs,
      background: bg, color, fontWeight: 600,
      borderRadius: 999, whiteSpace: 'nowrap',
    }}>{children}</span>
  );
}

// ---------- мигалка изменения ----------
// Кладётся на любой контейнер ячейки. Если highlight есть, рисует жёлтую
// рамку, фон и крошечный значок «было → стало» в углу.
function ChangeBadge({ highlight }) {
  if (!highlight) return null;
  return (
    <div style={{
      position: 'absolute', top: -10, right: -6,
      background: '#111', color: '#fff',
      padding: '3px 8px', borderRadius: 999,
      fontSize: 11, fontWeight: 800,
      boxShadow: '0 4px 10px rgba(0,0,0,0.25)',
      whiteSpace: 'nowrap', zIndex: 5,
    }}>
      {highlight.old} → {highlight.new}
    </div>
  );
}

// CSS для пульсации добавляем один раз глобально.
(function injectChangeStyles() {
  if (document.getElementById('__pishcheblok_change_styles')) return;
  const css = `
    @keyframes flashBg {
      0%   { background-color: #fff7c2; box-shadow: 0 0 0 3px #f5c400 inset; }
      70%  { background-color: #fffbe6; box-shadow: 0 0 0 2px #f5c40080 inset; }
      100% { background-color: transparent; box-shadow: none; }
    }
    .flash-cell { animation: flashBg 6s ease-out forwards; }
    @keyframes toastIn {
      from { opacity: 0; transform: translateX(40px); }
      to   { opacity: 1; transform: none; }
    }
  `;
  const tag = document.createElement('style');
  tag.id = '__pishcheblok_change_styles';
  tag.textContent = css;
  document.head.appendChild(tag);
})();

// ---------- стек тостов «было → стало» ----------
function ChangeToasts() {
  useKitchenStore();
  const toasts = (window.KITCHEN_STORE.toasts || []).slice(-4);
  if (!toasts.length) return null;
  return (
    <div style={{
      position: 'fixed', top: 90, right: 20,
      display: 'flex', flexDirection: 'column', gap: 10,
      zIndex: 8000, pointerEvents: 'none',
    }}>
      {toasts.map(t => (
        <div key={t.id} style={{
          minWidth: 280, maxWidth: 360,
          background: '#111', color: '#fff',
          borderLeft: '6px solid #f5c400',
          borderRadius: 12,
          padding: '12px 16px',
          boxShadow: '0 12px 32px rgba(0,0,0,0.25)',
          animation: 'toastIn 200ms ease-out',
        }}>
          <div style={{ fontSize: 12, fontWeight: 700, color: '#f5c400', textTransform: 'uppercase', letterSpacing: 1, marginBottom: 4 }}>
            ⚡ Обновление из 1С
          </div>
          <div style={{ fontSize: 14, color: '#ddd', marginBottom: 6 }}>{t.label}</div>
          <div style={{ fontSize: 16, fontWeight: 800 }}>
            <span style={{ color: '#888', textDecoration: 'line-through' }}>{t.old}</span>
            <span style={{ margin: '0 8px', color: '#f5c400' }}>→</span>
            <span style={{ color: '#fff' }}>{t.new}</span>
          </div>
        </div>
      ))}
    </div>
  );
}

// ---------- индикатор связи с бэкендом ----------
function ConnectionDot() {
  useKitchenStore();
  const ok = window.KITCHEN_STORE.connected;
  return (
    <div title={ok ? 'Связь с сервером' : 'Нет связи с сервером'} style={{
      position: 'fixed', top: 12, right: 14,
      display: 'flex', alignItems: 'center', gap: 6,
      padding: '4px 10px', borderRadius: 999,
      background: ok ? '#0E7C3A' : '#B8420F',
      color: '#fff', fontSize: 11, fontWeight: 700,
      zIndex: 9000, opacity: 0.85,
    }}>
      <span style={{ width: 8, height: 8, borderRadius: 999, background: '#fff' }}></span>
      {ok ? 'ONLINE' : 'OFFLINE'}
    </div>
  );
}

// ---------- dev-панель ----------
// Кнопка «эмулировать правку из 1С». Видна только на localhost и пока 1С нет.
// Когда подключим реальный источник — спрячем по DATA_SOURCE из meta.
function DevPanel() {
  useKitchenStore();
  const [busy, setBusy] = React.useState(false);
  const meta = window.KITCHEN_META || {};
  const branch = window.KITCHEN_BRANCH;
  const isMock = meta.source === 'mock';
  const onLocalhost = /^(localhost|127\.|192\.168\.)/.test(location.hostname);
  if (!isMock || !onLocalhost || !branch) return null;

  const fire = async (body) => {
    setBusy(true);
    try {
      const API = (window.PISHCHEBLOK_API || '') + '/api/v1';
      await fetch(API + '/mock/edit', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ branch: branch.id, ...body }),
      });
    } catch (e) { console.error(e); }
    finally { setBusy(false); }
  };

  // Берём первое блюдо текущего филиала и первый продукт — чтобы кнопки
  // работали и на филиалах, где нет «борща» или «картофеля».
  const data = window.KITCHEN_DATA || {};
  const firstDish = (data.cook && Object.values(data.cook.dishes || {}).flat()[0]) || null;
  const firstStoreGroup = data.storekeeper && data.storekeeper.groups[0];
  const firstStoreItem = firstStoreGroup && firstStoreGroup.items[0];

  return (
    <div style={{
      position: 'fixed', left: 16, bottom: 64,
      background: 'rgba(17,17,17,0.92)', color: '#fff',
      borderRadius: 12, padding: '10px 14px',
      fontSize: 12, fontWeight: 700,
      display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap',
      boxShadow: '0 8px 24px rgba(0,0,0,0.3)',
      zIndex: 9000, maxWidth: 'calc(100vw - 32px)',
    }}>
      <span style={{ color: '#f5c400', textTransform: 'uppercase', letterSpacing: 1, marginRight: 6 }}>
        DEV · {branch.name}
      </span>
      <button disabled={busy} onClick={() => fire({ type: 'random' })} style={devBtnStyle}>
        {busy ? '…' : '⚡ Случайная правка'}
      </button>
      {firstDish && (
        <button
          disabled={busy}
          onClick={() => fire({ type: 'cook_portions', dishId: firstDish.id, value: Math.floor(firstDish.portions * (0.5 + Math.random())) })}
          style={devBtnStyle}>
          Повар: {firstDish.name.split(' ').slice(0, 2).join(' ')}
        </button>
      )}
      {firstStoreItem && (
        <button
          disabled={busy}
          onClick={() => fire({ type: 'store_qty', groupId: firstStoreGroup.id, itemName: firstStoreItem.name, value: Math.floor(firstStoreItem.qty * (0.5 + Math.random())) })}
          style={devBtnStyle}>
          Кладовщик: {firstStoreItem.name.split(' ')[0]}
        </button>
      )}
    </div>
  );
}
const devBtnStyle = {
  background: '#fff', color: '#111',
  border: 'none', borderRadius: 8,
  padding: '6px 10px', fontSize: 12, fontWeight: 700,
  cursor: 'pointer', fontFamily: 'inherit',
};

Object.assign(window, {
  ROLE_COLORS, RoleHeader, Pill,
  ChangeBadge, ChangeToasts, ConnectionDot, DevPanel,
  MealClock, StaleBadge, useNow, getMealStatus, MEAL_SCHEDULE,
});
