import { describe, it, expect, beforeEach, vi } from 'vitest'

// docked.ts no longer imports $lib/apps (defaults are implicit: absent key
// = visible), so no mock is needed. Each test re-imports the module fresh
// (after clearing localStorage) so the module-scoped store starts from the
// cleared state every time — without this, the store's state leaks between
// tests since it's cached with the module instance.
import type * as Docked from './docked'

let mod: typeof Docked

beforeEach(async () => {
  localStorage.clear()
  vi.resetModules()
  mod = await import('./docked')
})

describe('docked visibility store', () => {
  it('defaults docked apps to visible', () => {
    expect(mod.isDockedVisible('mascot')).toBe(true)
    expect(mod.isDockedVisible('other-docked')).toBe(true)
  })

  it('treats unknown ids as visible (absent key = visible)', () => {
    expect(mod.isDockedVisible('nope')).toBe(true)
  })

  it('toggle flips visibility', () => {
    mod.toggleDocked('mascot')
    expect(mod.isDockedVisible('mascot')).toBe(false)
    mod.toggleDocked('mascot')
    expect(mod.isDockedVisible('mascot')).toBe(true)
  })

  it('persists to localStorage', () => {
    mod.toggleDocked('mascot')
    const raw = localStorage.getItem(mod.STORAGE_KEY)
    expect(raw).toBeTruthy()
    expect(JSON.parse(raw!).mascot).toBe(false)
  })

  it('merge over defaults so a newly-registered docked app is visible', async () => {
    // Simulate a persisted blob from before 'other-docked' existed.
    localStorage.setItem(mod.STORAGE_KEY, JSON.stringify({ mascot: false }))
    vi.resetModules()
    const fresh = await import('./docked')
    expect(fresh.isDockedVisible('mascot')).toBe(false)
    expect(fresh.isDockedVisible('other-docked')).toBe(true)
  })

  it('dockedVisibility store is subscribable', () => {
    let latest: Record<string, boolean> | undefined
    const unsub = mod.dockedVisibility.subscribe((v) => (latest = v))
    // Store starts empty — absent keys mean visible (isDockedVisible fallback).
    expect(latest).toEqual({})
    expect(mod.isDockedVisible('mascot')).toBe(true)
    mod.toggleDocked('mascot')
    expect(latest?.mascot).toBe(false)
    expect(mod.isDockedVisible('mascot')).toBe(false)
    unsub()
  })
})
