import { renderHook, act, waitFor } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import { useSettingsForm } from './useSettingsForm';

describe('useSettingsForm', () => {
  it('loads settings from API on mount', async () => {
    const { result } = renderHook(() => useSettingsForm());

    expect(result.current.isLoading).toBe(true);

    await waitFor(() => {
      expect(result.current.isLoading).toBe(false);
    });

    expect(result.current.settings.debug_mode).toBe(false);
    expect(result.current.settings.email_notifications).toBe(true);
    expect(result.current.settings.log_retention).toBe(30);
  });

  it('tracks dirty state when a setting changes', async () => {
    const { result } = renderHook(() => useSettingsForm());

    await waitFor(() => {
      expect(result.current.isLoading).toBe(false);
    });

    expect(result.current.isDirty).toBe(false);

    act(() => {
      result.current.updateSetting('debug_mode', true);
    });

    expect(result.current.isDirty).toBe(true);
    expect(result.current.changedFields.has('debug_mode')).toBe(true);
  });

  it('discard resets to initial state', async () => {
    const { result } = renderHook(() => useSettingsForm());

    await waitFor(() => {
      expect(result.current.isLoading).toBe(false);
    });

    act(() => {
      result.current.updateSetting('debug_mode', true);
      result.current.updateSetting('max_retries', 5);
    });

    expect(result.current.isDirty).toBe(true);

    act(() => {
      result.current.discard();
    });

    expect(result.current.isDirty).toBe(false);
    expect(result.current.settings.debug_mode).toBe(false);
    expect(result.current.settings.max_retries).toBe(3);
  });

  it('save persists settings and resets dirty state', async () => {
    const { result } = renderHook(() => useSettingsForm());

    await waitFor(() => {
      expect(result.current.isLoading).toBe(false);
    });

    act(() => {
      result.current.updateSetting('debug_mode', true);
    });

    await act(async () => {
      await result.current.save();
    });

    expect(result.current.isDirty).toBe(false);
    expect(result.current.settings.debug_mode).toBe(true);
  });

  it('is not dirty when setting is changed back to initial value', async () => {
    const { result } = renderHook(() => useSettingsForm());

    await waitFor(() => {
      expect(result.current.isLoading).toBe(false);
    });

    act(() => {
      result.current.updateSetting('debug_mode', true);
    });

    expect(result.current.isDirty).toBe(true);

    act(() => {
      result.current.updateSetting('debug_mode', false);
    });

    expect(result.current.isDirty).toBe(false);
  });
});
