// #region TaskDrawerTests [C:3] [TYPE Module] [SEMANTICS task, drawer, store, test, resource]
// @BRIEF Unit tests for task drawer store validating open/close, preference-aware opening, resource task mapping, and status-driven cleanup.
// @RELATION DEPENDS_ON -> [EXT:frontend:taskDrawer]

import { describe, it, expect, beforeEach, vi } from 'vitest';
import { get } from 'svelte/store';
import {
  taskDrawerStore,
  openDrawerForTask,
  openDrawerForTaskIfPreferred,
  openDrawer,
  closeDrawer,
  updateResourceTask,
  setTaskDrawerAutoOpenPreference,
  getTaskDrawerAutoOpenPreference,
  getTaskForResource
} from '../taskDrawer.svelte.js';

describe('taskDrawerStore', () => {
  beforeEach(() => {
    setTaskDrawerAutoOpenPreference(true);
    taskDrawerStore.set({
      isOpen: false,
      activeTaskId: null,
      resourceTaskMap: {}
    });
  });

  it('should open drawer for a specific task', () => {
    openDrawerForTask('task-123');
    const state = get(taskDrawerStore);
    expect(state.isOpen).toBe(true);
    expect(state.activeTaskId).toBe('task-123');
  });

  it('should close drawer and clear active task', () => {
    openDrawerForTask('task-123');
    closeDrawer();
    const state = get(taskDrawerStore);
    expect(state.isOpen).toBe(false);
    expect(state.activeTaskId).toBe(null);
  });

  it('should open drawer via preference-aware helper when auto-open is enabled', () => {
    setTaskDrawerAutoOpenPreference(true);
    const opened = openDrawerForTaskIfPreferred('task-123');
    const state = get(taskDrawerStore);

    expect(opened).toBe(true);
    expect(state.isOpen).toBe(true);
    expect(state.activeTaskId).toBe('task-123');
  });

  it('should skip opening drawer via preference-aware helper when auto-open is disabled', () => {
    setTaskDrawerAutoOpenPreference(false);
    const opened = openDrawerForTaskIfPreferred('task-123');
    const state = get(taskDrawerStore);

    expect(opened).toBe(false);
    expect(state.isOpen).toBe(false);
    expect(state.activeTaskId).toBe(null);
  });

  it('should update resource task mapping for running task', () => {
    updateResourceTask('dash-1', 'task-1', 'RUNNING');
    const state = get(taskDrawerStore);
    expect(state.resourceTaskMap['dash-1']).toEqual({ taskId: 'task-1', status: 'RUNNING' });
  });

  it('should remove mapping when task completes (SUCCESS)', () => {
    updateResourceTask('dash-1', 'task-1', 'RUNNING');
    updateResourceTask('dash-1', 'task-1', 'SUCCESS');
    const state = get(taskDrawerStore);
    expect(state.resourceTaskMap['dash-1']).toBeUndefined();
  });

  it('should remove mapping when task fails (ERROR)', () => {
    updateResourceTask('dash-1', 'task-1', 'RUNNING');
    updateResourceTask('dash-1', 'task-1', 'ERROR');
    const state = get(taskDrawerStore);
    expect(state.resourceTaskMap['dash-1']).toBeUndefined();
  });

  it('should return false for empty taskId in openDrawerForTask', () => {
    const result = openDrawerForTask('');
    expect(result).toBe(false);
    const state = get(taskDrawerStore);
    expect(state.isOpen).toBe(false);
  });

  it('should return true when already open for same task', () => {
    openDrawerForTask('task-123');
    const result = openDrawerForTask('task-123');
    expect(result).toBe(true);
    const state = get(taskDrawerStore);
    expect(state.isOpen).toBe(true);
    expect(state.activeTaskId).toBe('task-123');
  });

  it('should be no-op calling closeDrawer when already closed', () => {
    // Already closed from beforeEach
    closeDrawer();
    const state = get(taskDrawerStore);
    expect(state.isOpen).toBe(false);
  });

  it('should open drawer in list mode (activeTaskId null)', () => {
    openDrawer();
    const state = get(taskDrawerStore);
    expect(state.isOpen).toBe(true);
    expect(state.activeTaskId).toBeNull();
  });

  it('should be no-op calling openDrawer when already open with null taskId', () => {
    openDrawer();
    openDrawer();
    const state = get(taskDrawerStore);
    expect(state.isOpen).toBe(true);
    expect(state.activeTaskId).toBeNull();
  });

  it('should remove resource task mapping on IDLE status', () => {
    updateResourceTask('dash-1', 'task-1', 'RUNNING');
    updateResourceTask('dash-1', 'task-1', 'IDLE');
    const state = get(taskDrawerStore);
    expect(state.resourceTaskMap['dash-1']).toBeUndefined();
  });

  it('should persist auto-open preference to localStorage', () => {
    setTaskDrawerAutoOpenPreference(false);
    expect(getTaskDrawerAutoOpenPreference()).toBe(false);

    setTaskDrawerAutoOpenPreference(true);
    expect(getTaskDrawerAutoOpenPreference()).toBe(true);
  });

  it('should get task info for specific resource', () => {
    updateResourceTask('dash-1', 'task-42', 'RUNNING');
    const taskInfo = getTaskForResource('dash-1');
    expect(taskInfo).toEqual({ taskId: 'task-42', status: 'RUNNING' });
  });

  it('should return null for resource without task', () => {
    const taskInfo = getTaskForResource('non-existent');
    expect(taskInfo).toBeNull();
  });

  // ── Additional edge cases ─────────────────────────────────────

  it('openDrawer with isOpen=true and activeTaskId=not-null should reopen with null taskId', () => {
    openDrawerForTask('task-123');
    expect(get(taskDrawerStore).activeTaskId).toBe('task-123');

    openDrawer(); // Opens in list mode (activeTaskId = null)
    const state = get(taskDrawerStore);
    expect(state.isOpen).toBe(true);
    expect(state.activeTaskId).toBeNull();
  });

  it('updateResourceTask with IDLE should remove mapping', () => {
    updateResourceTask('dash-1', 'task-1', 'RUNNING');
    updateResourceTask('dash-1', 'task-1', 'IDLE');
    const state = get(taskDrawerStore);
    expect(state.resourceTaskMap['dash-1']).toBeUndefined();
  });

  it('readAutoOpenTaskDrawerPreference should return true for missing key', async () => {
    localStorage.removeItem('ss_tools.profile.auto_open_task_drawer');
    // Re-import to trigger readAutoOpenTaskDrawerPreference
    vi.resetModules();
    const freshMod = await import('../taskDrawer.svelte.js');
    expect(freshMod.getTaskDrawerAutoOpenPreference()).toBe(true);
  });

  it('readAutoOpenTaskDrawerPreference should return false when key is "false"', async () => {
    localStorage.setItem('ss_tools.profile.auto_open_task_drawer', 'false');
    vi.resetModules();
    const freshMod = await import('../taskDrawer.svelte.js');
    expect(freshMod.getTaskDrawerAutoOpenPreference()).toBe(false);
  });

  it('setTaskDrawerAutoOpenPreference should write to localStorage when window is defined', () => {
    localStorage.removeItem('ss_tools.profile.auto_open_task_drawer');
    setTaskDrawerAutoOpenPreference(false);
    expect(localStorage.getItem('ss_tools.profile.auto_open_task_drawer')).toBe('false');
    setTaskDrawerAutoOpenPreference(true);
    expect(localStorage.getItem('ss_tools.profile.auto_open_task_drawer')).toBe('true');
  });

  it('should handle taskDrawerStore.set and .update', () => {
    taskDrawerStore.set({
      isOpen: true,
      activeTaskId: 'direct-set',
      resourceTaskMap: {},
    });
    let state = get(taskDrawerStore);
    expect(state.isOpen).toBe(true);
    expect(state.activeTaskId).toBe('direct-set');

    taskDrawerStore.update((s) => ({ ...s, activeTaskId: 'updated' }));
    state = get(taskDrawerStore);
    expect(state.activeTaskId).toBe('updated');
  });

  it('should return current value via .value getter', () => {
    const state = taskDrawerStore.value;
    expect(state.isOpen).toBe(false);
    expect(state.activeTaskId).toBeNull();
    expect(state.resourceTaskMap).toEqual({});
  });

  it('should handle subscribe correctly', () => {
    const received: unknown[] = [];
    const unsub = taskDrawerStore.subscribe((s) => received.push(s));
    expect(received.length).toBe(1); // Initial call
    openDrawer();
    expect(received.length).toBe(2);
    unsub();
    openDrawerForTask('should-not-fire');
    expect(received.length).toBe(2); // No new calls after unsubscribe
  });
});
// #endregion TaskDrawerTests
