import { beforeEach, describe, expect, it } from 'vitest';
import { resetStore } from '../test/storeTestUtils';
import { useStore } from './useStore';

describe('useStore', () => {
  beforeEach(() => {
    resetStore();
  });

  it('stores and clears auth state with localStorage', () => {
    useStore.getState().login('token-1');

    expect(useStore.getState().isAuthenticated).toBe(true);
    expect(useStore.getState().token).toBe('token-1');
    expect(localStorage.getItem('token')).toBe('token-1');

    useStore.getState().logout();

    expect(useStore.getState().isAuthenticated).toBe(false);
    expect(useStore.getState().projects).toEqual([]);
    expect(useStore.getState().frames).toEqual([]);
    expect(localStorage.getItem('token')).toBeNull();
  });

  it('manages projects, frames, masks, annotations and templates', () => {
    const project = { id: '1', name: 'Project', status: 'ready' as const };
    useStore.getState().addProject(project);
    useStore.getState().updateProject({ ...project, name: 'Updated' });
    useStore.getState().setCurrentProject(project);
    useStore.getState().setFrames([{ id: 'f1', projectId: '1', index: 0, url: '/f1.jpg', width: 640, height: 360 }]);
    useStore.getState().setCurrentFrame(0);
    useStore.getState().addMask({ id: 'm1', frameId: 'f1', pathData: 'M 0 0 Z', label: 'mask', color: '#fff' });
    useStore.getState().setSelectedMaskIds(['m1']);
    useStore.getState().updateMask('m1', { label: 'updated mask', saveStatus: 'dirty' });
    useStore.getState().addAnnotation({ id: 'a1', frameId: 'f1', type: 'mask', points: [], label: 'ann', color: '#fff' });
    useStore.getState().addTemplate({ id: 't1', name: 'Template', classes: [], rules: [] });
    useStore.getState().updateTemplate({ id: 't1', name: 'Template 2', classes: [], rules: [] });
    useStore.getState().setActiveClass({ id: 'c1', name: '胆囊', color: '#ff0000', zIndex: 10 });

    expect(useStore.getState().projects[0].name).toBe('Updated');
    expect(useStore.getState().currentProject?.id).toBe('1');
    expect(useStore.getState().frames).toHaveLength(1);
    expect(useStore.getState().currentFrameIndex).toBe(0);
    expect(useStore.getState().selectedMaskIds).toEqual(['m1']);
    expect(useStore.getState().masks[0]).toEqual(expect.objectContaining({ label: 'updated mask', saveStatus: 'dirty' }));
    expect(useStore.getState().annotations).toHaveLength(1);
    expect(useStore.getState().templates[0].name).toBe('Template 2');
    expect(useStore.getState().activeClassId).toBe('c1');

    useStore.getState().removeAnnotation('a1');
    useStore.getState().clearMasks();
    useStore.getState().removeTemplate('t1');

    expect(useStore.getState().annotations).toEqual([]);
    expect(useStore.getState().masks).toEqual([]);
    expect(useStore.getState().selectedMaskIds).toEqual([]);
    expect(useStore.getState().templates).toEqual([]);
  });

  it('keeps undo and redo history for mask edits', () => {
    useStore.getState().addMask({ id: 'm1', frameId: 'f1', pathData: 'M 0 0 Z', label: 'mask 1', color: '#fff' });
    useStore.getState().addMask({ id: 'm2', frameId: 'f1', pathData: 'M 1 1 Z', label: 'mask 2', color: '#000' });

    expect(useStore.getState().masks.map((mask) => mask.id)).toEqual(['m1', 'm2']);
    useStore.getState().undoMasks();
    expect(useStore.getState().masks.map((mask) => mask.id)).toEqual(['m1']);
    useStore.getState().redoMasks();
    expect(useStore.getState().masks.map((mask) => mask.id)).toEqual(['m1', 'm2']);
  });
});
