<?php

use PHPUnit\Framework\TestCase;
use SHServ\Models\Modes;

class ModesTest extends TestCase {

	protected $tb;

	protected function setUp(): void {
		$this -> tb = app() -> thin_builder;
		$this -> tb -> query("
			CREATE TABLE shserv_modes (
				tag VARCHAR(32) PRIMARY KEY,
				is_active TINYINT(1) NOT NULL DEFAULT 0,
				updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
			)
		");
	}

	protected function tearDown(): void {
		$this -> tb -> query("DROP TABLE IF EXISTS shserv_modes");
	}

	public function testSyncRegistryTagsCreatesRows() {
		$model = new Modes();
		$model -> sync_registry_tags();

		$definitions = \ControlScripts\ModesRegistry::definitions();
		$tags = array_keys($definitions);

		$rows = $this -> tb -> select('shserv_modes', [], []);
		$this -> assertCount(count($tags), $rows);

		foreach($rows as $row) {
			$this -> assertContains($row['tag'], $tags);
			$this -> assertEquals(0, $row['is_active']);
		}
	}

	public function testEnableAndDisable() {
		$model = new Modes();
		$model -> sync_registry_tags();

		$this -> assertFalse($model -> is_active('night'));

		$model -> enable('night');
		$this -> assertTrue($model -> is_active('night'));

		$model -> disable('night');
		$this -> assertFalse($model -> is_active('night'));
	}

	public function testAnyActive() {
		$model = new Modes();
		$model -> sync_registry_tags();

		$this -> assertFalse($model -> any_active(['night', 'sleep']));

		$model -> enable('sleep');
		$this -> assertTrue($model -> any_active(['night', 'sleep']));
		$this -> assertFalse($model -> any_active(['night', 'away']));
	}

	public function testAllActive() {
		$model = new Modes();
		$model -> sync_registry_tags();

		$this -> assertFalse($model -> all_active(['night', 'sleep']));

		$model -> enable('night');
		$this -> assertFalse($model -> all_active(['night', 'sleep']));

		$model -> enable('sleep');
		$this -> assertTrue($model -> all_active(['night', 'sleep']));
	}

	public function testActiveTags() {
		$model = new Modes();
		$model -> sync_registry_tags();

		$this -> assertEquals([], $model -> active_tags());

		$model -> enable('away');
		$model -> enable('sleep');

		$active = $model -> active_tags();
		$this -> assertCount(2, $active);
		$this -> assertContains('away', $active);
		$this -> assertContains('sleep', $active);
	}

	public function testListAllReturnsMeta() {
		$model = new Modes();
		$model -> sync_registry_tags();
		$model -> enable('night');

		$list = $model -> list_all();
		$night = array_values(array_filter($list, fn($m) => $m['tag'] === 'night'))[0];

		$this -> assertEquals('night', $night['tag']);
		$this -> assertEquals('Ночь', $night['label']);
		$this -> assertNotEmpty($night['description']);
		$this -> assertTrue($night['is_active']);
	}

	public function testModesContextToggle() {
		$model = new Modes();
		$model -> sync_registry_tags();

		$ctx = new \SHServ\Middleware\ModesContext();

		$this -> assertFalse($ctx -> is('movie'));

		$ctx -> toggle('movie');
		$this -> assertTrue($ctx -> is('movie'));

		$ctx -> toggle('movie');
		$this -> assertFalse($ctx -> is('movie'));
	}

	public function testModesContextMeta() {
		$ctx = new \SHServ\Middleware\ModesContext();

		$meta = $ctx -> meta('away');
		$this -> assertEquals('Не дома', $meta['label']);
		$this -> assertNotEmpty($meta['description']);
	}
}
