export const name = 'DCS-отчёт: structured smoke + быстрый пользовательский фильтр';
export const tags = ['report', 'smoke'];
export const timeout = 90000;

export default async function({ navigateSection, openCommand, getFormState, getCommands, clickElement, selectValue, fillFields, readSpreadsheet, closeForm, wait, assert, step, log }) {

  await step('navigation: команда отчёта зарегистрирована в подсистеме Склад', async () => {
    const r = await navigateSection('Склад');
    const flat = (r.commands || []).flat();
    log(`commands: ${JSON.stringify(flat)}`);
    assert.ok(flat.includes('Остатки товаров'), 'В подсистеме Склад есть команда «Остатки товаров»');
  });

  await step('open: openCommand отрывает форму отчёта с кнопкой Сформировать', async () => {
    const s = await openCommand('Остатки товаров');
    log(`form=${s.form} formCount=${s.formCount} buttons=${s.buttons?.map(b => b.name).join(',')}`);
    assert.equal(s.formCount, 1, 'Открыта одна форма');
    const submit = s.buttons?.find(b => b.name === 'Сформировать');
    assert.ok(submit, 'Есть кнопка «Сформировать»');
    assert.equal(submit.default, true, '«Сформировать» — кнопка по умолчанию');
  });

  await step('reset: сброс пользовательских настроек к стандартным', async () => {
    // 1С хранит пользовательские настройки между сессиями — сбрасываем к дефолту,
    // чтобы тест был идемпотентным независимо от предыдущих прогонов.
    await clickElement('Еще');
    await clickElement('Установить стандартные настройки');
  });

  await step('quickAccess: быстрый фильтр Номенклатура виден и выключен по умолчанию', async () => {
    const s = await getFormState();
    log(`reportSettings: ${JSON.stringify(s.reportSettings)}`);
    assert.ok(Array.isArray(s.reportSettings) && s.reportSettings.length === 1, 'Один быстрый фильтр в reportSettings');
    const f = s.reportSettings[0];
    assert.equal(f.name, 'Номенклатура', 'Имя фильтра — заголовок DCS-поля');
    assert.equal(f.enabled, false, '@off — выключен по умолчанию');
    assert.equal(f.value, '', 'Значение пустое');
    assert.ok(Array.isArray(f.actions) && f.actions.includes('select'), 'Доступно действие select');
  });

  let baseRowCount = 0;
  let baseTotalSum = '';

  await step('generate: отчёт без фильтра возвращает все строки', async () => {
    await clickElement('Сформировать');
    await wait(3);
    const r = await readSpreadsheet();
    log(`headers=${JSON.stringify(r.headers)} total=${r.total} totals=${JSON.stringify(r.totals)}`);
    assert.deepEqual(r.headers, ['Номенклатура', 'Количество', 'Сумма'], 'Заголовки колонок отчёта');
    assert.ok(r.data?.length >= 2, 'В отчёте есть строки данных');
    assert.ok(r.totals?.['Сумма'], 'Есть итог по Сумме');
    baseRowCount = r.data.length;
    baseTotalSum = r.totals['Сумма'];
  });

  await step('apply filter: selectValue включает чекбокс и подставляет значение', async () => {
    const r = await selectValue('Номенклатура', 'Товар 02');
    log(`selected: ${JSON.stringify(r.selected)}`);
    assert.ok(r.selected, 'selectValue вернул объект selected');
    const after = await getFormState();
    const f = after.reportSettings?.[0];
    log(`after filter: ${JSON.stringify(f)}`);
    assert.equal(f.enabled, true, 'Чекбокс быстрого фильтра автоматически включился');
    assert.equal(f.value, 'Товар 02', 'Подставилось выбранное значение');
  });

  await step('regenerate: отчёт с фильтром возвращает только подходящие строки', async () => {
    await clickElement('Сформировать');
    await wait(3);
    const r = await readSpreadsheet();
    log(`filtered total=${r.total} rows=${r.data?.length} totals=${JSON.stringify(r.totals)}`);
    assert.ok(r.data.length < baseRowCount, `Строк меньше чем без фильтра (${r.data.length} < ${baseRowCount})`);
    const named = r.data.filter(row => row['Номенклатура']);
    assert.ok(named.length >= 1, 'Есть хотя бы одна именованная строка');
    assert.ok(named.every(row => row['Номенклатура'] === 'Товар 02'), 'Все именованные строки относятся к «Товар 02»');
    const sumKey = Object.keys(r.totals).find(k => k.includes('Сумма'));
    assert.ok(sumKey, 'В totals есть колонка Суммы (платформа дописывает контекст фильтра)');
    assert.notEqual(r.totals[sumKey], baseTotalSum, 'Итог по Сумме изменился после применения фильтра');
  });

  await step('clear filter: выключение чекбокса возвращает полный набор данных', async () => {
    // Снять быстрый фильтр через toggle off — fillFields с 'false' выключает чекбокс,
    // value сохраняется (платформа помнит последний выбор для повторного включения),
    // но данные при перерасчёте возвращаются к нефильтрованному набору.
    const r = await fillFields({ 'Номенклатура': 'false' });
    log(`toggle off: ${JSON.stringify(r.filled)}`);
    const after = await getFormState();
    assert.equal(after.reportSettings[0].enabled, false, 'Чекбокс выключен');

    await clickElement('Сформировать');
    await wait(3);
    const report = await readSpreadsheet();
    log(`after clear: rows=${report.data?.length} totals=${JSON.stringify(report.totals)}`);
    assert.equal(report.data.length, baseRowCount, 'Восстановилось исходное число строк');
    assert.equal(report.totals['Сумма'], baseTotalSum, 'Восстановился исходный итог по Сумме');
  });

  await step('drill-down: dblclick по ячейке Номенклатура открывает форму элемента', async () => {
    // Сформируем отчёт ещё раз для чистого состояния
    await clickElement('Сформировать');
    await wait(3);
    const r = await readSpreadsheet();
    const namedIdx = r.data.findIndex(row => row['Номенклатура']);
    log(`first row with Номенклатура: idx=${namedIdx} value=${r.data[namedIdx]?.['Номенклатура']}`);
    assert.ok(namedIdx >= 0, 'есть строка с заполненной Номенклатурой');

    const beforeForm = await getFormState();
    const clicked = await clickElement({ row: namedIdx, column: 'Номенклатура' }, { dblclick: true });
    log(`clicked: ${JSON.stringify(clicked.clicked)}`);
    assert.equal(clicked.clicked?.kind, 'spreadsheetCell', 'clicked.kind=spreadsheetCell');
    await wait(1);

    const after = await getFormState();
    log(`after drill: form=${after.form} buttons=${after.buttons?.map(b => b.name).join(',')}`);
    assert.notEqual(after.form, beforeForm.form, 'открыта новая форма (form изменился)');
    const hasItemButton = after.buttons?.some(b => b.name === 'Записать и закрыть' || b.name === 'Записать');
    assert.ok(hasItemButton, 'открыта форма элемента (есть «Записать»)');
    await closeForm();
  });

  await step('cleanup: закрываем форму отчёта', async () => {
    const r = await closeForm();
    log(`closed=${r.closed} formCount=${r.formCount}`);
    assert.equal(r.closed, true, 'Форма закрылась');
  });
}
