'use strict';

/**
 * ui/routes/entries.js — главная страница: список записей + CRUD.
 *
 * Данные из /api/v1/entries (Bearer token из сессии).
 * Admin: ?company=<id> (числовой PK) для управления конкретной компанией.
 *   - Без параметра: ищем компанию admin в списке по clientId.
 *     Если не найдена (первый вход) — один GET /api/v1/entries создаёт её,
 *     потом редирект на числовой ID.
 *   - С параметром: грузим записи этой компании через admin-ветку API.
 * User: без параметра, API сам определяет компанию по clientId из токена.
 */

const { Router } = require('express');
const api = require('../api-client');

function createRouter() {
  const router = Router();

  // URL для возврата после CRUD — всегда с числовым company ID
  function backUrl(req) {
    const id = req.query.company || (req.body && req.body.company_id);
    return id ? '/?company=' + id : '/';
  }

  // Суффикс ?company=<id> для API — только числовой ID или пусто
  function companyQuery(req) {
    const id = req.query.company || (req.body && req.body.company_id);
    if (id) return '?company=' + id;
    // Мульти-компания: передаём активный client_id
    if (!req.user.isAdmin && req.user.allClientIds && req.user.allClientIds.length > 1) {
      return '?client_id=' + encodeURIComponent(req.user.activeClientId || req.user.clientId);
    }
    return '';
  }

  // GET / — список записей
  router.get('/', async (req, res) => {
    const token = api.token(req);

    // ── Переключатель компании для мульти-компании ──────────────────────
    const switchTo = (req.query.switchTo || '').trim();
    if (!req.user.isAdmin && switchTo && req.user.allClientIds && req.user.allClientIds.includes(switchTo)) {
      req.session.user.activeClientId = switchTo;
      if (req.session.user.clientId) req.session.user.clientId = switchTo;
      // Синхронизируем req.user — resolveUser запустился ДО обработчика
      req.user.activeClientId = switchTo;
    }

    try {
      let entries = [], limit = 15, selectedCompany = null, companies = [];

      if (req.user.isAdmin) {
        const cr = await api.get('/api/v1/companies', token);
        companies = cr.data.companies || [];

        const companyId = req.query.company ? parseInt(req.query.company, 10) : null;

        if (!companyId) {
          let ownCo = companies.find(c => c.client_id === req.user.clientId) || null;
          if (!ownCo) {
            await api.get('/api/v1/entries', token);
            const cr2 = await api.get('/api/v1/companies', token);
            ownCo = (cr2.data.companies || []).find(c => c.client_id === req.user.clientId) || null;
          }
          return res.redirect('/?company=' + (ownCo ? ownCo.id : ''));
        }

        selectedCompany = companies.find(c => c.id === companyId) || null;
        if (selectedCompany) {
          const includeDeleted = req.query.includeDeleted === 'true' ? '&includeDeleted=true' : '';
          const er = await api.get('/api/v1/entries?company=' + companyId + includeDeleted, token);
          entries = er.data.entries || [];
          limit   = er.data.limit   || 15;
        }
      } else {
        // Обычный пользователь: запрашиваем записи для активной компании
        const activeClientId = req.user.activeClientId || req.user.clientId;
        const clientIdParam = req.user.allClientIds && req.user.allClientIds.length > 1
          ? '?client_id=' + encodeURIComponent(activeClientId)
          : '';
        const er = await api.get('/api/v1/entries' + clientIdParam, token);
        entries = er.data.entries || [];
        limit   = er.data.limit   || 15;
      }

      const hasMultiple = !req.user.isAdmin && req.user.allClientIds && req.user.allClientIds.length > 1;

      res.render('index', {
        entries,
        limit,
        used:            entries.length,
        user:            req.user,
        isAdmin:         req.user.isAdmin,
        companies,
        selectedCompany,
        allClientIds:    hasMultiple ? req.user.allClientIds : null,
        activeClientId:  req.user.activeClientId || req.user.clientId,
        error:           req.query.error   || null,
        success:         req.query.success || null,
        lastValue:       req.query.lastValue   || '',
        lastComment:     req.query.lastComment || '',
        includeDeleted:  req.query.includeDeleted === 'true',
        csrfToken:       '',
      });
    } catch (e) {
      res.render('index', {
        entries: [], limit: 15, used: 0,
        user: req.user, isAdmin: req.user.isAdmin,
        companies: [], selectedCompany: null,
        allClientIds: null, activeClientId: null,
        error: 'Ошибка загрузки: ' + e.message,
        success: null, lastValue: '', lastComment: '',
        includeDeleted: false, csrfToken: '',
      });
    }
  });

  // POST /add — создать запись
  router.post('/add', async (req, res) => {
    const token = api.token(req);
    const { value, comment } = req.body;
    const cq   = companyQuery(req);
    const back = backUrl(req);
    try {
      const r = await api.post('/api/v1/entries' + cq, token, { value, comment });
      if (r.status === 201) {
        const msg = r.data.wasNormalized
          ? 'Запись добавлена (CIDR нормализован до ' + r.data.entry.value_cidr + ')'
          : 'Запись добавлена';
        return res.redirect(back + (back.includes('?') ? '&' : '?') + 'success=' + encodeURIComponent(msg));
      }
      // Ошибка — возвращаем введённые значения чтобы не перепечатывать
      const err = (r.data && r.data.error) || 'Ошибка';
      res.redirect(back + (back.includes('?') ? '&' : '?') +
        'error=' + encodeURIComponent(err) +
        '&lastValue=' + encodeURIComponent(value || '') +
        '&lastComment=' + encodeURIComponent(comment || ''));
    } catch (e) {
      res.redirect(back + (back.includes('?') ? '&' : '?') + 'error=' + encodeURIComponent(e.message));
    }
  });

  // POST /edit/:id — обновить запись
  router.post('/edit/:id', async (req, res) => {
    const token = api.token(req);
    const { value, comment } = req.body;
    const cq   = companyQuery(req);
    const back = backUrl(req);
    try {
      const r = await api.patch('/api/v1/entries/' + req.params.id + cq, token, { value, comment });
      if (r.status === 200) {
        return res.redirect(back + (back.includes('?') ? '&' : '?') + 'success=' + encodeURIComponent('Запись обновлена'));
      }
      // Ошибка — возвращаем введённые значения в модалку
      const err = (r.data && r.data.error) || 'Ошибка';
      res.redirect(back + (back.includes('?') ? '&' : '?') +
        'error=' + encodeURIComponent(err) +
        '&lastValue=' + encodeURIComponent(value || '') +
        '&lastComment=' + encodeURIComponent(comment || ''));
    } catch (e) {
      res.redirect(back + (back.includes('?') ? '&' : '?') + 'error=' + encodeURIComponent(e.message));
    }
  });

  // POST /delete/:id — удалить запись
  router.post('/delete/:id', async (req, res) => {
    const token = api.token(req);
    const cq   = companyQuery(req);
    const back = backUrl(req);
    try {
      const r = await api.delete('/api/v1/entries/' + req.params.id + cq, token);
      if (r.status === 204) {
        return res.redirect(back + (back.includes('?') ? '&' : '?') + 'success=' + encodeURIComponent('Запись удалена'));
      }
      res.redirect(back + (back.includes('?') ? '&' : '?') + 'error=' + encodeURIComponent((r.data && r.data.error) || 'Ошибка'));
    } catch (e) {
      res.redirect(back + (back.includes('?') ? '&' : '?') + 'error=' + encodeURIComponent(e.message));
    }
  });

  return router;
}

module.exports = { createRouter };
