import { db } from '@sim/db'
import { account } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { and, eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import {
  shopifyShopDomainSchema,
  shopifyStoreCookieSchema,
} from '@/lib/api/contracts/oauth-connections'
import { getSession } from '@/lib/auth'
import { getBaseUrl } from '@/lib/core/utils/urls'
import { isSameOrigin } from '@/lib/core/utils/validation'
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
import { processCredentialDraft } from '@/lib/credentials/draft-processor'
import { safeAccountInsert } from '@/app/api/auth/oauth/utils'

const logger = createLogger('ShopifyStore')

export const dynamic = 'force-dynamic'

export const GET = withRouteHandler(async (request: NextRequest) => {
  const baseUrl = getBaseUrl()

  try {
    const session = await getSession()
    if (!session?.user?.id) {
      logger.warn('Unauthorized attempt to store Shopify token')
      return NextResponse.redirect(`${baseUrl}/workspace?error=unauthorized`)
    }

    const parsedCookies = shopifyStoreCookieSchema.safeParse({
      accessToken: request.cookies.get('shopify_pending_token')?.value,
      shopDomain: request.cookies.get('shopify_pending_shop')?.value,
      scope: request.cookies.get('shopify_pending_scope')?.value || undefined,
      returnUrl: request.cookies.get('shopify_return_url')?.value || undefined,
    })

    if (!parsedCookies.success) {
      logger.error('Missing token or shop domain in cookies')
      return NextResponse.redirect(`${baseUrl}/workspace?error=shopify_missing_data`)
    }
    const { accessToken, shopDomain, scope, returnUrl } = parsedCookies.data

    if (!shopifyShopDomainSchema.safeParse(shopDomain).success) {
      logger.error('Invalid shop domain format in cookie', { shopDomain })
      return NextResponse.redirect(`${baseUrl}/workspace?error=shopify_invalid_domain`)
    }

    const shopResponse = await fetch(`https://${shopDomain}/admin/api/2024-10/shop.json`, {
      headers: {
        'X-Shopify-Access-Token': accessToken,
        'Content-Type': 'application/json',
      },
    })

    if (!shopResponse.ok) {
      const errorText = await shopResponse.text()
      logger.error('Invalid Shopify token', {
        status: shopResponse.status,
        error: errorText,
      })
      return NextResponse.redirect(`${baseUrl}/workspace?error=shopify_invalid_token`)
    }

    const shopData = await shopResponse.json()
    const shopInfo = shopData.shop
    const stableAccountId = shopInfo.id?.toString() || shopDomain

    const existing = await db.query.account.findFirst({
      where: and(
        eq(account.userId, session.user.id),
        eq(account.providerId, 'shopify'),
        eq(account.accountId, stableAccountId)
      ),
    })

    const now = new Date()

    const accountData = {
      accessToken: accessToken,
      accountId: stableAccountId,
      scope: scope || '',
      updatedAt: now,
      idToken: shopDomain,
    }

    if (existing) {
      await db.update(account).set(accountData).where(eq(account.id, existing.id))
      logger.info('Updated existing Shopify account', { accountId: existing.id })
    } else {
      await safeAccountInsert(
        {
          id: `shopify_${session.user.id}_${Date.now()}`,
          userId: session.user.id,
          providerId: 'shopify',
          accountId: accountData.accountId,
          accessToken: accountData.accessToken,
          scope: accountData.scope,
          idToken: accountData.idToken,
          createdAt: now,
          updatedAt: now,
        },
        { provider: 'Shopify', identifier: shopDomain }
      )
    }

    const persisted =
      existing ??
      (await db.query.account.findFirst({
        where: and(
          eq(account.userId, session.user.id),
          eq(account.providerId, 'shopify'),
          eq(account.accountId, stableAccountId)
        ),
      }))

    if (persisted) {
      try {
        await processCredentialDraft({
          userId: session.user.id,
          providerId: 'shopify',
          accountId: persisted.id,
        })
      } catch (error) {
        logger.error('Failed to process credential draft for Shopify', { error })
      }
    }

    const redirectUrl = returnUrl && isSameOrigin(returnUrl) ? returnUrl : `${baseUrl}/workspace`
    const finalUrl = new URL(redirectUrl)
    finalUrl.searchParams.set('shopify_connected', 'true')

    const response = NextResponse.redirect(finalUrl.toString())
    response.cookies.delete('shopify_pending_token')
    response.cookies.delete('shopify_pending_shop')
    response.cookies.delete('shopify_pending_scope')
    response.cookies.delete('shopify_return_url')

    return response
  } catch (error) {
    logger.error('Error storing Shopify token:', error)
    return NextResponse.redirect(`${baseUrl}/workspace?error=shopify_store_error`)
  }
})
