/**
 * API client for pounce backend
 * 
 * API URL is determined dynamically based on the current hostname:
 * - localhost/127.0.0.1 → http://localhost:8000/api/v1
 * - Local network IPs (10.x, 192.168.x) → http://{hostname}:8000/api/v1
 * - Production (any other domain) → https://{hostname}/api/v1 (requires reverse proxy)
 */

const getApiBase = (): string => {
  // Server-side rendering: use environment variable or localhost
  if (typeof window === 'undefined') {
    // Prefer internal backend URL (server-only) when running in Docker/SSR
    const backendUrl = process.env.BACKEND_URL?.replace(/\/$/, '')
    const configured = (backendUrl ? `${backendUrl}/api/v1` : process.env.NEXT_PUBLIC_API_URL) || 'http://localhost:8000/api/v1'
    const normalized = configured.replace(/\/$/, '')
    return normalized.endsWith('/api/v1') ? normalized : `${normalized}/api/v1`
  }

  const { protocol, hostname, port } = window.location

  // Localhost development
  if (hostname === 'localhost' || hostname === '127.0.0.1') {
    return 'http://localhost:8000/api/v1'
  }

  // Local network (10.x.x.x, 192.168.x.x, 172.16-31.x.x)
  if (/^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.)/.test(hostname)) {
    return `http://${hostname}:8000/api/v1`
}

  // Production: use same protocol and domain with /api/v1 path
  // This requires a reverse proxy (nginx/caddy) to route /api/v1 to the backend
  return `${protocol}//${hostname}/api/v1`
}

// Lazy-evaluated to ensure window is available on client
let _apiBase: string | null = null
const getApiBaseUrl = (): string => {
  if (_apiBase === null) {
    _apiBase = getApiBase()
  }
  return _apiBase
}

interface ApiError {
  detail: string
}

class ApiClient {
  get baseUrl(): string {
    return getApiBaseUrl().replace('/api/v1', '')
    }

  async request<T>(
    endpoint: string,
    options: RequestInit = {}
  ): Promise<T> {
    const url = `${getApiBaseUrl()}${endpoint}`
    const headers: Record<string, string> = {
      'Content-Type': 'application/json',
      ...options.headers as Record<string, string>,
    }

    const response = await fetch(url, {
      ...options,
      headers,
      credentials: 'include', // send HttpOnly auth cookie
    })

    if (!response.ok) {
      const errorData = await response.json().catch(() => ({ detail: 'An error occurred' }))
      const errorMessage = typeof errorData.detail === 'string' 
        ? errorData.detail 
        : (errorData.message || JSON.stringify(errorData.detail) || 'An error occurred')
      throw new Error(errorMessage)
    }

    if (response.status === 204) {
      return {} as T
    }

    return response.json()
  }

  // Auth
  async register(email: string, password: string, name?: string, ref?: string) {
    return this.request<{ id: number; email: string }>('/auth/register', {
      method: 'POST',
      body: JSON.stringify({ email, password, name, ref }),
    })
  }

  async getReferralLink() {
    return this.request<{
      invite_code: string
      url: string
      stats?: {
        window_days: number
        referred_users_total: number
        qualified_referrals_total: number
        referral_link_views_window: number
        bonus_domains: number
        next_reward_at: number
        badge: string | null
        cooldown_days?: number
        disqualified_cooldown_total?: number
        disqualified_missing_ip_total?: number
        disqualified_shared_ip_total?: number
        disqualified_duplicate_ip_total?: number
      }
    }>('/auth/referral')
  }

  async login(email: string, password: string) {
    const response = await this.request<{ expires_in: number }>(
      '/auth/login',
      {
        method: 'POST',
        body: JSON.stringify({ email, password }),
      }
    )
    return response
  }

  async logout() {
    // Clears auth cookie on the backend
    return this.request<{ message: string; success: boolean }>('/auth/logout', {
      method: 'POST',
    })
  }

  async getMe() {
    return this.request<{
      id: number
      email: string
      name: string | null
      is_active: boolean
      is_admin: boolean
      is_verified: boolean
      created_at: string
    }>('/auth/me')
  }

  // Dashboard (Terminal Radar) - single call payload
  async getDashboardSummary() {
    return this.request<{
      market: {
        total_auctions: number
        ending_soon: number
        ending_soon_preview: Array<{
          domain: string
          current_bid: number
          time_remaining: string
          platform: string
          affiliate_url?: string
        }>
      }
      listings: { active: number; sold: number; draft: number; total: number }
      tlds: { trending: Array<{ tld: string; reason: string; price_change: number; current_price: number }> }
      timestamp: string
    }>('/dashboard/summary')
  }

  // Analyze (Alpha Terminal - Diligence)
  async analyzeDomain(domain: string, opts?: { fast?: boolean; refresh?: boolean }) {
    const params = new URLSearchParams()
    if (opts?.fast) params.set('fast', 'true')
    if (opts?.refresh) params.set('refresh', 'true')
    const qs = params.toString()
    return this.request<{
      domain: string
      computed_at: string
      cached: boolean
      sections: Array<{
        key: string
        title: string
        items: Array<{
          key: string
          label: string
          value: unknown | null
          status: string
          source: string
          details: Record<string, unknown>
        }>
      }>
    }>(`/analyze/${encodeURIComponent(domain)}${qs ? `?${qs}` : ''}`)
  }

  // HUNT (Alpha Terminal - Discovery)
  async getHuntBargainBin(limit: number = 100) {
    const qs = new URLSearchParams({ limit: String(limit) })
    return this.request<{
      items: Array<{
        domain: string
        platform: string
        auction_url: string
        current_bid: number
        currency: string
        end_time: string
        age_years: number | null
        backlinks: number | null
        pounce_score: number | null
      }>
      total: number
      filtered_out_missing_data: number
      last_updated: string | null
    }>(`/hunt/bargain-bin?${qs}`)
  }

  async getHuntTrends(geo: string = 'US') {
    const qs = new URLSearchParams({ geo })
    return this.request<{
      geo: string
      items: Array<{ title: string; approx_traffic?: string | null; published_at?: string | null; link?: string | null }>
      fetched_at: string
    }>(`/hunt/trends?${qs}`)
  }

  async huntKeywords(payload: { keywords: string[]; tlds?: string[] }) {
    return this.request<{
      items: Array<{ keyword: string; domain: string; tld: string; is_available: boolean | null; status: string }>
    }>(`/hunt/keywords`, {
      method: 'POST',
      body: JSON.stringify(payload),
    })
  }

  async huntTypos(payload: { brand: string; tlds?: string[]; limit?: number }) {
    return this.request<{
      brand: string
      items: Array<{ domain: string; is_available: boolean | null; status: string }>
    }>(`/hunt/typos`, {
      method: 'POST',
      body: JSON.stringify(payload),
    })
  }

  async huntBrandables(payload: { pattern: string; tlds?: string[]; limit?: number; max_checks?: number }) {
    return this.request<{
      pattern: string
      items: Array<{ domain: string; is_available: boolean | null; status: string }>
    }>(`/hunt/brandables`, {
      method: 'POST',
      body: JSON.stringify(payload),
    })
  }

  // LLM Naming (AI-powered suggestions for Trends & Forge)
  async expandTrendKeywords(trend: string, geo: string = 'US') {
    return this.request<{ keywords: string[]; trend: string }>('/naming/trends/expand', {
      method: 'POST',
      body: JSON.stringify({ trend, geo }),
    })
  }

  async analyzeTrend(trend: string, geo: string = 'US') {
    return this.request<{ analysis: string; trend: string }>('/naming/trends/analyze', {
      method: 'POST',
      body: JSON.stringify({ trend, geo }),
    })
  }

  async generateBrandableNames(concept: string, style?: string, count: number = 15) {
    return this.request<{ names: string[]; concept: string }>('/naming/forge/generate', {
      method: 'POST',
      body: JSON.stringify({ concept, style, count }),
    })
  }

  async generateSimilarNames(brand: string, count: number = 12) {
    return this.request<{ names: string[]; brand: string }>('/naming/forge/similar', {
      method: 'POST',
      body: JSON.stringify({ brand, count }),
    })
  }

  // LLM Vision (Trader/Tycoon)
  async getVision(domain: string, refresh: boolean = false) {
    const qs = new URLSearchParams({ domain })
    if (refresh) qs.set('refresh', 'true')
    return this.request<{
      domain: string
      cached: boolean
      model: string
      prompt_version: string
      generated_at: string
      result: {
        business_concept: string
        industry_vertical: string
        buyer_persona: string
        cold_email_subject: string
        cold_email_body: string
        monetization_idea: string
        radio_test_score: number
        reasoning: string
      }
    }>(`/llm/vision?${qs.toString()}`)
  }

  async getYieldLandingPreview(domain: string, refresh: boolean = false) {
    const qs = new URLSearchParams({ domain })
    if (refresh) qs.set('refresh', 'true')
    return this.request<{
      domain: string
      cached: boolean
      model: string
      prompt_version: string
      generated_at: string
      result: {
        template: string
        headline: string
        seo_intro: string
        cta_label: string
        niche: string
        color_scheme: string
      }
    }>(`/llm/yield/landing-preview?${qs.toString()}`)
  }

  // CFO (Alpha Terminal - Management)
  async getCfoSummary() {
    return this.request<{
      computed_at: string
      upcoming_30d_total_usd: number
      upcoming_30d_rows: Array<{
        domain_id: number
        domain: string
        renewal_date: string | null
        renewal_cost_usd: number | null
        cost_source: string
        is_sold: boolean
      }>
      monthly: Array<{ month: string; total_cost_usd: number; domains: number }>
      kill_list: Array<{
        domain_id: number
        domain: string
        renewal_date: string | null
        renewal_cost_usd: number | null
        cost_source: string
        auto_renew: boolean
        is_dns_verified: boolean
        yield_net_60d: number
        yield_clicks_60d: number
        reason: string
      }>
    }>(`/cfo/summary`)
  }

  async cfoSetToDrop(domainId: number) {
    return this.request<{ domain_id: number; auto_renew: boolean; updated_at: string }>(`/cfo/domains/${domainId}/set-to-drop`, {
      method: 'POST',
    })
  }

  async updateMe(data: { name?: string }) {
    return this.request<{
      id: number
      email: string
      name: string | null
      is_active: boolean
      created_at: string
    }>('/auth/me', {
      method: 'PUT',
      body: JSON.stringify(data),
    })
  }

  // Password Reset
  async forgotPassword(email: string) {
    return this.request<{ message: string; success: boolean }>('/auth/forgot-password', {
      method: 'POST',
      body: JSON.stringify({ email }),
    })
  }

  async resetPassword(token: string, newPassword: string) {
    return this.request<{ message: string; success: boolean }>('/auth/reset-password', {
      method: 'POST',
      body: JSON.stringify({ token, new_password: newPassword }),
    })
  }

  // Email Verification
  async verifyEmail(token: string) {
    return this.request<{ message: string; success: boolean }>('/auth/verify-email', {
      method: 'POST',
      body: JSON.stringify({ token }),
    })
  }

  async resendVerification(email: string) {
    return this.request<{ message: string; success: boolean }>('/auth/resend-verification', {
      method: 'POST',
      body: JSON.stringify({ email }),
    })
  }

  // OAuth
  async getOAuthProviders() {
    return this.request<{ google_enabled: boolean; github_enabled: boolean }>('/oauth/providers')
  }

  getGoogleLoginUrl(redirect?: string) {
    const params = redirect ? `?redirect=${encodeURIComponent(redirect)}` : ''
    return `${getApiBaseUrl()}/oauth/google/login${params}`
  }

  getGitHubLoginUrl(redirect?: string) {
    const params = redirect ? `?redirect=${encodeURIComponent(redirect)}` : ''
    return `${getApiBaseUrl()}/oauth/github/login${params}`
  }

  // Contact Form
  async submitContact(name: string, email: string, subject: string, message: string) {
    return this.request<{ message: string; success: boolean }>('/contact', {
      method: 'POST',
      body: JSON.stringify({ name, email, subject, message }),
    })
  }

  // Newsletter
  async subscribeNewsletter(email: string) {
    return this.request<{ message: string; success: boolean }>('/contact/newsletter/subscribe', {
      method: 'POST',
      body: JSON.stringify({ email }),
    })
  }

  async unsubscribeNewsletter(email: string, token?: string) {
    return this.request<{ message: string; success: boolean }>('/contact/newsletter/unsubscribe', {
      method: 'POST',
      body: JSON.stringify({ email, token }),
    })
  }

  // Subscription - Stripe Integration
  async createCheckoutSession(plan: string, successUrl?: string, cancelUrl?: string) {
    return this.request<{ checkout_url: string; session_id: string }>('/subscription/checkout', {
      method: 'POST',
      body: JSON.stringify({
        plan,
        success_url: successUrl,
        cancel_url: cancelUrl,
      }),
    })
  }

  async createPortalSession() {
    return this.request<{ portal_url: string }>('/subscription/portal', {
      method: 'POST',
    })
  }

  async cancelSubscription() {
    return this.request<{ status: string; message: string; new_tier: string }>('/subscription/cancel', {
      method: 'POST',
    })
  }

  // Domain Check (public)
  async checkDomain(domain: string, quick = false) {
    return this.request<{
      domain: string
      status: string
      is_available: boolean
      registrar: string | null
      expiration_date: string | null
      creation_date: string | null
      name_servers: string[] | null
      error_message: string | null
      checked_at: string
    }>('/check', {
      method: 'POST',
      body: JSON.stringify({ domain, quick }),
    })
  }

  // Domains (authenticated)
  async getDomains(page = 1, perPage = 20) {
    return this.request<{
      domains: Array<{
        id: number
        name: string
        status: string
        is_available: boolean
        registrar: string | null
        expiration_date: string | null
        notify_on_available: boolean
        created_at: string
        last_checked: string | null
      }>
      total: number
      page: number
      per_page: number
      pages: number
    }>(`/domains?page=${page}&per_page=${perPage}`)
  }

  async addDomain(name: string, notify = true) {
    return this.request<{
      id: number
      name: string
      status: string
      is_available: boolean
    }>('/domains', {
      method: 'POST',
      body: JSON.stringify({ name, notify_on_available: notify }),
    })
  }

  async deleteDomain(id: number) {
    return this.request<void>(`/domains/${id}`, {
      method: 'DELETE',
    })
  }

  async refreshDomain(id: number) {
    return this.request<{
      id: number
      name: string
      status: string
      is_available: boolean
    }>(`/domains/${id}/refresh`, {
      method: 'POST',
    })
  }

  async refreshAllDomains() {
    return this.request<{
      message: string
      checked: number
      errors: number
      changes: Array<{
        domain: string
        change: 'became_available' | 'became_taken'
        old_registrar?: string
        new_registrar?: string
      }>
      total_domains: number
    }>('/domains/refresh-all', {
      method: 'POST',
    })
  }

  async updateDomainNotify(id: number, notify: boolean) {
    return this.request<{
      id: number
      name: string
      notify: boolean
    }>(`/domains/${id}/notify`, {
      method: 'PATCH',
      body: JSON.stringify({ notify }),
    })
  }

  async updateDomainExpiry(id: number, expirationDate: string | null) {
    return this.request<{
      id: number
      name: string
      expiration_date: string | null
    }>(`/domains/${id}/expiry`, {
      method: 'PATCH',
      body: JSON.stringify({ expiration_date: expirationDate }),
    })
  }

  // Marketplace Listings (Pounce Direct)
  async getMarketplaceListings() {
    return this.request<any[]>('/listings')
  }

  // My Listings
  async getMyListings() {
    return this.request<any[]>('/listings/my')
  }

  async createListing(data: { domain: string; asking_price: number | null; currency: string; price_type: string }) {
    return this.request<any>('/listings', { method: 'POST', body: JSON.stringify(data) })
  }

  async deleteListing(id: number) {
    return this.request<void>(`/listings/${id}`, { method: 'DELETE' })
  }

  async updateListing(
    id: number,
    data: {
      status?: string
      title?: string
      description?: string
      asking_price?: number
      sold_reason?: string | null
      sold_price?: number | null
      sold_currency?: string | null
    }
  ) {
    return this.request<any>(`/listings/${id}`, { method: 'PUT', body: JSON.stringify(data) })
  }

  async startDnsVerification(id: number) {
    return this.request<{
      verification_code: string
      dns_record_type: string
      dns_record_name: string
      dns_record_value: string
      instructions: string
      status: string
    }>(`/listings/${id}/verify-dns`, { method: 'POST' })
  }

  async checkDnsVerification(id: number) {
    return this.request<{
      verified: boolean
      status: string
      message: string
    }>(`/listings/${id}/verify-dns/check`)
  }

  async getListingInquiries(id: number) {
    return this.request<any[]>(`/listings/${id}/inquiries`)
  }

  async updateListingInquiry(
    listingId: number,
    inquiryId: number,
    data: { status: 'new' | 'read' | 'replied' | 'closed' | 'spam'; reason?: string | null }
  ) {
    return this.request<any>(`/listings/${listingId}/inquiries/${inquiryId}`, {
      method: 'PATCH',
      body: JSON.stringify(data),
    })
  }

  async getMyInquiryThreads() {
    return this.request<Array<{
      id: number
      listing_id: number
      domain: string
      slug: string
      status: string
      created_at: string
      closed_at: string | null
      closed_reason: string | null
    }>>('/listings/inquiries/my')
  }

  async getInquiryMessagesAsBuyer(inquiryId: number) {
    return this.request<any[]>(`/listings/inquiries/${inquiryId}/messages`)
  }

  async sendInquiryMessageAsBuyer(inquiryId: number, body: string) {
    return this.request<any>(`/listings/inquiries/${inquiryId}/messages`, {
      method: 'POST',
      body: JSON.stringify({ body }),
    })
  }

  async getInquiryMessagesAsSeller(listingId: number, inquiryId: number) {
    return this.request<any[]>(`/listings/${listingId}/inquiries/${inquiryId}/messages`)
  }

  async sendInquiryMessageAsSeller(listingId: number, inquiryId: number, body: string) {
    return this.request<any>(`/listings/${listingId}/inquiries/${inquiryId}/messages`, {
      method: 'POST',
      body: JSON.stringify({ body }),
    })
  }

  // Inbox Counts (for badge)
  async getInboxCounts() {
    return this.request<{
      buyer_unread: number
      seller_unread: number
      total_unread: number
    }>('/listings/inbox/counts')
  }

  // Seller Inbox (unified view of all inquiries)
  async getSellerInbox(statusFilter?: 'all' | 'new' | 'read' | 'replied' | 'closed' | 'spam') {
    const params = statusFilter && statusFilter !== 'all' ? `?status_filter=${statusFilter}` : ''
    return this.request<{
      inquiries: Array<{
        id: number
        listing_id: number
        domain: string
        slug: string
        buyer_name: string
        buyer_email: string
        offer_amount: number | null
        status: string
        created_at: string
        read_at: string | null
        replied_at: string | null
        closed_at: string | null
        closed_reason: string | null
        has_unread_reply: boolean
        last_message_preview: string
        last_message_at: string
        last_message_is_buyer: boolean
      }>
      total: number
      unread: number
    }>(`/listings/inbox/seller${params}`)
  }

  // Subscription
  async getSubscription() {
    return this.request<{
      id: number
      tier: string
      tier_name: string
      status: string
      domain_limit: number
      domains_used: number
      portfolio_limit: number
      check_frequency: string
      history_days: number
      features: {
        email_alerts: boolean
        priority_alerts: boolean
        full_whois: boolean
        expiration_tracking: boolean
        domain_valuation: boolean
        market_insights: boolean
        api_access: boolean
        webhooks: boolean
        bulk_tools: boolean
        seo_metrics: boolean
      }
      started_at: string
      expires_at: string | null
    }>('/subscription')
  }

  async getTiers() {
    return this.request<{
      tiers: Array<{
        id: string
        name: string
        domain_limit: number
        price: number
        features: string[]
      }>
    }>('/subscription/tiers')
  }

  // Domain History (Professional/Enterprise)
  async getDomainHistory(domainId: number, limit = 30) {
    return this.request<{
      domain: string
      total_checks: number
      history: Array<{
        id: number
        status: string
        is_available: boolean
        checked_at: string
      }>
    }>(`/domains/${domainId}/history?limit=${limit}`)
  }

  // Domain Health Check - 4-layer analysis (DNS, HTTP, SSL, WHOIS)
  async getDomainHealth(domainId: number, options?: { refresh?: boolean }) {
    const refreshParam = options?.refresh ? '?refresh=true' : ''
    return this.request<DomainHealthReport>(`/domains/${domainId}/health${refreshParam}`)
  }

  // Quick health check for any domain (premium)
  async quickHealthCheck(domain: string) {
    return this.request<DomainHealthReport>(`/domains/health-check?domain=${encodeURIComponent(domain)}`, {
      method: 'POST',
    })
  }

  // Bulk cached health reports for watchlist UI (fast)
  async getDomainsHealthCache() {
    return this.request<{
      reports: Record<string, DomainHealthReport>
      total_domains: number
      cached_domains: number
      timestamp: string
    }>('/domains/health-cache')
  }

  // TLD Pricing
  async getTldOverview(
    limit = 25,
    offset = 0,
    sortBy: 'popularity' | 'price_asc' | 'price_desc' | 'name' = 'popularity',
    search?: string
  ) {
    const params = new URLSearchParams({
      limit: limit.toString(),
      offset: offset.toString(),
      sort_by: sortBy,
    })
    if (search) {
      params.append('search', search)
    }
    return this.request<{
      tlds: Array<{
        tld: string
        type: string
        description: string
        avg_registration_price: number
        min_registration_price: number
        max_registration_price: number
        min_renewal_price: number
        avg_renewal_price: number
        registrar_count: number
        trend: string
        price_change_7d: number
        price_change_1y: number
        price_change_3y: number
        risk_level: 'low' | 'medium' | 'high'
        risk_reason: string
        popularity_rank?: number
      }>
      total: number
      limit: number
      offset: number
      has_more: boolean
      source: string
    }>(`/tld-prices/overview?${params.toString()}`)
  }

  async getTldHistory(tld: string, days = 90) {
    return this.request<{
      tld: string
      type: string
      description: string
      registry: string
      current_price: number
      price_change_7d: number
      price_change_30d: number
      price_change_90d: number
      trend: string
      trend_reason: string
      history: Array<{
        date: string
        price: number
      }>
      source: string
    }>(`/tld-prices/${tld}/history?days=${days}`)
  }

  async getTldCompare(tld: string) {
    return this.request<{
      tld: string
      type: string
      description: string
      registry: string
      introduced: number | null
      registrars: Array<{
        name: string
        registration_price: number
        renewal_price: number
        transfer_price: number
      }>
      cheapest_registrar: string
      cheapest_price: number
      price_range: {
        min: number
        max: number
        avg: number
      }
    }>(`/tld-prices/${tld}/compare`)
  }

  async getTrendingTlds() {
    return this.request<{
      trending: Array<{
        tld: string
        reason: string
        price_change: number
        current_price: number
      }>
    }>('/tld-prices/trending')
  }

  // Get TLD info for SEO pages
  async getTldInfo(tld: string) {
    try {
      const compare = await this.getTldCompare(tld)
      return {
        tld: compare.tld,
        type: compare.type,
        registration_price: compare.cheapest_price,
        renewal_price: compare.registrars?.[0]?.renewal_price || null,
        registrar_count: compare.registrars?.length || 0,
        description: compare.description,
        introduced: compare.introduced?.toString() || null,
        registry: compare.registry,
      }
    } catch {
      return null
    }
  }

  // Get TLD prices for SEO pages
  async getTldPrices(tld: string) {
    try {
      const [compare, history] = await Promise.all([
        this.getTldCompare(tld),
        this.getTldHistory(tld, 365),
      ])
      return {
        registrars: compare.registrars?.map(r => ({
          registrar: r.name,
          registration: r.registration_price,
          renewal: r.renewal_price,
          transfer: r.transfer_price,
        })) || [],
        history: history.history || [],
      }
    } catch {
      return { registrars: [], history: [] }
    }
  }

  // ============== Portfolio ==============
  
  async getPortfolio(
    status?: string,
    sortBy = 'created_at',
    sortOrder = 'desc',
    limit = 100,
    offset = 0
  ) {
    const params = new URLSearchParams({
      sort_by: sortBy,
      sort_order: sortOrder,
      limit: limit.toString(),
      offset: offset.toString(),
    })
    if (status) {
      params.append('status', status)
    }
    return this.request<PortfolioDomain[]>(`/portfolio?${params.toString()}`)
  }

  async getPortfolioSummary() {
    return this.request<PortfolioSummary>('/portfolio/summary')
  }

  async addPortfolioDomain(data: PortfolioDomainCreate) {
    return this.request<PortfolioDomain>('/portfolio', {
      method: 'POST',
      body: JSON.stringify(data),
    })
  }

  async getPortfolioDomain(id: number) {
    return this.request<PortfolioDomain>(`/portfolio/${id}`)
  }

  async updatePortfolioDomain(id: number, data: Partial<PortfolioDomainCreate>) {
    return this.request<PortfolioDomain>(`/portfolio/${id}`, {
      method: 'PUT',
      body: JSON.stringify(data),
    })
  }

  async deletePortfolioDomain(id: number) {
    return this.request<void>(`/portfolio/${id}`, {
      method: 'DELETE',
    })
  }

  async markDomainSold(id: number, saleDate: string, salePrice: number) {
    return this.request<PortfolioDomain>(`/portfolio/${id}/sell`, {
      method: 'POST',
      body: JSON.stringify({
        sale_date: saleDate,
        sale_price: salePrice,
      }),
    })
  }

  async refreshDomainValue(id: number) {
    return this.request<PortfolioDomain>(`/portfolio/${id}/refresh-value`, {
      method: 'POST',
    })
  }

  // ============== Portfolio DNS Verification ==============

  async startPortfolioDnsVerification(id: number) {
    return this.request<DNSVerificationStart>(`/portfolio/${id}/verify-dns`, {
      method: 'POST',
    })
  }

  async checkPortfolioDnsVerification(id: number) {
    return this.request<DNSVerificationCheck>(`/portfolio/${id}/verify-dns/check`)
  }

  async getVerifiedPortfolioDomains() {
    return this.request<PortfolioDomain[]>('/portfolio/verified')
  }

  async getDomainValuation(domain: string) {
    return this.request<DomainValuation>(`/portfolio/valuation/${domain}`)
  }

  // ============== Market Feed (Unified) ==============

  /**
   * Get unified market feed combining Pounce Direct listings + external auctions.
   * This is the main feed for the Market page.
   */
  async getMarketFeed(options: {
    source?: 'all' | 'pounce' | 'external'
    keyword?: string
    tld?: string
    minPrice?: number
    maxPrice?: number
    minScore?: number
    endingWithin?: number
    verifiedOnly?: boolean
    sortBy?: 'score' | 'price_asc' | 'price_desc' | 'time' | 'newest'
    limit?: number
    offset?: number
  } = {}) {
    const params = new URLSearchParams()
    
    if (options.source) params.append('source', options.source)
    if (options.keyword) params.append('keyword', options.keyword)
    if (options.tld) params.append('tld', options.tld)
    if (options.minPrice !== undefined) params.append('min_price', options.minPrice.toString())
    if (options.maxPrice !== undefined) params.append('max_price', options.maxPrice.toString())
    if (options.minScore !== undefined) params.append('min_score', options.minScore.toString())
    if (options.endingWithin !== undefined) params.append('ending_within', options.endingWithin.toString())
    if (options.verifiedOnly) params.append('verified_only', 'true')
    if (options.sortBy) params.append('sort_by', options.sortBy)
    if (options.limit !== undefined) params.append('limit', options.limit.toString())
    if (options.offset !== undefined) params.append('offset', options.offset.toString())
    
    return this.request<{
      items: Array<{
        id: string
        domain: string
        tld: string
        price: number
        currency: string
        price_type: 'bid' | 'fixed' | 'negotiable'
        status: 'auction' | 'instant'
        source: string
        is_pounce: boolean
        verified: boolean
        time_remaining?: string
        end_time?: string
        num_bids?: number
        slug?: string
        seller_verified: boolean
        url: string
        is_external: boolean
        pounce_score: number
      }>
      total: number
      pounce_direct_count: number
      auction_count: number
      sources: string[]
      last_updated: string
      filters_applied: Record<string, any>
    }>(`/auctions/feed?${params.toString()}`)
  }

  // ============== Auctions (Smart Pounce) ==============

  async getAuctions(
    keyword?: string,
    tld?: string,
    platform?: string,
    minBid?: number,
    maxBid?: number,
    endingSoon = false,
    sortBy = 'ending',
    limit = 100,
    offset = 0
  ) {
    const params = new URLSearchParams({
      sort_by: sortBy,
      limit: limit.toString(),
      offset: offset.toString(),
      ending_soon: endingSoon.toString(),
    })
    if (keyword) params.append('keyword', keyword)
    if (tld) params.append('tld', tld)
    if (platform) params.append('platform', platform)
    if (minBid !== undefined) params.append('min_bid', minBid.toString())
    if (maxBid !== undefined) params.append('max_bid', maxBid.toString())
    
    return this.request<{
      auctions: Array<{
        domain: string
        platform: string
        platform_url: string
        current_bid: number
        currency: string
        num_bids: number
        end_time: string
        time_remaining: string
        buy_now_price: number | null
        reserve_met: boolean | null
        traffic: number | null
        age_years: number | null
        tld: string
        affiliate_url: string
      }>
      total: number
      platforms_searched: string[]
      last_updated: string
    }>(`/auctions?${params.toString()}`)
  }

  async getEndingSoonAuctions(hours = 1, limit = 10) {
    return this.request<Array<{
      domain: string
      platform: string
      platform_url: string
      current_bid: number
      currency: string
      num_bids: number
      end_time: string
      time_remaining: string
      buy_now_price: number | null
      reserve_met: boolean | null
      traffic: number | null
      age_years: number | null
      tld: string
      affiliate_url: string
    }>>(`/auctions/ending-soon?hours=${hours}&limit=${limit}`)
  }

  async getHotAuctions(limit = 10) {
    return this.request<Array<{
      domain: string
      platform: string
      platform_url: string
      current_bid: number
      currency: string
      num_bids: number
      end_time: string
      time_remaining: string
      buy_now_price: number | null
      reserve_met: boolean | null
      traffic: number | null
      age_years: number | null
      tld: string
      affiliate_url: string
    }>>(`/auctions/hot?limit=${limit}`)
  }

  async getAuctionOpportunities() {
    return this.request<{
      opportunities: Array<{
        auction: {
          domain: string
          platform: string
          platform_url: string
          current_bid: number
          currency: string
          num_bids: number
          end_time: string
          time_remaining: string
          buy_now_price: number | null
          reserve_met: boolean | null
          traffic: number | null
          age_years: number | null
          tld: string
          affiliate_url: string
        }
        analysis: {
          estimated_value: number
          current_bid: number
          value_ratio: number
          potential_profit: number
          opportunity_score: number
          recommendation: string
        }
      }>
      strategy_tips: string[]
      generated_at: string
    }>('/auctions/opportunities')
  }

  async getAuctionPlatformStats() {
    return this.request<Array<{
      platform: string
      active_auctions: number
      avg_bid: number
      ending_soon: number
    }>>('/auctions/stats')
  }

  // ============== Price Alerts ==============

  async getPriceAlerts(activeOnly = false) {
    const params = activeOnly ? '?active_only=true' : ''
    return this.request<PriceAlert[]>(`/price-alerts${params}`)
  }

  async createPriceAlert(tld: string, targetPrice?: number, thresholdPercent = 5) {
    return this.request<PriceAlert>('/price-alerts', {
      method: 'POST',
      body: JSON.stringify({
        tld: tld.replace(/^\./, ''),
        target_price: targetPrice,
        threshold_percent: thresholdPercent,
      }),
    })
  }

  async getPriceAlertStatus(tld: string) {
    return this.request<{ tld: string; has_alert: boolean; is_active: boolean }>(
      `/price-alerts/status/${tld.replace(/^\./, '')}`
    )
  }

  async getPriceAlert(tld: string) {
    return this.request<PriceAlert>(`/price-alerts/${tld.replace(/^\./, '')}`)
  }

  async updatePriceAlert(tld: string, data: { is_active?: boolean; target_price?: number; threshold_percent?: number }) {
    return this.request<PriceAlert>(`/price-alerts/${tld.replace(/^\./, '')}`, {
      method: 'PUT',
      body: JSON.stringify(data),
    })
  }

  async deletePriceAlert(tld: string) {
    return this.request<void>(`/price-alerts/${tld.replace(/^\./, '')}`, {
      method: 'DELETE',
    })
  }

  async togglePriceAlert(tld: string) {
    return this.request<PriceAlert>(`/price-alerts/${tld.replace(/^\./, '')}/toggle`, {
      method: 'POST',
    })
  }
}

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

export interface PortfolioDomain {
  id: number
  domain: string
  purchase_date: string | null
  purchase_price: number | null
  purchase_registrar: string | null
  registrar: string | null
  renewal_date: string | null
  renewal_cost: number | null
  auto_renew: boolean
  estimated_value: number | null
  value_updated_at: string | null
  is_sold: boolean
  sale_date: string | null
  sale_price: number | null
  status: string
  notes: string | null
  tags: string | null
  roi: number | null
  // DNS Verification fields
  is_dns_verified: boolean
  verification_status: string  // 'unverified' | 'pending' | 'verified' | 'failed'
  verification_code: string | null
  verified_at: string | null
  created_at: string
  updated_at: string
}

export interface DNSVerificationStart {
  domain_id: number
  domain: string
  verification_code: string
  dns_record_type: string
  dns_record_name: string
  dns_record_value: string
  instructions: string
  status: string
}

export interface DNSVerificationCheck {
  verified: boolean
  status: string
  message: string
}

export interface PortfolioSummary {
  total_domains: number
  active_domains: number
  sold_domains: number
  total_invested: number
  total_value: number
  total_sold_value: number
  unrealized_profit: number
  realized_profit: number
  overall_roi: number
}

export interface PortfolioDomainCreate {
  domain: string
  purchase_date?: string
  purchase_price?: number
  purchase_registrar?: string
  registrar?: string
  renewal_date?: string
  renewal_cost?: number
  auto_renew?: boolean
  notes?: string
  tags?: string
}

export interface DomainValuation {
  domain: string
  estimated_value: number
  currency: string
  scores: {
    length: number
    tld: number
    keyword: number
    brandability: number
    overall: number
  }
  factors: {
    length: number
    tld: string
    has_numbers: boolean
    has_hyphens: boolean
    is_dictionary_word: boolean
  }
  confidence: string
  source: string
  calculated_at: string
  valuation_formula?: string
}

export interface PriceAlert {
  id: number
  tld: string
  is_active: boolean
  target_price: number | null
  threshold_percent: number
  last_notified_at: string | null
  last_notified_price: number | null
  created_at: string
}

// Domain Health Check Types
export type HealthStatus = 'healthy' | 'weakening' | 'parked' | 'critical' | 'unknown'

export interface DomainHealthReport {
  domain: string
  status: HealthStatus
  score: number  // 0-100
  checked_at: string
  signals: string[]
  recommendations: string[]
  dns: {
    has_ns: boolean
    has_a: boolean
    has_mx: boolean
    nameservers: string[]
    is_parked: boolean
    parking_provider?: string
    error?: string
  }
  http: {
    is_reachable: boolean
    status_code?: number
    is_parked: boolean
    parking_keywords?: string[]
    content_length?: number
    error?: string
  }
  ssl: {
    has_certificate: boolean
    is_valid: boolean
    expires_at?: string
    days_until_expiry?: number
    issuer?: string
    error?: string
  }
}

// ============== Admin API Extension ==============

class AdminApiClient extends ApiClient {
  // Admin Stats
  async getAdminStats() {
    return this.request<any>('/admin/stats')
  }

  async getAdminEarnings() {
    return this.request<{
      mrr: number
      arr: number
      paying_customers: number
      tier_breakdown: {
        scout: { count: number; revenue: number }
        trader: { count: number; revenue: number }
        tycoon: { count: number; revenue: number }
      }
      new_subscriptions: { week: number; month: number }
      churn: { month: number }
      yield_revenue_month: number
      total_revenue_month: number
      timestamp: string
    }>('/admin/earnings')
  }

  async getAdminEarningsHistory(months: number = 12) {
    return this.request<{
      monthly_data: Array<{
        month: string
        mrr: number
        arr: number
        paying_customers: number
        scout: number
        trader: number
        tycoon: number
        new_subscriptions: number
        churn: number
      }>
      metrics: {
        mrr_growth_percent: number
        arpu: number
        ltv: number
        total_customers: number
      }
      timestamp: string
    }>(`/admin/earnings/history?months=${months}`)
  }

  // Admin Users
  async getAdminUsers(limit: number = 50, offset: number = 0, search?: string) {
    const params = new URLSearchParams({ limit: String(limit), offset: String(offset) })
    if (search) params.append('search', search)
    return this.request<any>(`/admin/users?${params}`)
  }

  async getAdminUser(userId: number) {
    return this.request<any>(`/admin/users/${userId}`)
  }

  async updateAdminUser(userId: number, data: { name?: string; is_active?: boolean; is_verified?: boolean; is_admin?: boolean }) {
    return this.request<any>(`/admin/users/${userId}`, {
      method: 'PATCH',
      body: JSON.stringify(data),
    })
  }

  async deleteAdminUser(userId: number) {
    return this.request<any>(`/admin/users/${userId}`, { method: 'DELETE' })
  }

  async upgradeUser(userId: number, tier: string) {
    return this.request<any>(`/admin/users/${userId}/upgrade?tier=${tier}`, { method: 'POST' })
  }

  // Newsletter
  async getAdminNewsletter(limit: number = 100, offset: number = 0, activeOnly: boolean = true) {
    const params = new URLSearchParams({ 
      limit: String(limit), 
      offset: String(offset),
      active_only: String(activeOnly),
    })
    return this.request<any>(`/admin/newsletter?${params}`)
  }

  async exportNewsletterEmails() {
    return this.request<{ emails: string[]; count: number }>('/admin/newsletter/export')
  }

  // TLD Scraping
  async triggerTldScrape() {
    return this.request<any>('/admin/scrape-tld-prices', { method: 'POST' })
  }

  async getTldPriceStats() {
    return this.request<any>('/admin/tld-prices/stats')
  }

  // Auction Scraping
  async triggerAuctionScrape() {
    return this.request<any>('/auctions/admin/scrape', { method: 'POST' })
  }

  async getAuctionScrapeStatus() {
    return this.request<any>('/auctions/admin/scrape-status')
  }

  // System
  async getSystemHealth() {
    return this.request<any>('/admin/system/health')
  }

  async makeUserAdmin(email: string) {
    return this.request<any>(`/admin/system/make-admin?email=${encodeURIComponent(email)}`, { method: 'POST' })
  }

  // Price Alerts
  async getAdminPriceAlerts(limit = 100, offset = 0) {
    return this.request<{
      alerts: Array<{
        id: number
        tld: string
        target_price: number | null
        alert_type: string
        created_at: string
        user: { id: number; email: string; name: string | null }
      }>
      total: number
    }>(`/admin/price-alerts?limit=${limit}&offset=${offset}`)
  }

  // Domain Health Check
  async triggerDomainChecks() {
    return this.request<{
      message: string
      domains_queued: number
      started_at: string
    }>('/admin/domains/check-all', { method: 'POST' })
  }

  // Email Test
  async sendTestEmail() {
    return this.request<{
      message: string
      sent_to: string
      timestamp: string
    }>('/admin/system/test-email', { method: 'POST' })
  }

  // Scheduler Status
  async getSchedulerStatus() {
    return this.request<{
      scheduler_running: boolean
      jobs: Array<{
        id: string
        name: string
        next_run: string | null
        trigger: string
      }>
      last_runs: {
        tld_scrape: string | null
        auction_scrape: string | null
        domain_check: string | null
      }
      timestamp: string
    }>('/admin/system/scheduler')
  }

  async listDbBackups(limit: number = 20) {
    const query = new URLSearchParams({ limit: String(limit) })
    return this.request<{ backups: Array<{ name: string; path: string; size_bytes: number; modified_at: string }> }>(
      `/admin/system/backups?${query}`
    )
  }

  async createDbBackup(verify: boolean = true) {
    const query = new URLSearchParams({ verify: String(verify) })
    return this.request<{
      status: string
      backup: { path: string; size_bytes: number; created_at: string; verified: boolean; verification_detail: string | null }
    }>(`/admin/system/backups?${query}`, { method: 'POST' })
  }

  async runOpsAlertsNow() {
    return this.request<any>('/admin/system/ops-alerts/run', { method: 'POST' })
  }

  async getOpsAlertsHistory(limit: number = 100) {
    const query = new URLSearchParams({ limit: String(limit) })
    return this.request<{ events: any[] }>(`/admin/system/ops-alerts/history?${query}`)
  }

  // User Export
  async exportUsersCSV() {
    return this.request<{
      csv: string
      count: number
      exported_at: string
    }>('/admin/users/export')
  }

  // Bulk Upgrade
  async bulkUpgradeUsers(userIds: number[], tier: string) {
    return this.request<{
      message: string
      tier: string
      upgraded: Array<{ user_id: number; email: string }>
      failed: Array<{ user_id: number; reason: string }>
      total_upgraded: number
      total_failed: number
    }>('/admin/users/bulk-upgrade', {
      method: 'POST',
      body: JSON.stringify({ user_ids: userIds, tier }),
    })
  }

  // Activity Log
  async getActivityLog(limit = 50, offset = 0) {
    return this.request<{
      logs: Array<{
        id: number
        action: string
        details: string
        created_at: string
        admin: { id: number; email: string; name: string | null }
      }>
      total: number
    }>(`/admin/activity-log?limit=${limit}&offset=${offset}`)
  }

  // ============== Blog ==============

  async getBlogPosts(limit = 10, offset = 0, category?: string, tag?: string) {
    let url = `/blog/posts?limit=${limit}&offset=${offset}`
    if (category) url += `&category=${encodeURIComponent(category)}`
    if (tag) url += `&tag=${encodeURIComponent(tag)}`
    return this.request<{
      posts: Array<{
        id: number
        title: string
        slug: string
        excerpt: string | null
        cover_image: string | null
        category: string | null
        tags: string[]
        is_published: boolean
        published_at: string | null
        created_at: string
        view_count: number
        author: { id: number; name: string | null }
      }>
      total: number
      limit: number
      offset: number
    }>(url)
  }

  async getBlogPost(slug: string) {
    return this.request<{
      id: number
      title: string
      slug: string
      excerpt: string | null
      content: string
      cover_image: string | null
      category: string | null
      tags: string[]
      meta_title: string | null
      meta_description: string | null
      is_published: boolean
      published_at: string | null
      created_at: string
      updated_at: string
      view_count: number
      author: { id: number; name: string | null }
    }>(`/blog/posts/${slug}`)
  }

  async getBlogPostMeta(slug: string) {
    return this.request<{
      id: number
      title: string
      slug: string
      excerpt: string | null
      cover_image: string | null
      category: string | null
      tags: string[]
      meta_title: string | null
      meta_description: string | null
      is_published: boolean
      published_at: string | null
      created_at: string
      updated_at: string
      view_count: number
      author: { id: number; name: string | null }
    }>(`/blog/posts/${slug}/meta`)
  }

  async getBlogCategories() {
    return this.request<{
      categories: Array<{ name: string; count: number }>
    }>('/blog/posts/categories')
  }

  async getFeaturedPosts(limit = 3) {
    return this.request<{
      posts: Array<{
        id: number
        title: string
        slug: string
        excerpt: string | null
        cover_image: string | null
        category: string | null
        published_at: string | null
      }>
    }>(`/blog/posts/featured?limit=${limit}`)
  }

  // Admin Blog
  async getAdminBlogPosts(limit = 50, offset = 0, status?: 'published' | 'draft') {
    let url = `/blog/admin/posts?limit=${limit}&offset=${offset}`
    if (status) url += `&status_filter=${status}`
    return this.request<{
      posts: Array<{
        id: number
        title: string
        slug: string
        excerpt: string | null
        cover_image: string | null
        category: string | null
        tags: string[]
        is_published: boolean
        published_at: string | null
        created_at: string
        view_count: number
        author: { id: number; name: string | null }
      }>
      total: number
    }>(url)
  }

  async createBlogPost(data: {
    title: string
    content: string
    excerpt?: string
    cover_image?: string
    category?: string
    tags?: string[]
    meta_title?: string
    meta_description?: string
    is_published?: boolean
  }) {
    return this.request<any>('/blog/admin/posts', {
      method: 'POST',
      body: JSON.stringify(data),
    })
  }

  async updateBlogPost(postId: number, data: {
    title?: string
    content?: string
    excerpt?: string
    cover_image?: string
    category?: string
    tags?: string[]
    meta_title?: string
    meta_description?: string
    is_published?: boolean
  }) {
    return this.request<any>(`/blog/admin/posts/${postId}`, {
      method: 'PATCH',
      body: JSON.stringify(data),
    })
  }

  async deleteBlogPost(postId: number) {
    return this.request<any>(`/blog/admin/posts/${postId}`, {
      method: 'DELETE',
    })
  }

  async publishBlogPost(postId: number) {
    return this.request<any>(`/blog/admin/posts/${postId}/publish`, {
      method: 'POST',
    })
  }

  async unpublishBlogPost(postId: number) {
    return this.request<any>(`/blog/admin/posts/${postId}/unpublish`, {
      method: 'POST',
    })
  }

  // =========================================================================
  // YIELD / Intent Routing API
  // =========================================================================

  async analyzeYieldDomain(domain: string) {
    return this.request<{
      domain: string
      intent: {
        category: string
        subcategory: string | null
        confidence: number
        keywords_matched: string[]
        suggested_partners: string[]
        monetization_potential: 'high' | 'medium' | 'low'
      }
      value: {
        estimated_monthly_min: number
        estimated_monthly_max: number
        currency: string
        potential: string
        confidence: number
        geo: string | null
      }
      partners: string[]
      monetization_potential: string
    }>(`/yield/analyze?domain=${encodeURIComponent(domain)}`, {
      method: 'POST',
    })
  }

  async getYieldDashboard() {
    return this.request<{
      stats: {
        total_domains: number
        active_domains: number
        pending_domains: number
        monthly_revenue: number
        monthly_clicks: number
        monthly_conversions: number
        lifetime_revenue: number
        lifetime_clicks: number
        lifetime_conversions: number
        pending_payout: number
        next_payout_date: string | null
        currency: string
      }
      domains: YieldDomain[]
      recent_transactions: YieldTransaction[]
      top_domains: YieldDomain[]
    }>('/yield/dashboard')
  }

  async getYieldDomains(params?: { status?: string; limit?: number; offset?: number }) {
    const queryParams = new URLSearchParams()
    if (params?.status) queryParams.set('status', params.status)
    if (params?.limit) queryParams.set('limit', params.limit.toString())
    if (params?.offset) queryParams.set('offset', params.offset.toString())
    
    return this.request<{
      domains: YieldDomain[]
      total: number
      total_active: number
      total_revenue: number
      total_clicks: number
    }>(`/yield/domains?${queryParams}`)
  }

  async getYieldDomain(domainId: number) {
    return this.request<YieldDomain>(`/yield/domains/${domainId}`)
  }

  async activateYieldDomain(domain: string, acceptTerms: boolean = true) {
    return this.request<{
      domain_id: number
      domain: string
      status: string
      intent: {
        category: string
        subcategory: string | null
        confidence: number
        keywords_matched: string[]
        suggested_partners: string[]
        monetization_potential: string
      }
      value_estimate: {
        estimated_monthly_min: number
        estimated_monthly_max: number
        currency: string
        potential: string
        confidence: number
        geo: string | null
      }
      dns_instructions: {
        domain: string
        nameservers: string[]
        cname_host: string
        cname_target: string
        verification_url: string
      }
      landing?: {
        template: string
        headline: string
        seo_intro: string
        cta_label: string
        model?: string | null
        generated_at?: string | null
      } | null
      message: string
    }>('/yield/activate', {
      method: 'POST',
      body: JSON.stringify({ domain, accept_terms: acceptTerms }),
    })
  }

  async verifyYieldDomainDNS(domainId: number) {
    return this.request<{
      domain: string
      verified: boolean
      expected_ns: string[]
      actual_ns: string[]
      cname_ok: boolean
      error: string | null
      checked_at: string
    }>(`/yield/domains/${domainId}/verify`, {
      method: 'POST',
    })
  }

  async updateYieldDomain(domainId: number, data: {
    active_route?: string
    landing_page_url?: string
    status?: string
  }) {
    return this.request<YieldDomain>(`/yield/domains/${domainId}`, {
      method: 'PATCH',
      body: JSON.stringify(data),
    })
  }

  async deleteYieldDomain(domainId: number) {
    return this.request<{ message: string }>(`/yield/domains/${domainId}`, {
      method: 'DELETE',
    })
  }

  async getYieldTransactions(params?: { 
    domain_id?: number
    status?: string
    limit?: number
    offset?: number 
  }) {
    const queryParams = new URLSearchParams()
    if (params?.domain_id) queryParams.set('domain_id', params.domain_id.toString())
    if (params?.status) queryParams.set('status', params.status)
    if (params?.limit) queryParams.set('limit', params.limit.toString())
    if (params?.offset) queryParams.set('offset', params.offset.toString())
    
    return this.request<{
      transactions: YieldTransaction[]
      total: number
      total_gross: number
      total_net: number
    }>(`/yield/transactions?${queryParams}`)
  }

  async getYieldPayouts(params?: { status?: string; limit?: number; offset?: number }) {
    const queryParams = new URLSearchParams()
    if (params?.status) queryParams.set('status', params.status)
    if (params?.limit) queryParams.set('limit', params.limit.toString())
    if (params?.offset) queryParams.set('offset', params.offset.toString())
    
    return this.request<{
      payouts: YieldPayout[]
      total: number
      total_paid: number
      total_pending: number
    }>(`/yield/payouts?${queryParams}`)
  }

  async getYieldPartners(category?: string) {
    const params = category ? `?category=${encodeURIComponent(category)}` : ''
    return this.request<YieldPartner[]>(`/yield/partners${params}`)
  }

  async getTelemetryKpis(days: number = 30) {
    const query = new URLSearchParams({ days: String(days) })
    return this.request<{
      window: { days: number; start: string; end: string }
      deal: {
        listing_views: number
        inquiries_created: number
        seller_replied_inquiries: number
        inquiry_reply_rate: number
        listings_with_inquiries: number
        listings_sold: number
        inquiry_to_sold_listing_rate: number
        median_reply_seconds: number | null
        median_time_to_sold_seconds: number | null
      }
      yield: {
        connected_domains: number
        clicks: number
        conversions: number
        conversion_rate: number
        payouts_paid: number
        payouts_paid_amount_total: number
      }
    }>(`/telemetry/kpis?${query}`)
  }

  async getReferralKpis(days: number = 30, limit: number = 200, offset: number = 0) {
    const query = new URLSearchParams({ days: String(days), limit: String(limit), offset: String(offset) })
    return this.request<{
      window: { days: number; start: string; end: string }
      totals: Record<string, number>
      referrers: Array<{
        user_id: number
        email: string
        invite_code: string | null
        created_at: string
        referred_users_total: number
        referred_users_window: number
        referral_link_views_window: number
      }>
    }>(`/telemetry/referrals?${query}`)
  }

  // ============================================================================
  // DROPS - Zone File Analysis (.ch / .li)
  // ============================================================================

  async getDropsStats() {
    return this.request<{
      ch: { domain_count: number; last_sync: string | null }
      li: { domain_count: number; last_sync: string | null }
      daily_drops: number
    }>('/drops/stats')
  }

  async getDrops(params?: {
    tld?: 'ch' | 'li' | 'xyz' | 'org' | 'online' | 'info' | 'dev' | 'app'
    hours?: number
    min_length?: number
    max_length?: number
    exclude_numeric?: boolean
    exclude_hyphen?: boolean
    keyword?: string
    limit?: number
    offset?: number
  }) {
    const query = new URLSearchParams()
    if (params?.tld) query.set('tld', params.tld)
    if (params?.hours) query.set('hours', params.hours.toString())
    if (params?.min_length) query.set('min_length', params.min_length.toString())
    if (params?.max_length) query.set('max_length', params.max_length.toString())
    if (params?.exclude_numeric) query.set('exclude_numeric', 'true')
    if (params?.exclude_hyphen) query.set('exclude_hyphen', 'true')
    if (params?.keyword) query.set('keyword', params.keyword)
    if (params?.limit) query.set('limit', params.limit.toString())
    if (params?.offset) query.set('offset', params.offset.toString())
    
    return this.request<{
      total: number
      items: Array<{
        id: number
        domain: string
        tld: string
        dropped_date: string
        length: number
        is_numeric: boolean
        has_hyphen: boolean
        availability_status: 'available' | 'dropping_soon' | 'taken' | 'unknown'
        last_status_check: string | null
        deletion_date: string | null
      }>
    }>(`/drops?${query}`)
  }

  async getDropsTlds() {
    return this.request<{
      tlds: Array<{
        tld: string
        name: string
        flag: string
        registry: string
      }>
    }>('/drops/tlds')
  }

  async checkDropStatus(dropId: number) {
    return this.request<{
      id: number
      domain: string
      status: 'available' | 'dropping_soon' | 'taken' | 'unknown'
      rdap_status: string[]
      can_register_now: boolean
      should_track: boolean
      message: string
      deletion_date: string | null
    }>(`/drops/check-status/${dropId}`, { method: 'POST' })
  }

  async trackDrop(dropId: number) {
    return this.request<{
      status: string
      domain: string
      message: string
    }>(`/drops/track/${dropId}`, { method: 'POST' })
  }
}

// Yield Types
export interface YieldDomain {
  id: number
  domain: string
  status: 'pending' | 'verifying' | 'active' | 'paused' | 'inactive' | 'error'
  detected_intent: string | null
  intent_confidence: number
  active_route: string | null
  partner_name: string | null
  dns_verified: boolean
  dns_verified_at: string | null
  connected_at: string | null
  landing_template?: string | null
  landing_headline?: string | null
  landing_intro?: string | null
  landing_cta_label?: string | null
  landing_model?: string | null
  landing_generated_at?: string | null
  total_clicks: number
  total_conversions: number
  total_revenue: number
  currency: string
  activated_at: string | null
  created_at: string
}

export interface YieldTransaction {
  id: number
  event_type: 'click' | 'lead' | 'sale'
  partner_slug: string
  click_id?: string | null
  gross_amount: number
  net_amount: number
  currency: string
  status: 'pending' | 'confirmed' | 'paid' | 'rejected'
  geo_country: string | null
  created_at: string
  confirmed_at: string | null
}

export interface YieldPayout {
  id: number
  amount: number
  currency: string
  period_start: string
  period_end: string
  transaction_count: number
  status: 'pending' | 'processing' | 'completed' | 'failed'
  payment_method: string | null
  payment_reference: string | null
  created_at: string
  completed_at: string | null
}

export interface YieldPartner {
  slug: string
  name: string
  network: string
  intent_categories: string[]
  geo_countries: string[]
  payout_type: string
  description: string | null
  logo_url: string | null
}

export const api = new AdminApiClient()

