import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'

export interface ShopifyProduct {
  id: number
  title: string
  handle: string
  body_html: string
  vendor: string
  product_type: string
  created_at: string
  updated_at: string
  published_at: string
  status: string
  tags: string
  variants: Array<{
    id: number
    product_id: number
    title: string
    price: string
    sku: string
    position: number
    inventory_quantity: number
    compare_at_price: string | null
    fulfillment_service: string
    inventory_management: string
    option1: string | null
    option2: string | null
    option3: string | null
  }>
  options: Array<{
    id: number
    product_id: number
    name: string
    position: number
    values: string[]
  }>
  images: Array<{
    id: number
    product_id: number
    position: number
    src: string
    width: number
    height: number
  }>
}

export interface ShopifyOrder {
  id: number
  name: string // Order name like "#1001"
  order_number: number
  email: string
  created_at: string
  updated_at: string
  cancelled_at: string | null
  closed_at: string | null
  currency: string
  current_total_price: string
  current_subtotal_price: string
  current_total_tax: string
  financial_status: string // paid, pending, refunded, etc.
  fulfillment_status: string | null // fulfilled, partial, null
  customer: {
    id: number
    email: string
    first_name: string
    last_name: string
    phone: string | null
    orders_count: number
    total_spent: string
  }
  billing_address: {
    first_name: string
    last_name: string
    address1: string
    address2: string | null
    city: string
    province: string
    country: string
    zip: string
    phone: string
    name: string
  }
  shipping_address: {
    first_name: string
    last_name: string
    address1: string
    address2: string | null
    city: string
    province: string
    country: string
    zip: string
    phone: string
    name: string
  }
  line_items: Array<{
    id: number
    product_id: number
    variant_id: number
    title: string
    quantity: number
    sku: string
    variant_title: string | null
    vendor: string | null
    price: string
    total_discount: string
  }>
  note: string | null
  tags: string
}

export interface ShopifyCustomer {
  id: number
  email: string
  created_at: string
  updated_at: string
  first_name: string
  last_name: string
  orders_count: number
  state: string // enabled, disabled, declined, invited
  total_spent: string
  last_order_id: number | null
  note: string | null
  verified_email: boolean
  phone: string | null
  tags: string
  currency: string
  accepts_marketing: boolean
  accepts_marketing_updated_at: string
  default_address?: {
    id: number
    customer_id: number
    first_name: string
    last_name: string
    company: string | null
    address1: string
    address2: string | null
    city: string
    province: string
    country: string
    zip: string
    phone: string
    name: string
    province_code: string
    country_code: string
    default: boolean
  }
  addresses: Array<{
    id: number
    customer_id: number
    first_name: string
    last_name: string
    company: string | null
    address1: string
    address2: string | null
    city: string
    province: string
    country: string
    zip: string
    phone: string
    name: string
  }>
}

// Rate limiting configuration
const RATE_LIMIT_DELAY = 200 // 200ms = 5 requests per second (Shopify standard limit)
let lastRequestTime = 0

// Wait for rate limit
async function rateLimitWait() {
  const now = Date.now()
  const timeSinceLastRequest = now - lastRequestTime
  if (timeSinceLastRequest < RATE_LIMIT_DELAY) {
    await new Promise(resolve => setTimeout(resolve, RATE_LIMIT_DELAY - timeSinceLastRequest))
  }
  lastRequestTime = Date.now()
}

// Make authenticated API request to Shopify
export async function shopifyApiRequest(
  storeId: string,
  endpoint: string,
  method: string = 'GET',
  body?: any
): Promise<any> {
  const supabaseUrl = Deno.env.get('SUPABASE_URL')!
  const supabaseServiceKey = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
  const supabase = createClient(supabaseUrl, supabaseServiceKey)

  // Get store credentials
  const { data: store, error: storeError } = await supabase
    .from('stores')
    .select('store_name, store_url, api_key')
    .eq('id', storeId)
    .eq('platform_name', 'shopify')
    .single()

  if (storeError || !store) {
    throw new Error('Shopify store not found')
  }

  if (!store.api_key) {
    throw new Error('Shopify access token not found')
  }

  // Build API URL
  const apiVersion = '2024-01' // Use stable API version
  const baseUrl = `https://${store.store_url}/admin/api/${apiVersion}`
  const url = `${baseUrl}${endpoint}`

  // Apply rate limiting
  await rateLimitWait()

  // Make request
  const options: RequestInit = {
    method,
    headers: {
      'X-Shopify-Access-Token': store.api_key,
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    }
  }

  if (body && (method === 'POST' || method === 'PUT' || method === 'PATCH')) {
    options.body = JSON.stringify(body)
  }

  const response = await fetch(url, options)

  // Check for rate limit headers
  const rateLimitRemaining = response.headers.get('X-Shopify-Shop-Api-Call-Limit')
  if (rateLimitRemaining) {
    console.log(`[Shopify] Rate limit: ${rateLimitRemaining}`)
  }

  if (!response.ok) {
    const errorText = await response.text()
    console.error(`[Shopify] API error (${response.status}):`, errorText)
    throw new Error(`Shopify API error: ${response.status} - ${errorText}`)
  }

  return await response.json()
}

// Fetch products with pagination
export async function fetchProducts(
  storeId: string,
  limit: number = 250, // Shopify max is 250
  sinceId?: number
): Promise<ShopifyProduct[]> {
  let endpoint = `/products.json?limit=${limit}`
  if (sinceId) {
    endpoint += `&since_id=${sinceId}`
  }

  const response = await shopifyApiRequest(storeId, endpoint)
  return response.products || []
}

// Fetch all products with automatic pagination
export async function fetchAllProducts(storeId: string): Promise<ShopifyProduct[]> {
  const allProducts: ShopifyProduct[] = []
  let sinceId: number | undefined = undefined
  let hasMore = true

  while (hasMore) {
    const products = await fetchProducts(storeId, 250, sinceId)

    if (products.length === 0) {
      hasMore = false
    } else {
      allProducts.push(...products)
      sinceId = products[products.length - 1].id
      hasMore = products.length === 250 // If we got max results, there might be more
    }
  }

  return allProducts
}

export interface ShopifyOrderFilters {
  status?: string;       // any, open, closed, cancelled
  financial_status?: string;  // paid, pending, refunded, etc.
  fulfillment_status?: string; // shipped, partial, unshipped, any
  created_at_min?: string;    // ISO 8601 datetime
  created_at_max?: string;    // ISO 8601 datetime
  updated_at_min?: string;    // ISO 8601 datetime
  updated_at_max?: string;    // ISO 8601 datetime
  customer_id?: string;       // Filter by customer ID
  email?: string;             // Filter by customer email
  name?: string;              // Filter by customer name
}

// Fetch orders with pagination
export async function fetchOrders(
  storeId: string,
  limit: number = 250,
  sinceId?: number,
  filters?: ShopifyOrderFilters
): Promise<ShopifyOrder[]> {
  let endpoint = `/orders.json?limit=${limit}`

  // Apply filters
  if (filters) {
    if (filters.status) {
      endpoint += `&status=${filters.status}`
    }
    if (filters.financial_status) {
      endpoint += `&financial_status=${filters.financial_status}`
    }
    if (filters.fulfillment_status) {
      endpoint += `&fulfillment_status=${filters.fulfillment_status}`
    }
    if (filters.created_at_min) {
      endpoint += `&created_at_min=${encodeURIComponent(filters.created_at_min)}`
    }
    if (filters.created_at_max) {
      endpoint += `&created_at_max=${encodeURIComponent(filters.created_at_max)}`
    }
    if (filters.updated_at_min) {
      endpoint += `&updated_at_min=${encodeURIComponent(filters.updated_at_min)}`
    }
    if (filters.updated_at_max) {
      endpoint += `&updated_at_max=${encodeURIComponent(filters.updated_at_max)}`
    }
    if (filters.email) {
      endpoint += `&email=${encodeURIComponent(filters.email)}`
    }
    if (filters.name) {
      endpoint += `&name=${encodeURIComponent(filters.name)}`
    }
  } else {
    // Default to 'any' status if no filters provided
    endpoint += `&status=any`
  }

  if (sinceId) {
    endpoint += `&since_id=${sinceId}`
  }

  const response = await shopifyApiRequest(storeId, endpoint)
  return response.orders || []
}

// Fetch all orders with automatic pagination
export async function fetchAllOrders(
  storeId: string,
  filters?: ShopifyOrderFilters
): Promise<ShopifyOrder[]> {
  const allOrders: ShopifyOrder[] = []
  let sinceId: number | undefined = undefined
  let hasMore = true

  while (hasMore) {
    const orders = await fetchOrders(storeId, 250, sinceId, filters)

    if (orders.length === 0) {
      hasMore = false
    } else {
      allOrders.push(...orders)
      sinceId = orders[orders.length - 1].id
      hasMore = orders.length === 250
    }
  }

  return allOrders
}

// Fetch a single order by ID
export async function fetchOrder(storeId: string, orderId: number): Promise<ShopifyOrder> {
  const response = await shopifyApiRequest(storeId, `/orders/${orderId}.json`)
  return response.order
}

// Fetch a single order by name (e.g., "#1001")
export async function fetchOrderByName(storeId: string, orderName: string): Promise<ShopifyOrder | null> {
  // Shopify's order name field is searchable
  const orders = await fetchOrders(storeId, 1, undefined, { name: orderName })
  return orders.length > 0 ? orders[0] : null
}

export interface ShopifyCustomerFilters {
  email?: string;    // Filter by exact email
  query?: string;    // GraphQL-style query for searching
}

// Fetch customers with pagination
export async function fetchCustomers(
  storeId: string,
  limit: number = 250,
  sinceId?: number,
  filters?: ShopifyCustomerFilters
): Promise<ShopifyCustomer[]> {
  let endpoint = `/customers.json?limit=${limit}`

  if (filters) {
    if (filters.email) {
      endpoint += `&email=${encodeURIComponent(filters.email)}`
    }
    if (filters.query) {
      endpoint += `&query=${encodeURIComponent(filters.query)}`
    }
  }

  if (sinceId) {
    endpoint += `&since_id=${sinceId}`
  }

  const response = await shopifyApiRequest(storeId, endpoint)
  return response.customers || []
}

// Fetch all customers with automatic pagination
export async function fetchAllCustomers(
  storeId: string,
  filters?: ShopifyCustomerFilters
): Promise<ShopifyCustomer[]> {
  const allCustomers: ShopifyCustomer[] = []
  let sinceId: number | undefined = undefined
  let hasMore = true

  while (hasMore) {
    const customers = await fetchCustomers(storeId, 250, sinceId, filters)

    if (customers.length === 0) {
      hasMore = false
    } else {
      allCustomers.push(...customers)
      sinceId = customers[customers.length - 1].id
      hasMore = customers.length === 250
    }
  }

  return allCustomers
}

// Register a webhook with Shopify
export async function registerWebhook(
  storeId: string,
  topic: string,
  address: string
): Promise<{ id: number; topic: string; address: string }> {
  const endpoint = '/webhooks.json'

  const response = await shopifyApiRequest(storeId, endpoint, 'POST', {
    webhook: {
      topic,
      address,
      format: 'json'
    }
  })

  return response.webhook
}

// List registered webhooks
export async function listWebhooks(storeId: string): Promise<any[]> {
  const endpoint = '/webhooks.json'
  const response = await shopifyApiRequest(storeId, endpoint)
  return response.webhooks || []
}

// Delete a webhook
export async function deleteWebhook(storeId: string, webhookId: number): Promise<void> {
  const endpoint = `/webhooks/${webhookId}.json`
  await shopifyApiRequest(storeId, endpoint, 'DELETE')
}
