import { describe, it, expect, beforeEach, vi } from 'vitest'
import { createPinia, setActivePinia } from 'pinia'
import { useUi } from '../useUi' // Adjust path as necessary

// Mock localStorage
const localStorageMock = (() => {
  let store = {}
  return {
    getItem: vi.fn((key) => store[key] || null),
    setItem: vi.fn((key, value) => {
      store[key] = value.toString()
    }),
    clear: vi.fn(() => {
      store = {}
    }),
    removeItem: vi.fn((key) => {
      delete store[key]
    }),
  }
})()

// Define the storage key, matching the one in useUi.js
const APPEARANCE_STORAGE_KEY = 'appearanceSettings';

// Apply the mock to window.localStorage BEFORE store import or usage
vi.stubGlobal('localStorage', localStorageMock)

describe('useUi Store', () => {
  beforeEach(() => {
    setActivePinia(createPinia())
    localStorageMock.clear()
    localStorageMock.setItem.mockClear()
    localStorageMock.getItem.mockClear()
    // Ensure that when the store is initialized, it re-reads from the (mocked) localStorage
    // This is important because the store's state definition runs only once when imported.
    // For tests, we need to control this. Re-importing or using a factory for useUi might be needed
    // if the store is not re-evaluating its state function that calls loadSettingsFromLocalStorage().
    // However, Pinia's setup with setActivePinia(createPinia()) should handle store isolation.
  })

  it('initializes with default appearance settings if no local storage data exists', () => {
    const store = useUi()
    expect(store.primaryColor).toBe('#1976D2')
    expect(store.theme).toBe('light')
    expect(store.fontSize).toBe(16)
    // Check new accent color defaults
    expect(store.accentColorEmpleados).toBe('#2196F3')
    expect(store.accentColorTareas).toBe('#4CAF50')
    expect(store.accentColorPlanillas).toBe('#FF9800')
    expect(store.accentColorAsistencias).toBe('#E91E63')
    expect(store.accentColorConfiguracion).toBe('#607D8B')
    // Check new default view defaults
    expect(store.defaultViewEmpleados).toBe('table')
    expect(store.defaultViewTareas).toBe('table')
    expect(store.defaultViewPlanillas).toBe('table')
    expect(store.defaultViewAsistencias).toBe('table')
    expect(store.defaultViewConfiguracion).toBe('table')
    // Check other new defaults
    expect(store.tableBgColorEmpleados).toBe('#FFFFFF')
    expect(store.desktopNavbarPersistent).toBe(false)
    expect(localStorageMock.getItem).toHaveBeenCalledWith(APPEARANCE_STORAGE_KEY)
  })

  it('loads settings from localStorage if present', () => {
    const storedSettings = {
      primaryColor: '#FF0000',
      theme: 'dark',
      fontSize: 20,
      animationsEnabled: false,
      accentColorEmpleados: '#0000FF',
      accentColorTareas: '#00FF00',
      accentColorPlanillas: '#FFFF00',
      accentColorAsistencias: '#FF00FF',
      accentColorConfiguracion: '#112233',
      tableBgColorEmpleados: '#EEEEEE',
      tableBgColorTareas: '#DDDDDD',
      tableBgColorPlanillas: '#CCCCCC',
      tableBgColorAsistencias: '#BBBBBB',
      tableBgColorConfiguracion: '#AAAAAA',
      desktopNavbarPersistent: true,
      defaultViewEmpleados: 'card',
      defaultViewTareas: 'card',
      defaultViewPlanillas: 'card',
      defaultViewAsistencias: 'card',
      defaultViewConfiguracion: 'card',
    }
    localStorageMock.getItem.mockReturnValueOnce(JSON.stringify(storedSettings))

    const store = useUi()

    expect(localStorageMock.getItem).toHaveBeenCalledWith(APPEARANCE_STORAGE_KEY)
    expect(store.primaryColor).toBe('#FF0000')
    expect(store.theme).toBe('dark')
    expect(store.fontSize).toBe(20)
    expect(store.animationsEnabled).toBe(false)
    expect(store.accentColorEmpleados).toBe('#0000FF')
    expect(store.accentColorTareas).toBe('#00FF00')
    expect(store.accentColorPlanillas).toBe('#FFFF00')
    expect(store.accentColorAsistencias).toBe('#FF00FF')
    expect(store.accentColorConfiguracion).toBe('#112233')
    expect(store.tableBgColorEmpleados).toBe('#EEEEEE')
    expect(store.tableBgColorTareas).toBe('#DDDDDD')
    expect(store.tableBgColorPlanillas).toBe('#CCCCCC')
    expect(store.tableBgColorAsistencias).toBe('#BBBBBB')
    expect(store.tableBgColorConfiguracion).toBe('#AAAAAA')
    expect(store.desktopNavbarPersistent).toBe(true)
    expect(store.defaultViewEmpleados).toBe('card')
    expect(store.defaultViewTareas).toBe('card')
    expect(store.defaultViewPlanillas).toBe('card')
    expect(store.defaultViewAsistencias).toBe('card')
    expect(store.defaultViewConfiguracion).toBe('card')
  })

  it('loads older settings from localStorage and uses defaults for new settings if not present', () => {
    const olderStoredSettings = {
      primaryColor: '#ABCDEF',
      theme: 'dark',
      fontSize: 18,
    } // Does not include new accent colors
    localStorageMock.getItem.mockReturnValueOnce(JSON.stringify(olderStoredSettings))

    const store = useUi()

    expect(store.primaryColor).toBe('#ABCDEF')
    expect(store.theme).toBe('dark')
    expect(store.fontSize).toBe(18)
    // New accent colors should fall back to defaults
    expect(store.accentColorEmpleados).toBe('#2196F3') // Default
    expect(store.accentColorTareas).toBe('#4CAF50')     // Default
    expect(store.accentColorPlanillas).toBe('#FF9800')  // Default
    expect(store.accentColorAsistencias).toBe('#E91E63') // Default
    expect(store.accentColorConfiguracion).toBe('#607D8B') // Default
    // New default view keys should fall back to 'table'
    expect(store.defaultViewEmpleados).toBe('table')
    expect(store.defaultViewTareas).toBe('table')
    expect(store.defaultViewPlanillas).toBe('table')
    expect(store.defaultViewAsistencias).toBe('table')
    expect(store.defaultViewConfiguracion).toBe('table')
    // Other new keys
    expect(store.tableBgColorEmpleados).toBe('#FFFFFF') // Default
    expect(store.desktopNavbarPersistent).toBe(false) // Default
  })

  it('falls back to default settings if localStorage data is invalid JSON', () => {
    localStorageMock.getItem.mockReturnValueOnce('invalid json')
    const store = useUi()
    expect(store.primaryColor).toBe('#1976D2') // Default
  })

  it('falls back to default settings if localStorage is not available (simulated by load error)', () => {
    // Simulate localStorage.getItem throwing an error by making the mock throw
    localStorageMock.getItem.mockImplementationOnce(() => {
      throw new Error("Storage unavailable");
    });

    const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); // Suppress console.error for this test
    const store = useUi();

    expect(store.primaryColor).toBe('#1976D2'); // Should use default
    expect(store.theme).toBe('light');
    expect(console.error).toHaveBeenCalledWith('Error loading appearance settings from local storage:', expect.any(Error));

    consoleErrorSpy.mockRestore(); // Restore console.error
  })

  describe('Actions', () => {
    // Update this list to match the store's appearanceSettingKeys
    const appearanceSettingKeysInTest = [
      'primaryColor', 'secondaryColor', 'warningColor', 'fontFamily',
      'fontSize', 'animationsEnabled', 'backgroundColor', 'theme',
      'accentColorEmpleados', 'accentColorTareas', 'accentColorPlanillas',
      'accentColorAsistencias', 'accentColorConfiguracion',
      'tableBgColorEmpleados', 'tableBgColorTareas', 'tableBgColorPlanillas',
      'tableBgColorAsistencias', 'tableBgColorConfiguracion',
      'desktopNavbarPersistent',
      'defaultViewEmpleados', 'defaultViewTareas', 'defaultViewPlanillas',
      'defaultViewAsistencias', 'defaultViewConfiguracion',
    ];

    it('setPrimaryColor updates state and saves to localStorage', () => {
      const store = useUi()
      store.setPrimaryColor('#00FF00')
      expect(store.primaryColor).toBe('#00FF00')
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        APPEARANCE_STORAGE_KEY,
        expect.stringContaining('"primaryColor":"#00FF00"')
      )
    })

    it('setFontSize updates state and saves to localStorage', () => {
      const store = useUi()
      store.setFontSize(24)
      expect(store.fontSize).toBe(24)
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        APPEARANCE_STORAGE_KEY,
        expect.stringContaining('"fontSize":24')
      )
    })

    it('setAnimationsEnabled updates state and saves to localStorage', () => {
      const store = useUi()
      store.setAnimationsEnabled(false)
      expect(store.animationsEnabled).toBe(false)
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        APPEARANCE_STORAGE_KEY,
        expect.stringContaining('"animationsEnabled":false')
      )
      store.setAnimationsEnabled(true)
      expect(store.animationsEnabled).toBe(true)
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        APPEARANCE_STORAGE_KEY,
        expect.stringContaining('"animationsEnabled":true')
      )
    })

    it('setTheme updates state and saves to localStorage', () => {
      const store = useUi()
      store.setTheme('dark')
      expect(store.theme).toBe('dark')
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        APPEARANCE_STORAGE_KEY,
        expect.stringContaining('"theme":"dark"')
      )
    })

    it('toggleTheme switches theme and saves to localStorage', () => {
      const store = useUi() // default is 'light'
      store.toggleTheme()
      expect(store.theme).toBe('dark')
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        APPEARANCE_STORAGE_KEY,
        expect.stringContaining('"theme":"dark"')
      )
      store.toggleTheme()
      expect(store.theme).toBe('light')
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        APPEARANCE_STORAGE_KEY,
        expect.stringContaining('"theme":"light"')
      )
    })

    it('saves only appearance settings to localStorage', () => {
      const store = useUi()
      // Clear any previous calls from initialization if store was already used in this describe block
      localStorageMock.setItem.mockClear();

      store.setPrimaryColor('#ABCDEF') // This will trigger a save

      // Check if setItem was called
      expect(localStorageMock.setItem).toHaveBeenCalledTimes(1);
      expect(localStorageMock.setItem).toHaveBeenCalledWith(APPEARANCE_STORAGE_KEY, expect.any(String));

      // Now parse the actual saved data
      const savedDataString = localStorageMock.setItem.mock.calls[0][1];
      const savedData = JSON.parse(savedDataString);

      expect(Object.keys(savedData).length).toBe(appearanceSettingKeysInTest.length);
      expect(savedData.sidebarOpen).toBeUndefined() // Ensure non-appearance data is not saved
      appearanceSettingKeysInTest.forEach(key => {
        //This assertion needs to be robust if some keys are not initialized (e.g. undefined)
        //However, our store initializes all appearance keys
        expect(savedData.hasOwnProperty(key)).toBe(true);
      })
    })

    // Tests for new accent color actions
    it('setAccentColorEmpleados updates state and saves to localStorage', () => {
      const store = useUi()
      store.setAccentColorEmpleados('#FF1122')
      expect(store.accentColorEmpleados).toBe('#FF1122')
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        APPEARANCE_STORAGE_KEY,
        expect.stringContaining('"accentColorEmpleados":"#FF1122"')
      )
    })

    it('setAccentColorTareas updates state and saves to localStorage', () => {
      const store = useUi()
      store.setAccentColorTareas('#33FF44')
      expect(store.accentColorTareas).toBe('#33FF44')
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        APPEARANCE_STORAGE_KEY,
        expect.stringContaining('"accentColorTareas":"#33FF44"')
      )
    })

    it('setAccentColorPlanillas updates state and saves to localStorage', () => {
      const store = useUi()
      store.setAccentColorPlanillas('#5566FF')
      expect(store.accentColorPlanillas).toBe('#5566FF')
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        APPEARANCE_STORAGE_KEY,
        expect.stringContaining('"accentColorPlanillas":"#5566FF"')
      )
    })

    it('setAccentColorAsistencias updates state and saves to localStorage', () => {
      const store = useUi()
      store.setAccentColorAsistencias('#FF7788')
      expect(store.accentColorAsistencias).toBe('#FF7788')
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        APPEARANCE_STORAGE_KEY,
        expect.stringContaining('"accentColorAsistencias":"#FF7788"')
      )
    })

    it('setAccentColorConfiguracion updates state and saves to localStorage', () => {
      const store = useUi()
      store.setAccentColorConfiguracion('#99AABB')
      expect(store.accentColorConfiguracion).toBe('#99AABB')
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        APPEARANCE_STORAGE_KEY,
        expect.stringContaining('"accentColorConfiguracion":"#99AABB"')
      )
    })

    // Tests for table background color actions
    it('setTableBgColorEmpleados updates state and saves to localStorage', () => {
      const store = useUi()
      store.setTableBgColorEmpleados('#EEECCC')
      expect(store.tableBgColorEmpleados).toBe('#EEECCC')
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        APPEARANCE_STORAGE_KEY,
        expect.stringContaining('"tableBgColorEmpleados":"#EEECCC"')
      )
    })
    // Similar tests for Tareas, Planillas, Asistencias, Configuracion table bg colors...

    it('setDesktopNavbarPersistent updates state and saves to localStorage', () => {
      const store = useUi()
      store.setDesktopNavbarPersistent(true)
      expect(store.desktopNavbarPersistent).toBe(true)
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        APPEARANCE_STORAGE_KEY,
        expect.stringContaining('"desktopNavbarPersistent":true')
      )
      store.setDesktopNavbarPersistent(false)
      expect(store.desktopNavbarPersistent).toBe(false)
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        APPEARANCE_STORAGE_KEY,
        expect.stringContaining('"desktopNavbarPersistent":false')
      )
    })

    // Tests for new default view actions
    it('setDefaultViewEmpleados updates state and saves to localStorage', () => {
      const store = useUi()
      store.setDefaultViewEmpleados('card')
      expect(store.defaultViewEmpleados).toBe('card')
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        APPEARANCE_STORAGE_KEY,
        expect.stringContaining('"defaultViewEmpleados":"card"')
      )
      store.setDefaultViewEmpleados('table')
      expect(store.defaultViewEmpleados).toBe('table')
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        APPEARANCE_STORAGE_KEY,
        expect.stringContaining('"defaultViewEmpleados":"table"')
      )
    })

    it('setDefaultViewTareas updates state and saves to localStorage', () => {
      const store = useUi()
      store.setDefaultViewTareas('card')
      expect(store.defaultViewTareas).toBe('card')
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        APPEARANCE_STORAGE_KEY,
        expect.stringContaining('"defaultViewTareas":"card"')
      )
    })

    it('setDefaultViewPlanillas updates state and saves to localStorage', () => {
      const store = useUi()
      store.setDefaultViewPlanillas('card')
      expect(store.defaultViewPlanillas).toBe('card')
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        APPEARANCE_STORAGE_KEY,
        expect.stringContaining('"defaultViewPlanillas":"card"')
      )
    })

    it('setDefaultViewAsistencias updates state and saves to localStorage', () => {
      const store = useUi()
      store.setDefaultViewAsistencias('card')
      expect(store.defaultViewAsistencias).toBe('card')
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        APPEARANCE_STORAGE_KEY,
        expect.stringContaining('"defaultViewAsistencias":"card"')
      )
    })

    it('setDefaultViewConfiguracion updates state and saves to localStorage', () => {
      const store = useUi()
      store.setDefaultViewConfiguracion('card')
      expect(store.defaultViewConfiguracion).toBe('card')
      expect(localStorageMock.setItem).toHaveBeenCalledWith(
        APPEARANCE_STORAGE_KEY,
        expect.stringContaining('"defaultViewConfiguracion":"card"')
      )
    })
  })
})
