// 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();
    });
  });
});