import { NextResponse } from 'next/server'
import { prisma } from '@/lib/prisma'
import { headers } from 'next/headers'
import crypto from 'crypto'

export async function POST(request: Request) {
  try {
    const body = await request.json()
    const { path } = body

    const headersList = await headers()
    const userAgent = request.headers.get('user-agent') || ''

    // Helper to get client IP
    const getClientIP = (): string => {
      // Check various headers for real IP
      const xForwardedFor = headersList.get('x-forwarded-for')
      const xRealIP = headersList.get('x-real-ip')
      const cfConnectingIP = headersList.get('cf-connecting-ip') // Cloudflare

      if (xForwardedFor) {
        // x-forwarded-for can contain multiple IPs, take the first one
        return xForwardedFor.split(',')[0].trim()
      }

      if (xRealIP) {
        return xRealIP.trim()
      }

      if (cfConnectingIP) {
        return cfConnectingIP.trim()
      }

      // Fallback to remote address (not available in Edge Runtime)
      return 'unknown'
    }

    const ip = getClientIP()
    const referer = headersList.get('referer') || null

    // Generate unique session ID
    const getSessionID = (): string => {
      // Create hash from IP + User-Agent for session identification
      const sessionData = `${ip}-${userAgent}-${new Date().toDateString()}`
      return crypto.createHash('sha256').update(sessionData).digest('hex').substring(0, 32)
    }

    const sessionId = getSessionID()

    // Check if we already tracked this IP in the last hour (to avoid spam)
    const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000)
    const recentVisit = await prisma.visitor.findFirst({
      where: {
        ip,
        visitedAt: { gte: oneHourAgo }
      }
    })

    if (recentVisit) {
      return NextResponse.json({ success: true, message: 'Already tracked recently' })
    }

    // Create visitor record
    await prisma.visitor.create({
      data: {
        ip,
        userAgent,
        path,
        referrer: referer,
        sessionId
      }
    })

    return NextResponse.json({ success: true })
  } catch (error) {
    console.error('=== VISITOR TRACKING ERROR ===')
    console.error('Time:', new Date().toISOString())
    console.error('Error:', error)
    if (error instanceof Error) {
      console.error('Message:', error.message)
      console.error('Stack:', error.stack)
    }
    console.error('============================')
    return NextResponse.json(
      { success: false, error: 'Failed to track visitor' },
      { status: 500 }
    )
  }
}

// GET endpoint for visitor statistics (admin only)
export async function GET() {
  try {
    const { auth } = await import('@/lib/auth')
    const { isAdmin } = await import('@/lib/admin')

    const session = await auth()
    if (!session?.user?.email || !isAdmin(session.user.email)) {
      return NextResponse.json(
        { success: false, error: 'Admin access required' },
        { status: 403 }
      )
    }

    const now = new Date()
    const today = new Date(now.getFullYear(), now.getMonth(), now.getDate())
    const yesterday = new Date(today)
    yesterday.setDate(yesterday.getDate() - 1)
    const last7Days = new Date(today)
    last7Days.setDate(last7Days.getDate() - 7)
    const last30Days = new Date(today)
    last30Days.setDate(last30Days.getDate() - 30)

    // Total unique visitors (count by IP)
    const totalVisitors = await prisma.visitor.groupBy({
      by: ['ip'],
      _count: true
    }).then(result => result.length)

    // Today's visitors
    const todayVisitors = await prisma.visitor.groupBy({
      by: ['ip'],
      where: {
        visitedAt: { gte: today }
      },
      _count: true
    }).then(result => result.length)

    // Yesterday's visitors (for comparison)
    const yesterdayVisitors = await prisma.visitor.groupBy({
      by: ['ip'],
      where: {
        visitedAt: {
          gte: yesterday,
          lt: today
        }
      },
      _count: true
    }).then(result => result.length)

    // This week visitors
    const thisWeekVisitors = await prisma.visitor.groupBy({
      by: ['ip'],
      where: {
        visitedAt: { gte: last7Days }
      },
      _count: true
    }).then(result => result.length)

    // Last week visitors (for comparison)
    const lastWeekStart = new Date(today)
    lastWeekStart.setDate(lastWeekStart.getDate() - 14)
    const lastWeekVisitors = await prisma.visitor.groupBy({
      by: ['ip'],
      where: {
        visitedAt: {
          gte: lastWeekStart,
          lt: last7Days
        }
      },
      _count: true
    }).then(result => result.length)

    // Daily visitors for last 30 days
    const dailyVisitors = await prisma.$queryRaw<{ date: string; count: bigint }[]>`
      SELECT DATE(visited_at) as date, COUNT(DISTINCT ip) as count
      FROM visitors
      WHERE visited_at >= ${last30Days.toISOString()}
      GROUP BY DATE(visited_at)
      ORDER BY date ASC
    `

    // Format daily data to ensure all 30 days are included
    const dailyVisitorData = []
    for (let i = 29; i >= 0; i--) {
      const d = new Date(today)
      d.setDate(d.getDate() - i)
      const dateStr = d.toISOString().split('T')[0]
      const dayData = dailyVisitors.find(v => v.date === dateStr)
      dailyVisitorData.push({
        date: dateStr,
        count: Number(dayData?.count || 0)
      })
    }

    // Top pages visited
    const topPages = await prisma.visitor.groupBy({
      by: ['path'],
      where: {
        path: { not: null },
        visitedAt: { gte: last30Days }
      },
      _count: true,
      orderBy: {
        _count: {
          path: 'desc'
        }
      },
      take: 10
    })

    // Growth percentage
    const visitorGrowthPercent = lastWeekVisitors > 0
      ? Math.round(((thisWeekVisitors - lastWeekVisitors) / lastWeekVisitors) * 100)
      : thisWeekVisitors > 0 ? 100 : 0

    return NextResponse.json({
      success: true,
      data: {
        totalVisitors,
        todayVisitors,
        yesterdayVisitors,
        thisWeekVisitors,
        lastWeekVisitors,
        visitorGrowthPercent,
        dailyVisitors: dailyVisitorData,
        topPages: topPages.map(page => ({
          path: page.path,
          visits: page._count
        }))
      }
    })
  } catch (error) {
    console.error('Visitor stats error:', error)
    return NextResponse.json(
      { success: false, error: 'Failed to fetch visitor statistics' },
      { status: 500 }
    )
  }
}