// FILE: _St/IG_StYellow/test_ext_side_random_delay_schedule_v313.js | ROLE: v313 Side 랜덤 다운로드 지연·예약 랜덤분·숨김 다운로드 방식 회귀
const assert = require('assert');
const fs = require('fs');
const path = require('path');
const root = __dirname;
const side = fs.readFileSync(path.join(root, 'side.js'), 'utf8');
const html = fs.readFileSync(path.join(root, 'side.html'), 'utf8');

// v311 shuffle controls must survive later patches.
assert.ok(html.includes('id="igblue_account_queue_shuffle"'));
assert.ok(html.includes('id="igblue_auto_shuffle"'));
assert.ok(side.includes('IGBLUE/account_queue_shuffle_v311'));
assert.ok(side.includes('IGBLUE/account_queue_auto_shuffle_v311'));

// Thumbnail default changed from legacy 200 to 100, with one-time migration for legacy default.
assert.ok(side.includes('function teThumbWidthDefault() { return 100; }'));
assert.ok(side.includes('visual/thumb_min_width_default_v313'));
assert.ok(side.includes('old === 200'));

// General JPG save is removed; Cache8701 owns automatic thumbnails.
assert.ok(!html.includes('id="download_image_save"'));
assert.ok(!html.includes('<span>Image 저장</span>'));
assert.ok(side.includes('function teDownloadImageSave()'));
assert.ok(side.includes('return false;'));
assert.ok(side.includes('for (const kind of ["mp4"])'));
assert.ok(!side.includes('for (const kind of ["mp4", "jpg"])')); 

// Download delay = base + fresh 0..max random each time.
assert.ok(html.includes('id="download_random_delay_sec"'));
assert.ok(html.includes('value="5"'));
assert.ok(side.includes('function teDownloadRandomDelayMaxSec()'));
assert.ok(side.includes('Math.floor(Math.random() * (randomMax + 1))'));
assert.ok(side.includes('base + randomSec'));
assert.ok(side.includes('const delayPlan = teDownloadDelayPlan(2);'));
assert.ok(side.includes('const delayPlan = teDownloadDelayPlan(0);'));

// Mode 1/2 remain in DOM for future recovery but are hidden from the operator.
assert.ok(/data-mode-title="다운로드 방식 1 · 전체" hidden/.test(html));
assert.ok(/data-mode-title="다운로드 방식 2 · 필터 결과" hidden/.test(html));
assert.ok(html.includes('id="down_all_medias"'));
assert.ok(html.includes('id="down_filtered_medias"'));

// Each schedule slot has local random enable + editable realized minute offset.
for (const id of [1,2]) {
  assert.ok(html.includes(`id="igblue_auto8700_schedule${id}_random_enabled"`));
  assert.ok(html.includes(`id="igblue_auto8700_schedule${id}_random_min"`));
}
assert.ok(side.includes('IGBLUE_AUTO8700_SCHEDULE_RANDOM_V313'));
assert.ok(side.includes('Math.floor(Math.random() * 60)'));
assert.ok(side.includes('rerollScheduleRandoms("side_load")'));
assert.ok(side.includes('rerollAll("auto_complete")'));
assert.ok(side.includes('row.effective_time = addMinutesToTime(row.time, row.applied_random_min)'));
assert.ok(side.includes('schedule_effective_time:effectiveTime'));
assert.ok(side.includes('schedule_random_min:randomMin'));

console.log('test_ext_side_random_delay_schedule_v313: OK');
