// Setting.test.jsx
import React from 'react';
import { render, screen, waitFor, fireEvent } from '@testing-library/react';
import { MemoryRouter, useNavigate, useLocation } from 'react-router-dom';
import Setting from './Setting';
import { getUserInfo, updatePassword } from '../../api/personal';

// Mock API 调用
jest.mock('../../api/personal', () => ({
  getUserInfo: jest.fn(),
  updatePassword: jest.fn()
}));

// Mock react-router-dom hooks
jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useNavigate: jest.fn(),
  useLocation: jest.fn()
}));

describe('Setting Component', () => {
  const mockNavigate = jest.fn();
  const mockLocation = {
    pathname: '/personal/setting',
    state: { dashboardTab: 'settings' }
  };

  beforeEach(() => {
    useNavigate.mockReturnValue(mockNavigate);
    useLocation.mockReturnValue(mockLocation);
    
    // 重置所有 mock
    jest.clearAllMocks();
    
    // 设置默认 mock 返回值
    getUserInfo.mockResolvedValue({
      username: 'testuser',
      email: 'test@example.com'
    });
    
    updatePassword.mockResolvedValue({ success: true });
  });

  it('应该正确加载并显示用户信息', async () => {
    render(
      <MemoryRouter>
        <Setting />
      </MemoryRouter>
    );

    await waitFor(() => {
      expect(screen.getByText('个人设置')).toBeInTheDocument();
      expect(screen.getByText('账户信息')).toBeInTheDocument();
      expect(screen.getByText('用户名:')).toBeInTheDocument();
      expect(screen.getByText('testuser')).toBeInTheDocument();
      expect(screen.getByRole('heading', { name: '修改密码' })).toBeInTheDocument();
    });
  });

  it('应该处理密码修改表单提交', async () => {
    render(
      <MemoryRouter>
        <Setting />
      </MemoryRouter>
    );

    // 填写表单
    fireEvent.change(screen.getByLabelText('原密码:'), { 
      target: { value: 'oldpassword123' } 
    });
    fireEvent.change(screen.getByLabelText('新密码:'), { 
      target: { value: 'newpassword123' } 
    });
    fireEvent.change(screen.getByLabelText('确认新密码:'), { 
      target: { value: 'newpassword123' } 
    });
    
    // 提交表单
    fireEvent.click(screen.getByRole('button', { name: '修改密码' }));

    await waitFor(() => {
      expect(updatePassword).toHaveBeenCalledWith('oldpassword123', 'newpassword123');
      expect(screen.getByText('密码修改成功')).toBeInTheDocument();
    });
  });


  it('应该处理API错误', async () => {
    updatePassword.mockRejectedValue(new Error('原密码不正确'));

    render(
      <MemoryRouter>
        <Setting />
      </MemoryRouter>
    );

    // 填写表单
    fireEvent.change(screen.getByLabelText('原密码:'), { 
      target: { value: 'wrongpassword' } 
    });
    fireEvent.change(screen.getByLabelText('新密码:'), { 
      target: { value: 'newpassword123' } 
    });
    fireEvent.change(screen.getByLabelText('确认新密码:'), { 
      target: { value: 'newpassword123' } 
    });
    
    // 提交表单
    fireEvent.click(screen.getByRole('button', { name: '修改密码' }));

    await waitFor(() => {
      expect(screen.getByText('原密码不正确')).toBeInTheDocument();
    });
  });

  it('应该显示加载状态', async () => {
    // 延迟API响应以测试加载状态
    updatePassword.mockImplementation(() => new Promise(() => {}));

    render(
      <MemoryRouter>
        <Setting />
      </MemoryRouter>
    );

    // 填写表单
    fireEvent.change(screen.getByLabelText('原密码:'), { 
      target: { value: 'oldpassword123' } 
    });
    fireEvent.change(screen.getByLabelText('新密码:'), { 
      target: { value: 'newpassword123' } 
    });
    fireEvent.change(screen.getByLabelText('确认新密码:'), { 
      target: { value: 'newpassword123' } 
    });
    
    // 提交表单
    fireEvent.click(screen.getByRole('button', { name: '修改密码' }));
    
    // 检查加载状态
    expect(screen.getByText('处理中...')).toBeInTheDocument();
    expect(screen.getByRole('button', { name: '处理中...' })).toBeDisabled();
  });

  it('应该处理返回按钮点击', async () => {
    render(
      <MemoryRouter>
        <Setting />
      </MemoryRouter>
    );

    const backButton = screen.getByText(/← 返回个人中心/);
    fireEvent.click(backButton);
    
    expect(mockNavigate).toHaveBeenCalledWith('/personal', {
      state: {
        fromSubpage: true,
        dashboardTab: 'settings'
      },
      replace: true
    });
  });

  it('应该清空表单并显示成功消息', async () => {
    render(
      <MemoryRouter>
        <Setting />
      </MemoryRouter>
    );

    // 填写表单
    fireEvent.change(screen.getByLabelText('原密码:'), { 
      target: { value: 'oldpassword123' } 
    });
    fireEvent.change(screen.getByLabelText('新密码:'), { 
      target: { value: 'newpassword123' } 
    });
    fireEvent.change(screen.getByLabelText('确认新密码:'), { 
      target: { value: 'newpassword123' } 
    });
    
    // 提交表单
    fireEvent.click(screen.getByRole('button', { name: '修改密码' }));

    await waitFor(() => {
      // 检查表单是否清空
      expect(screen.getByLabelText('原密码:')).toHaveValue('');
      expect(screen.getByLabelText('新密码:')).toHaveValue('');
      expect(screen.getByLabelText('确认新密码:')).toHaveValue('');
      
      // 检查成功消息
      expect(screen.getByText('密码修改成功')).toBeInTheDocument();
    });
  });
});