import { describe, it, expect, beforeEach, vi } from 'vitest';
import { render, screen, fireEvent, act } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import { useInputBarStore } from '../../src/store/inputBar';

// Mock the auth store to prevent localStorage access issues at module load
vi.mock('../../src/store/auth', () => ({
  useAuthStore: Object.assign(
    (selector: (s: any) => any) => selector({
      user: null,
      isAuthenticated: false,
      isLoading: false,
      quota: null,
      logout: vi.fn(),
      initialize: vi.fn(),
    }),
    { getState: () => ({ initialize: vi.fn(), logout: vi.fn() }) }
  ),
}));

// We need to test that key components render and integrate correctly.
// Since CSS Modules are not fully resolved in jsdom, we focus on DOM structure and logic.

describe('PromptInput Component', () => {
  beforeEach(() => {
    useInputBarStore.getState().reset();
  });

  it('should render textarea with universal placeholder', async () => {
    const { PromptInput } = await import('../../src/components/PromptInput');
    render(<PromptInput />);
    const textarea = screen.getByPlaceholderText(/上传1-5张参考图/);
    expect(textarea).toBeInTheDocument();
  });

  it('should render textarea with keyframe placeholder after mode switch', async () => {
    useInputBarStore.getState().switchMode('keyframe');
    const { PromptInput } = await import('../../src/components/PromptInput');
    render(<PromptInput />);
    const textarea = screen.getByPlaceholderText(/输入描述，定义首帧到尾帧/);
    expect(textarea).toBeInTheDocument();
  });

  it('should update store on input', async () => {
    const { PromptInput } = await import('../../src/components/PromptInput');
    render(<PromptInput />);
    const textarea = screen.getByRole('textbox');
    fireEvent.change(textarea, { target: { value: 'test prompt' } });
    expect(useInputBarStore.getState().prompt).toBe('test prompt');
  });
});

describe('UniversalUpload Component', () => {
  beforeEach(() => {
    useInputBarStore.getState().reset();
  });

  it('should render trigger button when no files', async () => {
    const { UniversalUpload } = await import('../../src/components/UniversalUpload');
    render(<UniversalUpload />);
    expect(screen.getByText('参考内容')).toBeInTheDocument();
  });

  it('should render thumbnails when files are added', async () => {
    const file = new File(['mock'], 'test.jpg', { type: 'image/jpeg' });
    useInputBarStore.getState().addReferences([file]);

    const { UniversalUpload } = await import('../../src/components/UniversalUpload');
    render(<UniversalUpload />);
    // Should not show the trigger
    expect(screen.queryByText('参考内容')).not.toBeInTheDocument();
  });

  it('should have hidden file input with correct accept', async () => {
    const { UniversalUpload } = await import('../../src/components/UniversalUpload');
    const { container } = render(<UniversalUpload />);
    const input = container.querySelector('input[type="file"]') as HTMLInputElement;
    expect(input).toBeTruthy();
    expect(input.accept).toBe('image/*,video/*');
    expect(input.multiple).toBe(true);
  });
});

describe('KeyframeUpload Component', () => {
  beforeEach(() => {
    useInputBarStore.getState().reset();
    useInputBarStore.getState().switchMode('keyframe');
  });

  it('should render first and last frame triggers', async () => {
    const { KeyframeUpload } = await import('../../src/components/KeyframeUpload');
    render(<KeyframeUpload />);
    expect(screen.getByText('首帧')).toBeInTheDocument();
    expect(screen.getByText('尾帧')).toBeInTheDocument();
  });

  it('should have file inputs accepting only images', async () => {
    const { KeyframeUpload } = await import('../../src/components/KeyframeUpload');
    const { container } = render(<KeyframeUpload />);
    const inputs = container.querySelectorAll('input[type="file"]');
    expect(inputs).toHaveLength(2);
    inputs.forEach((input) => {
      expect((input as HTMLInputElement).accept).toBe('image/*');
    });
  });
});

describe('Dropdown Component', () => {
  it('should render trigger and not show menu initially', async () => {
    const { Dropdown } = await import('../../src/components/Dropdown');
    render(
      <Dropdown
        items={[
          { label: 'Option A', value: 'a' },
          { label: 'Option B', value: 'b' },
        ]}
        value="a"
        onSelect={vi.fn()}
        trigger={<button>Click me</button>}
      />
    );
    expect(screen.getByText('Click me')).toBeInTheDocument();
    expect(screen.getByText('Option A')).toBeInTheDocument();
    expect(screen.getByText('Option B')).toBeInTheDocument();
  });

  it('should call onSelect when item clicked', async () => {
    const onSelect = vi.fn();
    const { Dropdown } = await import('../../src/components/Dropdown');
    render(
      <Dropdown
        items={[
          { label: 'Option A', value: 'a' },
          { label: 'Option B', value: 'b' },
        ]}
        value="a"
        onSelect={onSelect}
        trigger={<button>Click me</button>}
      />
    );

    // Open dropdown
    fireEvent.click(screen.getByText('Click me'));
    // Select option B
    fireEvent.click(screen.getByText('Option B'));
    expect(onSelect).toHaveBeenCalledWith('b');
  });
});

describe('Toast Component', () => {
  it('should render and be controllable via showToast', async () => {
    const { Toast, showToast } = await import('../../src/components/Toast');
    render(<Toast />);

    act(() => {
      showToast('Test message');
    });

    expect(screen.getByText('Test message')).toBeInTheDocument();
  });
});

describe('Toolbar Component', () => {
  beforeEach(() => {
    useInputBarStore.getState().reset();
  });

  it('should render all toolbar buttons in universal mode', async () => {
    const { Toolbar } = await import('../../src/components/Toolbar');
    render(<Toolbar />);
    // These texts may appear in both trigger and dropdown items
    expect(screen.getAllByText('视频生成').length).toBeGreaterThanOrEqual(1);
    expect(screen.getAllByText('Seedance 2.0').length).toBeGreaterThanOrEqual(1);
    expect(screen.getAllByText('全能参考').length).toBeGreaterThanOrEqual(1);
    expect(screen.getAllByText('21:9').length).toBeGreaterThanOrEqual(1);
    expect(screen.getAllByText('15s').length).toBeGreaterThanOrEqual(1);
    expect(screen.getByText('@')).toBeInTheDocument();
  });

  it('should show auto-match and hide @ button in keyframe mode', async () => {
    useInputBarStore.getState().switchMode('keyframe');
    const { Toolbar } = await import('../../src/components/Toolbar');
    render(<Toolbar />);
    expect(screen.getByText('自动匹配')).toBeInTheDocument();
    expect(screen.getAllByText('首尾帧').length).toBeGreaterThanOrEqual(1);
    expect(screen.getAllByText('5s').length).toBeGreaterThanOrEqual(1);
    expect(screen.queryByText('@')).not.toBeInTheDocument();
  });

  it('should show credits section with +30', async () => {
    const { Toolbar } = await import('../../src/components/Toolbar');
    render(<Toolbar />);
    expect(screen.getByText('30')).toBeInTheDocument();
  });
});

describe('VideoGenerationPage Component', () => {
  beforeEach(() => {
    useInputBarStore.getState().reset();
  });

  it('should render the page with hint text and input bar', async () => {
    const { VideoGenerationPage } = await import('../../src/components/VideoGenerationPage');
    render(
      <MemoryRouter>
        <VideoGenerationPage />
      </MemoryRouter>
    );
    expect(screen.getByText('在下方输入提示词，开始创作 AI 视频')).toBeInTheDocument();
  });
});

describe('Sidebar Component', () => {
  it('should render navigation items', async () => {
    const { Sidebar } = await import('../../src/components/Sidebar');
    render(<Sidebar />);
    expect(screen.getByText('灵感')).toBeInTheDocument();
    expect(screen.getByText('生成')).toBeInTheDocument();
    expect(screen.getByText('资产')).toBeInTheDocument();
    expect(screen.getByText('画布')).toBeInTheDocument();
    expect(screen.getByText('API')).toBeInTheDocument();
  });
});
