import qs from 'qs'

export function toQS(
  obj: Record<string, any>,
  prefix = '',
  options = { arrayFormat: 'brackets' },
): string {
  if (!obj || typeof obj !== 'object') return ''

  return Object.keys(obj)
    .filter((key) => !['__proto__', 'constructor', 'prototype'].includes(key))
    .map((key) => {
      const value = obj[key]
      const fullKey = prefix ? `${prefix}[${key}]` : key

      if (
        typeof value === 'object' &&
        value !== null &&
        !Array.isArray(value)
      ) {
        return toQS(value, fullKey, options)
      } else if (Array.isArray(value)) {
        if (options.arrayFormat === 'brackets') {
          return value
            .map(
              (val) =>
                `${encodeURIComponent(fullKey)}[]=${encodeURIComponent(val)}`,
            )
            .join('&')
        } else if (options.arrayFormat === 'comma') {
          return `${encodeURIComponent(fullKey)}=${value.map(encodeURIComponent).join(',')}`
        } else if (options.arrayFormat === 'indices') {
          return value
            .map(
              (val, index) =>
                `${encodeURIComponent(fullKey)}[${index}]=${encodeURIComponent(val)}`,
            )
            .join('&')
        } else {
          return value
            .map(
              (val) =>
                `${encodeURIComponent(fullKey)}=${encodeURIComponent(val)}`,
            )
            .join('&')
        }
      } else {
        return `${encodeURIComponent(fullKey)}=${encodeURIComponent(value)}`
      }
    })
    .filter(Boolean)
    .join('&')
}

function getDealerStatusFilter(status: string) {
  const now = new Date()
  const nowISO = now.toISOString().split('T')[0] // YYYY-MM-DD
  const plus5 = new Date(now.getTime() + 5 * 24 * 60 * 60 * 1000)
  const plus5ISO = plus5.toISOString().split('T')[0]

  switch (status) {
    case 'new':
      return { dealer_subscriptions: { id: { $null: true } } }
    case 'active':
    case 'trialing':
      return { dealer_subscriptions: { sub_status: { $eq: status } } }
    case 'expiring_soon':
      return {
        dealer_subscriptions: {
          next_billing_date: { $gte: nowISO, $lte: plus5ISO },
        },
      }
    case 'expired':
      return { dealer_subscriptions: { next_billing_date: { $lt: nowISO } } }
    default:
      return {}
  }
}

// Modified async query functions (no need to await `toQS`)
export function getLeadsQuery({
  page,
  pageSize,
  sort = [],
  dealerId,
  search,
  isOpen,
}: {
  page: number
  pageSize: number
  sort?: string[]
  dealerId?: number
  search?: string
  isOpen?: boolean
}) {
  const filters: Record<string, any> = {}

  if (dealerId) {
    filters.dealer_admin = {
      id: {
        $eq: dealerId,
      },
    }
  }

  if (search && search.trim()) {
    filters.rb_user = { name: { $containsi: search.trim() } }
  }

  filters.is_open = { $eq: true }

  if (typeof isOpen === 'boolean') {
    filters.is_open = { $eq: isOpen }
  }

  const data = {
    fields: ['lead_status', 'createdAt', 'is_open'],
    populate: {
      rb_user: {
        fields: ['name', 'phone', 'email'],
      },
      product: {
        fields: ['name', 'is_featured', 'is_exclusive', 'admin_managed'],
      },
      dealer_admin: {
        fields: ['name'],
      },
      market_places: {
        fields: ['name'],
      },
    },
    filters,
    sort,
    pagination: {
      page,
      pageSize,
    },
  }

  return toQS(data)
}

export function getDealersQuery(
  page: number,
  pageSize: number,
  sort: string[] = [],
  status?: string[] | [],
  userId?: number | null | undefined,
  search?: string | null | undefined,
) {
  const filters: Record<string, any> = {}

  if (status && status.length) {
    filters.$or = []
    for (let i = 0; i < status.length; i++) {
      const data = getDealerStatusFilter(status[i])
      console.log(data)
      if (data && Object.keys(data).length > 0) {
        filters.$or.push(data)
      }
    }

    if (filters.$or.length === 0) {
      delete filters.$or
    }
  }

  if (userId) {
    filters.user = {
      id: {
        $eq: userId,
      },
    }
  }

  if (search && search.trim()) {
    filters.name = { $containsi: search.trim() } // Case-insensitive contains
  }

  console.log(JSON.stringify(filters))

  const data = {
    fields: [
      'company_name',
      'name',
      'dealers_logo',
      'street_address',
      'mobile',
      'email',
      'stripe_customer_id',
      'onboarded',
    ],
    populate: {
      dealer_subscriptions: {
        fields: ['sub_status', 'trial_end_date', 'next_billing_date'],
      },
    },
    sort,
    pagination: {
      page,
      pageSize,
    },
    filters: filters,
  }

  return qs.stringify(data, { encodeValuesOnly: true })
}

export function getNavbarQuery({
  metalType,
  productType,
}: {
  metalType: string
  productType?: string
}) {
  const filters: Record<string, any> = {}

  if (typeof metalType === 'string') {
    filters.metal = { $eq: metalType }
  }

  if (typeof productType === 'string') {
    filters.product_type = { $eq: productType }
  }

  const data = {
    fields: ['id', 'document_id', 'name', 'metal'],
    populate: {
      dealer_admin: {
        fields: ['company_name', 'name'],
      },
      product_images: {
        fields: ['url'],
      },
      pricing: {
        fields: ['*'],
      },
      comparisons: {
        fields: ['*'],
        populate: {
          product_images: {
            fields: ['*'],
          },
        },
      },
    },
    filters,
    sort: ['id:desc'],
    isNavbarOnly: true,
    pagination: {
      page: 1,
      pageSize: 6,
    },
  }

  return toQS(data)
}

// ["is_active:desc"]
export function getProductsQuery(
  page: number,
  pageSize: number,
  sort: string[] = [],
  isFeatured?: boolean | null,
  isExclusive?: boolean | null,
  adminManaged?: boolean | null,
  search?: string | null,
  dealerAdminId?: number | null,
  isActive?: boolean | null,
  productType?: string | null,
) {
  const filters: Record<string, any> = {}

  if (typeof isActive === 'boolean') {
    filters.is_active = { $eq: isActive }
  }

  if (typeof dealerAdminId === 'number') {
    filters.dealer_admin = { id: { $eq: dealerAdminId } }
  }

  if (typeof isFeatured === 'boolean') {
    filters.is_featured = { $eq: isFeatured }
  }

  if (typeof isExclusive === 'boolean') {
    filters.is_exclusive = { $eq: isExclusive }
  }

  if (typeof adminManaged === 'boolean') {
    filters.admin_managed = { $eq: adminManaged }
  }

  if (typeof productType === 'string') {
    filters.product_type = { $eq: productType }
  }

  if (search && search.trim()) {
    filters.name = { $containsi: search.trim() }
  }

  const data = {
    fields: [
      'id',
      'document_id',
      'name',
      'views',
      'is_active',
      'metal',
      'product_type',
      'weight',
      'is_active',
      'unit',
      'is_melt_price',
      'is_featured',
      'is_exclusive',
      'admin_managed',
      'mint_year',
      'description',
      'is_ira_approved',
      'coin_tag',
    ],
    populate: {
      dealer_admin: {
        fields: ['company_name', 'name'],
        populate: {
          plans: {
            fields: ['plan_name', 'featured_fee'],
          },
        },
      },
      product_images: {
        fields: ['url'],
      },
      pricing: {
        fields: ['*'],
      },
      comparisons: {
        fields: ['*'],
        populate: {
          product_images: {
            // Explicitly include product_images relation
            fields: ['*'], // Get all fields of product_images
          },
        },
      },
    },
    filters,
    sort,
    pagination: {
      page,
      pageSize,
    },
  }

  return toQS(data)
}

// 'dealer_admin.company_name:desc',
// 'is_active:desc',
// 'is_featured:desc',
// 'is_exclusive:desc',
// 'admin_managed:desc',
export function getFrontendProductsQuery(
  page: number,
  pageSize: number,
  sort: string[] = ['name:desc'],
  isFeatured?: boolean | null | undefined,
) {
  // Base filters - always include is_active
  const filters: Record<string, any> = {
    is_active: { $eq: true },
  }

  // Only add is_featured filter if it's explicitly true or false
  if (typeof isFeatured === 'boolean') {
    filters.is_featured = { $eq: isFeatured }
  }

  const data = {
    fields: [
      'name',
      'views',
      'is_active',
      'metal',
      'product_type',
      'weight',
      'is_active',
      'unit',
      'is_melt_price',
      'is_featured',
      'is_exclusive',
      'coin_tag',
    ],
    filters,
    populate: {
      dealer_admin: {
        fields: ['company_name', 'name', 'document_id', 'id'],
      },
      pricing: {
        fields: ['*'],
      },
    },
    sort,
    pagination: {
      page,
      pageSize,
    },
  }

  return toQS(data)
}

/**
 * get single products
 * populate with dealer admin
 * and pricing data
 */

export function getSingleProduct() {
  const data = {
    fields: [
      'name',
      'views',
      'is_active',
      'metal',
      'product_type',
      'weight',
      'is_active',
      'unit',
      'is_melt_price',
      'is_featured',
      'is_exclusive',
      'coin_tag',
    ],
    populate: {
      dealer_admin: {
        fields: ['company_name', 'name', 'document_id', 'id'],
      },
      pricing: {
        fields: ['*'],
      },
      comparisons: {
        fields: ['*'],
        populate: {
          product_images: {
            // Explicitly include product_images relation
            fields: ['*'], // Get all fields of product_images
          },
        },
      },
      product_images: {
        fields: ['*'],
      },
    },
  }

  return toQS(data)
}

export function getPaymentsQuery(
  page: number,
  pageSize: number,
  sort: string[] = [],
  search?: string | null,
  Status?: string | null,
) {
  const filters: Record<string, any> = {}

  if (typeof Status === 'string') {
    filters.invoice_status = { $eq: Status }
  }

  if (search && search.trim()) {
    filters.dealer_admin = { company_name: { $containsi: search.trim() } }
  }

  const data = {
    fields: ['invoice_id', 'createdAt', 'invoice_status'],
    populate: {
      dealer_admin: {
        fields: ['company_name'],
        populate: {
          dealer_subscriptions: {
            fields: ['price', 'next_billing_date'],
          },
        },
      },
    },
    filters,
    sort,
    pagination: {
      page,
      pageSize,
    },
  }

  return toQS(data)
}

export function getCartDetails({
  page,
  pageSize,
  userId,
}: {
  page: number
  pageSize: number
  userId: number
}) {
  const filters: Record<string, any> = {}

  if (typeof userId === 'number') {
    filters.rb_user = { id: { $eq: userId } }
  }

  const data = {
    fields: ['quantity'],
    populate: {
      product: {
        fields: ['name', 'description', 'mint_year', 'unit', 'weight', 'metal'],
        populate: {
          product_images: {
            fields: ['url', 'name'],
          },
          dealer_admin: {
            fields: ['name', 'mobile', 'email'],
          },
          pricing: {
            fields: ['price_type', 'price', 'adder', 'multiplier', 'max'],
          },
        },
      },
    },
    filters,
    pagination: {
      page,
      pageSize,
    },
  }

  return toQS(data)
}

export function getDealerAdminWithPlan() {
  const data = {
    fields: ['*'],
    populate: {
      plans: {
        fields: ['*'],
      },
    },
  }

  return toQS(data)
}

export function getPaymentDetails({
  page,
  pageSize,
  sort = [],
  search,
  dealerId,
  status,
  searchByDealer,
}: {
  page: number
  pageSize: number
  sort?: string[]
  search?: string
  dealerId?: number
  status?: string
  searchByDealer?: boolean
}) {
  const filters: Record<string, any> = {}

  if (search && search.trim()) {
    if (searchByDealer) {
      filters.dealer_admin = filters.dealer_admin || {}
      filters.dealer_admin.name = { $containsi: search.trim() }
    } else {
      filters.invoice_id = { $containsi: search.trim() }
    }
  }

  if (status && typeof status === 'string') {
    filters.invoice_status = { $eq: status }
  }

  if (dealerId) {
    filters.dealer_admin = filters.dealer_admin || {}
    filters.dealer_admin.id = { $eq: dealerId }
  }

  const data = {
    fields: ['*'],
    populate: {
      dealer_admin: {
        fields: ['*'],
        populate: {
          dealer_subscriptions: {
            fields: ['*'],
          },
        },
      },
    },
    sort,
    filters,
    pagination: {
      page,
      pageSize,
    },
  }
  return toQS(data)
}

export function getDealeradminCoin(page: number, pageSize: number) {
  const data = {
    fields: ['id', 'documentId', 'name', 'company_name'],

    pagination: {
      page,
      pageSize,
    },
  }
  return toQS(data)
}

const queries = [
  // {
  //   name: 'LEADS',
  //   query: getLeadsQuery({
  //     page: 1,
  //     pageSize: 10,
  //     sort: [],
  //     dealerId: 13,
  //   }),
  // },
  // {
  //   name: 'DEALERS',
  //   query: getDealersQuery(1, 10, [], ['new', 'trialing'], null),
  // },
  // {
  //   name: 'GET-CART',
  //   query: getCartDetails({ page: 1, pageSize: 10, userId: 4 }),
  // },
  // {
  //   name: 'navebar-query',
  //   query: getNavbarQuery({ metalType: 'gold', productType: 'coin' }),
  // },
  // {
  //   name: 'GET-DEALER-WITH-PLAN',
  //   query: getDealerAdminWithPlan(),
  // },
  // {
  //   name: 'GET-PAYMENT-LIST',
  //   query: getPaymentDetails({
  //     dealerId: 14,
  //     page: 1,
  //     pageSize: 10,
  //     search: 'omkar',
  //     sort: [],
  //     status: undefined,
  //     searchByDealer: true,
  //   }),
  // },
  // {
  //   name: 'PRODUCTS',
  //   query: getProductsQuery(
  //     1,
  //     10,
  //     [],
  //     true,
  //     null,
  //     null,
  //     null,
  //     null,
  //     null,
  //     null,
  //   ),
  // },

  {
    name: 'DealerAdminCoin',
    query: getDealeradminCoin(1, 10),
  },
  // {
  //   name: 'PAYMENTS',
  //   query: getPaymentsQuery(1, 10, [], 'Alta Coins Hub', 'paid'),
  // }
  // { name: 'SINGOLE-PRODUCTS', query: getSingleProduct() },
  // {
  //   name: 'FRONTEND-PRODUCTS',
  //   query: getFrontendProductsQuery(1, 10),
  // },
]

queries.forEach(({ name, query }) => {
  console.log(`---${name}_QUERY---`, decodeURIComponent(query))
})
