import { getApiJwt } from './appwrite'

/**
 * Endpoints in this file are paths like `/subscription/status`.
 * Express mounts the API under `/api`, so the base must end with `/api`.
 * If VITE_API_URL is `http://localhost:3000` (missing /api), requests would 404.
 */
function resolveApiBase(): string {
  const raw = (import.meta.env.VITE_API_URL as string | undefined)?.trim()
  if (!raw) return '/api'

  if (raw.startsWith('/')) {
    const p = raw.replace(/\/+$/, '') || '/api'
    return p
  }

  if (!/^https?:\/\//i.test(raw)) {
    const p = raw.replace(/^\/+/, '').replace(/\/+$/, '') || 'api'
    return p.startsWith('api') ? `/${p}` : `/api`
  }

  const normalized = raw.replace(/\/+$/, '')
  try {
    const u = new URL(normalized)
    const path = u.pathname.replace(/\/$/, '') || '/'
    // Same host as Vite + /v1 = Appwrite-Proxy; never append /api (would hit /v1/api/… → 404)
    const localVite =
      /^(localhost|127\.0\.0\.1)$/i.test(u.hostname) &&
      (u.port === '5173' || (u.port === '' && u.hostname === 'localhost'))
    if (path === '/v1' && localVite) {
      return '/api'
    }
    if (path === '/' || path === '') {
      return `${normalized}/api`
    }
    if (path.endsWith('/api')) {
      return normalized
    }
    return `${normalized}/api`
  } catch {
    return '/api'
  }
}

const API_BASE = resolveApiBase()

/** Root-relative or absolute API URL; avoids `api/foo` (relative to current route). */
function joinApiUrl(base: string, endpoint: string): string {
  const ep = endpoint.startsWith('/') ? endpoint : `/${endpoint}`
  if (/^https?:\/\//i.test(base)) {
    return `${base.replace(/\/+$/, '')}${ep}`
  }
  let b = base.trim()
  if (!b.startsWith('/')) {
    b = `/${b.replace(/^\/+/, '')}`
  }
  b = b.replace(/\/+$/, '') || '/api'
  return `${b}${ep}`
}

interface ApiResponse<T> {
  success?: boolean
  data?: T
  error?: {
    code: string
    message: string
    fields?: Record<string, string[]>
    limit?: number
    used?: number
  }
}

async function fetchApi<T>(
  endpoint: string,
  options?: RequestInit
): Promise<ApiResponse<T>> {
  try {
    const headers: Record<string, string> = {
      ...(options?.headers as Record<string, string>),
    }
    if (!headers['Content-Type']) {
      headers['Content-Type'] = 'application/json'
    }
    const jwt = await getApiJwt()
    if (jwt) {
      headers['Authorization'] = `Bearer ${jwt}`
    }

    const urlJoined = joinApiUrl(API_BASE, endpoint)

    const response = await fetch(urlJoined, {
      ...options,
      headers,
    })

    const ct = response.headers.get('content-type') || ''
    const isJson = ct.includes('application/json')
    const data = isJson
      ? await response.json()
      : { success: false as const, error: undefined }

    if (!isJson) {
      return {
        error: {
          code: response.status === 404 ? 'NOT_FOUND' : 'INVALID_RESPONSE',
          message:
            response.status === 404
              ? 'API 404: backend unreachable or wrong port — check server is running and VITE_DEV_API_ORIGIN matches PORT.'
              : `Expected JSON, got ${ct || 'unknown'} (HTTP ${response.status})`,
        },
      }
    }

    if (!response.ok || data.success === false) {
      return {
        error: data.error || {
          code: 'UNKNOWN',
          message: `HTTP ${response.status}`,
        },
      }
    }

    return { success: true, data: data.data ?? data }
  } catch (error) {
    return {
      error: {
        code: 'NETWORK_ERROR',
        message: error instanceof Error ? error.message : 'Network error',
      },
    }
  }
}

export const api = {
  // ═══════════════════════════════════════════════════════════════════════════
  // EMAIL ACCOUNTS
  // ═══════════════════════════════════════════════════════════════════════════

  async getEmailAccounts() {
    return fetchApi<Array<{
      id: string
      email: string
      provider: 'gmail' | 'outlook' | 'imap'
      connected: boolean
      lastSync?: string
    }>>('/email/accounts')
  },

  async connectEmailAccount(provider: 'gmail' | 'outlook', email: string, accessToken: string, refreshToken?: string) {
    return fetchApi<{ accountId: string }>('/email/connect', {
      method: 'POST',
      body: JSON.stringify({ provider, email, accessToken, refreshToken }),
    })
  },

  async connectImapAccount(params: {
    email: string
    password: string
    imapHost?: string
    imapPort?: number
    imapSecure?: boolean
  }) {
    return fetchApi<{ accountId: string }>('/email/connect', {
      method: 'POST',
      body: JSON.stringify({
        provider: 'imap',
        email: params.email,
        accessToken: params.password,
        imapHost: params.imapHost,
        imapPort: params.imapPort,
        imapSecure: params.imapSecure,
      }),
    })
  },

  async disconnectEmailAccount(accountId: string) {
    return fetchApi<{ success: boolean }>(`/email/accounts/${accountId}`, {
      method: 'DELETE',
    })
  },

  // ═══════════════════════════════════════════════════════════════════════════
  // EMAIL STATS & SORTING
  // ═══════════════════════════════════════════════════════════════════════════

  async getEmailStats() {
    return fetchApi<{
      totalSorted: number
      todaySorted: number
      weekSorted: number
      categories: Record<string, number>
      timeSaved: number
    }>('/email/stats')
  },

  async sortEmails(accountId: string, maxEmails?: number, processAll?: boolean) {
    return fetchApi<{
      sorted: number
      inboxCleared: number
      categories: Record<string, number>
      timeSaved: { minutes: number; formatted: string }
      highlights: Array<{ type: string; count: number; message: string }>
      suggestions: Array<{ type: string; message: string }>
      provider?: string
      isDemo?: boolean
      isFirstRun?: boolean
      suggestedRules?: Array<{
        type: string
        name: string
        description: string
        confidence: number
        action?: { name?: string }
      }>
    }>('/email/sort', {
      method: 'POST',
      body: JSON.stringify({ accountId, maxEmails, processAll }),
    })
  },

  async sortDemo(count: number = 10) {
    return fetchApi<{
      sorted: number
      emails: Array<{
        from: string
        subject: string
        snippet: string
        category: string
        categoryName: string
        confidence?: number
        reason?: string
      }>
      categories: Record<string, number>
      aiEnabled: boolean
    }>('/email/sort-demo', {
      method: 'POST',
      body: JSON.stringify({ count }),
    })
  },

  async connectDemoAccount() {
    return fetchApi<{
      accountId: string
      email: string
      provider: string
      message?: string
    }>('/email/connect-demo', {
      method: 'POST',
      body: JSON.stringify({}),
    })
  },

  async getCategories() {
    return fetchApi<Array<{
      id: string
      name: string
      description: string
      color: string
      action: string
      priority: number
    }>>('/email/categories')
  },

  async getDigest() {
    return fetchApi<{
      date: string
      totalSorted: number
      inboxCleared: number
      timeSavedMinutes: number
      stats: Record<string, number>
      highlights: Array<{ type: string; count: number; message: string }>
      suggestions: Array<{ type: string; message: string }>
      hasData: boolean
    }>('/email/digest')
  },

  async getDigestHistory(days: number = 7) {
    return fetchApi<{
      days: number
      digests: Array<{
        date: string
        totalSorted: number
        inboxCleared: number
        timeSavedMinutes: number
        stats: Record<string, number>
      }>
      totals: {
        totalSorted: number
        inboxCleared: number
        timeSavedMinutes: number
      }
    }>(`/email/digest/history?days=${days}`)
  },

  // ═══════════════════════════════════════════════════════════════════════════
  // OAUTH
  // ═══════════════════════════════════════════════════════════════════════════

  async getOAuthUrl(provider: 'gmail' | 'outlook') {
    return fetchApi<{ url: string }>(`/oauth/${provider}/connect`)
  },

  async getOAuthStatus() {
    return fetchApi<{
      gmail: { enabled: boolean; scopes: string[] }
      outlook: { enabled: boolean; scopes: string[] }
    }>('/oauth/status')
  },

  // ═══════════════════════════════════════════════════════════════════════════
  // SUBSCRIPTION
  // ═══════════════════════════════════════════════════════════════════════════

  async getSubscriptionStatus() {
    return fetchApi<{
      status: string
      plan: string
      planDisplayName?: string
      isFreeTier: boolean
      emailsUsedThisMonth?: number
      emailsLimit?: number
      features: {
        emailAccounts: number
        emailsPerDay: number
        historicalSync: boolean
        customRules: boolean
        prioritySupport: boolean
      }
      currentPeriodEnd?: string
      cancelAtPeriodEnd?: boolean
    }>('/subscription/status')
  },

  async createSubscriptionCheckout(plan: string, email?: string) {
    return fetchApi<{ url: string; sessionId: string }>('/subscription/checkout', {
      method: 'POST',
      body: JSON.stringify({ plan, email }),
    })
  },

  async createPortalSession() {
    return fetchApi<{ url: string }>('/subscription/portal', {
      method: 'POST',
      body: JSON.stringify({}),
    })
  },

  async cancelSubscription() {
    return fetchApi<{ success: boolean }>('/subscription/cancel', {
      method: 'POST',
      body: JSON.stringify({}),
    })
  },

  async reactivateSubscription() {
    return fetchApi<{ success: boolean }>('/subscription/reactivate', {
      method: 'POST',
      body: JSON.stringify({}),
    })
  },

  // ═══════════════════════════════════════════════════════════════════════════
  // USER PREFERENCES
  // ═══════════════════════════════════════════════════════════════════════════

  async getUserPreferences() {
    return fetchApi<{
      vipSenders: Array<{ email: string; name?: string }>
      blockedSenders: string[]
      customRules: Array<{ condition: string; category: string }>
      priorityTopics: string[]
      profile?: {
        displayName?: string
        timezone?: string
        notificationPrefs?: Record<string, unknown>
      }
    }>('/preferences')
  },

  async saveUserPreferences(preferences: {
    vipSenders?: Array<{ email: string; name?: string }>
    blockedSenders?: string[]
    customRules?: Array<{ condition: string; category: string }>
    priorityTopics?: string[]
    companyLabels?: Array<{ name: string; condition?: string; category: string; enabled: boolean }>
  }) {
    return fetchApi<{ success: boolean }>('/preferences', {
      method: 'POST',
      body: JSON.stringify(preferences),
    })
  },

  // ═══════════════════════════════════════════════════════════════════════════
  // AI CONTROL
  // ═══════════════════════════════════════════════════════════════════════════

  async getAIControlSettings() {
    return fetchApi<{
      enabledCategories: string[]
      categoryActions: Record<string, 'inbox' | 'archive_read' | 'star'>
      autoDetectCompanies: boolean
      cleanup?: unknown
      categoryAdvanced?: Record<string, unknown>
      version?: number
    }>('/preferences/ai-control')
  },

  async saveAIControlSettings(settings: {
    enabledCategories?: string[]
    categoryActions?: Record<string, 'inbox' | 'archive_read' | 'star'>
    autoDetectCompanies?: boolean
    cleanup?: unknown
    categoryAdvanced?: Record<string, unknown>
    version?: number
  }) {
    return fetchApi<{ success: boolean }>('/preferences/ai-control', {
      method: 'POST',
      body: JSON.stringify(settings),
    })
  },

  async getCleanupPreview(accountId: string) {
    return fetchApi<{
      messages: Array<{
        id: string
        subject: string
        from: string
        date: string
        reason: 'read' | 'promotion'
      }>
      count: number
    }>(`/email/${accountId}/cleanup/preview`)
  },

  async runCleanup() {
    return fetchApi<{
      usersProcessed: number
      emailsProcessed: {
        readItems: number
        promotions: number
      }
      errors: Array<{ userId: string; error: string }>
    }>('/email/cleanup', {
      method: 'POST',
      body: JSON.stringify({}),
    })
  },

  async getCleanupStatus(accountId: string) {
    return fetchApi<{
      lastRun?: string
      lastRunCounts?: {
        readItems: number
        promotions: number
      }
      lastErrors?: string[]
    }>(`/email/${accountId}/cleanup/status`)
  },

  async updateProfile(payload: {
    displayName?: string
    timezone?: string
    notificationPrefs?: Record<string, unknown>
  }) {
    return fetchApi<{ success: boolean }>('/preferences/profile', {
      method: 'PATCH',
      body: JSON.stringify(payload),
    })
  },

  // ═══════════════════════════════════════════════════════════════════════════
  // COMPANY LABELS
  // ═══════════════════════════════════════════════════════════════════════════

  async getCompanyLabels() {
    return fetchApi<Array<{
      id?: string
      name: string
      condition: string
      enabled: boolean
      category?: string
    }>>('/preferences/company-labels')
  },

  async saveCompanyLabel(companyLabel: {
    id?: string
    name: string
    condition: string
    enabled: boolean
    category?: string
  }) {
    return fetchApi<{
      id?: string
      name: string
      condition: string
      enabled: boolean
      category?: string
    }>('/preferences/company-labels', {
      method: 'POST',
      body: JSON.stringify({ companyLabel }),
    })
  },

  async deleteCompanyLabel(labelId: string) {
    return fetchApi<{ success: boolean }>(`/preferences/company-labels/${labelId}`, {
      method: 'DELETE',
    })
  },

  // ═══════════════════════════════════════════════════════════════════════════
  // ME / ADMIN
  // ═══════════════════════════════════════════════════════════════════════════

  async getMe() {
    return fetchApi<{ isAdmin: boolean }>('/me')
  },

  // ═══════════════════════════════════════════════════════════════════════════
  // NAME LABELS (Workers – Admin only)
  // ═══════════════════════════════════════════════════════════════════════════

  async getNameLabels() {
    return fetchApi<Array<{
      id?: string
      name: string
      email?: string
      keywords?: string[]
      enabled: boolean
    }>>('/preferences/name-labels')
  },

  async saveNameLabel(nameLabel: { id?: string; name: string; email?: string; keywords?: string[]; enabled: boolean }) {
    return fetchApi<{ id?: string; name: string; email?: string; keywords?: string[]; enabled: boolean }>(
      '/preferences/name-labels',
      {
        method: 'POST',
        body: JSON.stringify({ nameLabel }),
      }
    )
  },

  async deleteNameLabel(labelId: string) {
    return fetchApi<{ success: boolean }>(`/preferences/name-labels/${labelId}`, { method: 'DELETE' })
  },

  // ═══════════════════════════════════════════════════════════════════════════
  // PRODUCTS & QUESTIONS (Legacy)
  // ═══════════════════════════════════════════════════════════════════════════

  async getProducts() {
    return fetchApi<unknown[]>('/products')
  },

  async getQuestions(productSlug: string) {
    return fetchApi<unknown[]>(`/questions?productSlug=${productSlug}`)
  },

  async createSubmission(productSlug: string, answers: Record<string, unknown>) {
    return fetchApi<{ submissionId: string }>('/submissions', {
      method: 'POST',
      body: JSON.stringify({ productSlug, answers }),
    })
  },

  async createCheckout(submissionId: string) {
    return fetchApi<{ url: string; sessionId: string }>('/checkout', {
      method: 'POST',
      body: JSON.stringify({ submissionId }),
    })
  },

  // ═══════════════════════════════════════════════════════════════════════════
  // CONFIG
  // ═══════════════════════════════════════════════════════════════════════════

  async getConfig() {
    return fetchApi<{
      features: {
        gmail: boolean
        outlook: boolean
        ai: boolean
      }
      pricing: {
        basic: { price: number; currency: string; accounts: number }
        pro: { price: number; currency: string; accounts: number }
        business: { price: number; currency: string; accounts: number }
      }
    }>('/config')
  },

  async healthCheck() {
    return fetchApi<{
      status: string
      timestamp: string
      version: string
      environment: string
      uptime: number
    }>('/health')
  },

  // ═══════════════════════════════════════════════════════════════════════════
  // ONBOARDING
  // ═══════════════════════════════════════════════════════════════════════════

  async getOnboardingStatus() {
    return fetchApi<{
      onboarding_step: string
      completedSteps: string[]
      first_value_seen_at?: string
      skipped_at?: string
    }>('/onboarding/status')
  },

  async updateOnboardingStep(step: string, completedSteps: string[] = []) {
    return fetchApi<{ step: string; completedSteps: string[] }>('/onboarding/step', {
      method: 'POST',
      body: JSON.stringify({ step, completedSteps }),
    })
  },

  async skipOnboarding() {
    return fetchApi<{ skipped: boolean }>('/onboarding/skip', {
      method: 'POST',
      body: JSON.stringify({}),
    })
  },

  async resumeOnboarding() {
    return fetchApi<{
      onboarding_step: string
      completedSteps: string[]
    }>('/onboarding/resume', {
      method: 'POST',
      body: JSON.stringify({}),
    })
  },

  // ═══════════════════════════════════════════════════════════════════════════
  // ACCOUNT MANAGEMENT
  // ═══════════════════════════════════════════════════════════════════════════

  async deleteAccount() {
    return fetchApi<{ success: boolean }>('/account/delete', {
      method: 'DELETE',
      body: JSON.stringify({}),
    })
  },

  // ═══════════════════════════════════════════════════════════════════════════
  // REFERRALS
  // ═══════════════════════════════════════════════════════════════════════════

  async getReferralCode() {
    return fetchApi<{
      referralCode: string
      referralCount: number
    }>('/referrals/code')
  },

  async trackReferral(referralCode: string) {
    return fetchApi<{ success: boolean }>('/referrals/track', {
      method: 'POST',
      body: JSON.stringify({ referralCode }),
    })
  },
}

export default api
