const API_BASE = (import.meta.env.VITE_API_URL as string | undefined)?.replace(/\/$/, '') || '/api'

export function apiUrl(path: string): string {
  if (/^https?:\/\//.test(path)) return path
  return `${API_BASE}${path.startsWith('/') ? path : `/${path}`}`
}

export async function apiFetch(path: string, init: RequestInit = {}): Promise<Response> {
  const headers: Record<string, string> = {}
  if (init.body && typeof init.body === 'string') {
    headers['Content-Type'] = 'application/json'
  }
  return fetch(apiUrl(path), {
    credentials: 'include',
    ...init,
    headers: {
      ...headers,
      ...init.headers,
    },
  })
}

export async function getErrorMessage(response: Response, fallback: string): Promise<string> {
  try {
    const data = await response.json()
    return data?.error ?? data?.message ?? fallback
  } catch {
    try {
      const text = await response.text()
      return text || fallback
    } catch {
      return fallback
    }
  }
}

export async function apiJson<T>(path: string, init: RequestInit = {}): Promise<T> {
  const response = await apiFetch(path, init)
  if (!response.ok) {
    const errorData = await response.json().catch(() => ({}))
    throw new Error(errorData?.error || errorData?.message || 'Request failed')
  }
  return response.json()
}

// ==================== Types ====================

export interface User {
  id: number
  username: string
  email: string
  role: string
}

export interface LoginResponse {
  user: User
  session_id: string
}

export interface SyncJob {
  id: number
  job_type: string
  sync_direction: string
  status: string
  records_processed: number
  records_failed: number
  created_at: string
  started_at: string | null
  completed_at: string | null
}

export interface SyncStatus {
  is_running: boolean
  stats: {
    running: number
    completed_today: number
    failed_today: number
  }
}

export interface SyncJobsResponse {
  jobs: SyncJob[]
}

export interface Conflict {
  id: number
  sync_job_id: number
  entity_type: string
  entity_id: string
  resolution_status: string
  source_data: Record<string, unknown>
  conflict_details: Record<string, unknown>
}

export interface PricingConfig {
  id: number
  metric_type: string
  unit: string
  rate_per_unit: number
  is_active: boolean
}

export interface BillingRecord {
  id: number
  customer_id: number
  subscription_id: number
  period_start: string
  period_end: string
  calculated_amount: number
  currency: string
  status: string
  created_at: string
  sent_to_sap: boolean
}

export interface AlertThreshold {
  id: number
  name: string
  subscription_id?: number
  metric_type: string
  threshold_value: number
  comparison_operator: string
  action: string
  notification_channels: string[]
  is_active: boolean
  last_triggered?: string
}

export interface AlertHistoryItem {
  id: number
  threshold_id: number
  threshold_name: string
  actual_value: number
  triggered_at: string
  action_taken?: string
  notification_sent: boolean
}

export interface Webhook {
  id: number
  url: string
  name: string
  event_type?: string
  is_active: boolean
  created_at: string
}

export interface ScheduledSync {
  id: number
  name: string
  schedule_type: string
  schedule_config: Record<string, unknown>
  job_type: string
  sync_direction: string
  is_active: boolean
  last_run: string | null
  next_run: string | null
}

export interface SapConfig {
  host: string
  port: number
  company_db: string
  username: string
  password: string
  use_ssl: boolean
  timeout_seconds: number
}

export interface PleskConfig {
  host: string
  port: number
  username: string
  password: string
  api_key: string
  use_https: boolean
  verify_ssl: boolean
  two_factor_enabled: boolean
  two_factor_method: string
  two_factor_secret: string | null
  session_id: string | null
}

export interface TestConnectionResponse {
  success: boolean
  message?: string
  error?: string
  requires_2fa?: boolean
  session_id?: string
  method?: string
}

export interface MessageResponse {
  message: string
}

export interface ConfigResponse {
  config: Record<string, unknown>
}

// ==================== Auth API ====================

export async function login(username: string, password: string): Promise<LoginResponse> {
  return apiJson('/auth/login', {
    method: 'POST',
    body: JSON.stringify({ username, password }),
  })
}

export async function logout(): Promise<MessageResponse> {
  return apiJson('/auth/logout', { method: 'POST' })
}

export async function getCurrentUser(): Promise<User> {
  return apiJson('/auth/me')
}

export async function changePassword(currentPassword: string, newPassword: string): Promise<MessageResponse> {
  return apiJson('/auth/change-password', {
    method: 'POST',
    body: JSON.stringify({ current_password: currentPassword, new_password: newPassword }),
  })
}

// ==================== Config API ====================

export async function getConfig(): Promise<ConfigResponse> {
  return apiJson('/config')
}

export async function updateConfig(key: string, value: unknown): Promise<MessageResponse> {
  return apiJson('/config', {
    method: 'PUT',
    body: JSON.stringify({ key, value }),
  })
}

// ==================== Connection Tests ====================

export async function testSapConnection(config: SapConfig): Promise<TestConnectionResponse> {
  return apiJson('/sap/test', {
    method: 'POST',
    body: JSON.stringify(config),
  })
}

export async function testPleskConnection(config: PleskConfig): Promise<TestConnectionResponse> {
  return apiJson('/plesk/test', {
    method: 'POST',
    body: JSON.stringify(config),
  })
}

// ==================== Sync API ====================

export async function getSyncStatus(): Promise<SyncStatus> {
  return apiJson('/sync/status')
}

export async function startSync(form: { job_type: string; sync_direction: string }): Promise<MessageResponse> {
  return apiJson('/sync/start', {
    method: 'POST',
    body: JSON.stringify(form),
  })
}

export async function stopSync(): Promise<MessageResponse> {
  return apiJson('/sync/stop', { method: 'POST' })
}

export async function getSyncJobs(): Promise<SyncJobsResponse> {
  return apiJson('/sync/jobs')
}

export async function simulateSync(jobType: string, direction: string): Promise<SyncJobsResponse> {
  return apiJson('/sync/simulate', {
    method: 'POST',
    body: JSON.stringify({ job_type: jobType, sync_direction: direction }),
  })
}

export async function getConflicts(): Promise<Conflict[]> {
  return apiJson('/sync/conflicts')
}

// ==================== Billing API ====================

export async function getPricingConfig(): Promise<PricingConfig[]> {
  return apiJson('/pricing')
}

export async function createPricingConfig(config: Omit<PricingConfig, 'id'>): Promise<PricingConfig> {
  return apiJson('/pricing', {
    method: 'POST',
    body: JSON.stringify(config),
  })
}

export async function getBillingRecords(): Promise<BillingRecord[]> {
  return apiJson('/billing/records')
}

export async function generateInvoice(customerId: number, periodStart: string, periodEnd: string): Promise<MessageResponse> {
  return apiJson('/billing/generate', {
    method: 'POST',
    body: JSON.stringify({ customer_id: customerId, period_start: periodStart, period_end: periodEnd }),
  })
}

export async function sendInvoiceToSap(billingRecordId: number): Promise<MessageResponse> {
  return apiJson('/billing/send-to-sap', {
    method: 'POST',
    body: JSON.stringify({ id: billingRecordId }),
  })
}

// ==================== Alerts API ====================

export async function getThresholds(): Promise<AlertThreshold[]> {
  return apiJson('/alerts/thresholds')
}

export async function createThreshold(threshold: Omit<AlertThreshold, 'id'>): Promise<AlertThreshold> {
  return apiJson('/alerts/thresholds', {
    method: 'POST',
    body: JSON.stringify(threshold),
  })
}

export async function getAlertHistory(): Promise<AlertHistoryItem[]> {
  return apiJson('/alerts/history')
}

// ==================== Webhooks API ====================

export async function getWebhooks(): Promise<Webhook[]> {
  return apiJson('/webhooks')
}

export async function createWebhook(url: string, eventType: string): Promise<Webhook> {
  return apiJson('/webhooks', {
    method: 'POST',
    body: JSON.stringify({ url, event_type: eventType }),
  })
}

export async function deleteWebhook(id: number): Promise<void> {
  await apiFetch(`/webhooks/${id}`, { method: 'DELETE' })
}

// ==================== Schedules API ====================

export async function getScheduledSyncs(): Promise<ScheduledSync[]> {
  return apiJson('/schedules')
}

export async function createScheduledSync(config: Omit<ScheduledSync, 'id' | 'last_run' | 'next_run'>): Promise<MessageResponse> {
  return apiJson('/schedules', {
    method: 'POST',
    body: JSON.stringify(config),
  })
}
