import { describe, it, expect, beforeEach, vi } from 'vitest'
import { flushPromises, mount } from '@vue/test-utils'
import OpsSettingsDialog from '../OpsSettingsDialog.vue'

const mockGetAlertRuntimeSettings = vi.fn()
const mockGetEmailNotificationConfig = vi.fn()
const mockGetWebhookNotificationConfig = vi.fn()
const mockGetAdvancedSettings = vi.fn()
const mockGetMetricThresholds = vi.fn()

vi.mock('@/api/admin/ops', () => ({
  opsAPI: {
    getAlertRuntimeSettings: () => mockGetAlertRuntimeSettings(),
    getEmailNotificationConfig: () => mockGetEmailNotificationConfig(),
    getWebhookNotificationConfig: () => mockGetWebhookNotificationConfig(),
    getAdvancedSettings: () => mockGetAdvancedSettings(),
    getMetricThresholds: () => mockGetMetricThresholds(),
  },
}))

vi.mock('@/stores/app', () => ({
  useAppStore: () => ({
    showSuccess: vi.fn(),
    showError: vi.fn(),
  }),
}))

vi.mock('vue-i18n', async (importOriginal) => {
  const actual = await importOriginal<typeof import('vue-i18n')>()
  return {
    ...actual,
    useI18n: () => ({
      t: (key: string) => key,
    }),
  }
})

const defaultRuntimeSettings = {
  evaluation_interval_seconds: 300,
}

const defaultEmailConfig = {
  alert: {
    enabled: false,
    recipients: [],
    min_severity: 'critical',
  },
  report: {
    enabled: false,
    recipients: [],
    daily_summary_enabled: false,
    daily_summary_schedule: '',
    weekly_summary_enabled: false,
    weekly_summary_schedule: '',
  },
}

const defaultWebhookConfig = {
  alert: {
    enabled: false,
    urls: [],
    secret: '',
    min_severity: 'critical',
    timeout_seconds: 10,
    include_resolved: false,
    rate_limit_per_hour: 60,
  },
  report: {
    enabled: false,
    urls: [],
    secret: '',
    daily_enabled: false,
    daily_schedule: '0 9 * * *',
  },
}

const defaultAdvancedSettings = {
  data_retention: {
    cleanup_enabled: true,
    cleanup_schedule: '0 2 * * *',
    error_log_retention_days: 30,
    minute_metrics_retention_days: 7,
    hourly_metrics_retention_days: 90,
  },
  aggregation: {
    aggregation_enabled: true,
  },
  ignore_count_tokens_errors: true,
  ignore_context_canceled: true,
  ignore_no_available_accounts: false,
  ignore_invalid_api_key_errors: true,
  ignore_insufficient_balance_errors: true,
  auto_refresh_enabled: true,
  auto_refresh_interval_seconds: 30,
  display_alert_events: true,
  display_openai_token_stats: true,
}

const defaultMetricThresholds = {
  sla_percent_min: 99.5,
  ttft_p99_ms_max: 500,
  request_error_rate_percent_max: 5,
  upstream_error_rate_percent_max: 5,
}

describe('OpsSettingsDialog', () => {
  beforeEach(() => {
    vi.clearAllMocks()
    mockGetAlertRuntimeSettings.mockResolvedValue(defaultRuntimeSettings)
    mockGetEmailNotificationConfig.mockResolvedValue(defaultEmailConfig)
    mockGetWebhookNotificationConfig.mockResolvedValue(defaultWebhookConfig)
    mockGetAdvancedSettings.mockResolvedValue(defaultAdvancedSettings)
    mockGetMetricThresholds.mockResolvedValue(defaultMetricThresholds)
  })

  it('does not load settings when show is false', async () => {
    mount(OpsSettingsDialog, {
      props: { show: false },
      global: {
        stubs: {
          BaseDialog: {
            template: '<div v-if="show"><slot /></div>',
            props: ['show'],
          },
        },
      },
    })

    await flushPromises()

    expect(mockGetAlertRuntimeSettings).not.toHaveBeenCalled()
  })

  it('loads settings when show changes from false to true', async () => {
    const wrapper = mount(OpsSettingsDialog, {
      props: { show: false },
      global: {
        stubs: {
          BaseDialog: {
            template: '<div v-if="show"><slot /></div>',
            props: ['show'],
          },
        },
      },
    })

    await flushPromises()
    expect(mockGetAlertRuntimeSettings).not.toHaveBeenCalled()

    await wrapper.setProps({ show: true })
    await flushPromises()

    expect(mockGetAlertRuntimeSettings).toHaveBeenCalled()
    expect(mockGetWebhookNotificationConfig).toHaveBeenCalled()
  })

  it('handles API error on load gracefully', async () => {
    mockGetWebhookNotificationConfig.mockRejectedValue(new Error('Load failed'))

    const wrapper = mount(OpsSettingsDialog, {
      props: { show: true },
      global: {
        stubs: {
          BaseDialog: {
            template: '<div v-if="show"><slot /></div>',
            props: ['show'],
          },
        },
      },
    })

    // Wait for watch to trigger and API call to complete
    await flushPromises()
    await flushPromises()

    // Component should not crash
    expect(wrapper.exists()).toBe(true)
  })
})
