import { prisma } from '@/lib/prisma'
import { sendStyledNotificationEmail } from '@/lib/email'

interface DigestResult {
  sent: number
  errors: number
}

interface DigestSection {
  title: string
  items: string[]
}

/**
 * Process and send email digests for all opted-in users.
 * Called by cron endpoint.
 */
export async function processDigests(
  type: 'daily' | 'weekly'
): Promise<DigestResult> {
  let sent = 0
  let errors = 0

  // Check if digest feature is enabled
  const enabledSetting = await prisma.systemSettings.findUnique({
    where: { key: 'digest_enabled' },
  })
  if (enabledSetting?.value === 'false') {
    return { sent: 0, errors: 0 }
  }

  // Find users who opted in for this digest frequency
  const users = await prisma.user.findMany({
    where: {
      digestFrequency: type,
      status: 'ACTIVE',
    },
    select: {
      id: true,
      name: true,
      email: true,
    },
  })

  if (users.length === 0) {
    return { sent: 0, errors: 0 }
  }

  // Load enabled sections from settings
  const sectionsSetting = await prisma.systemSettings.findUnique({
    where: { key: 'digest_sections' },
  })
  const enabledSections: string[] = sectionsSetting?.value
    ? JSON.parse(sectionsSetting.value)
    : ['pending_evaluations', 'upcoming_deadlines', 'new_assignments', 'unread_notifications']

  const baseUrl = process.env.NEXTAUTH_URL || 'https://portal.monaco-opc.com'

  for (const user of users) {
    try {
      const content = await getDigestContent(user.id, enabledSections)

      // Skip if there's nothing to report
      if (content.sections.length === 0) continue

      // Build email body from sections
      const bodyParts: string[] = []
      for (const section of content.sections) {
        bodyParts.push(`**${section.title}**`)
        for (const item of section.items) {
          bodyParts.push(`- ${item}`)
        }
        bodyParts.push('')
      }

      await sendStyledNotificationEmail(
        user.email,
        user.name || '',
        'DIGEST',
        {
          name: user.name || undefined,
          title: `Your ${type === 'daily' ? 'Daily' : 'Weekly'} Digest`,
          message: bodyParts.join('\n'),
          linkUrl: `${baseUrl}/dashboard`,
          metadata: {
            digestType: type,
            pendingEvaluations: content.pendingEvaluations,
            upcomingDeadlines: content.upcomingDeadlines,
            newAssignments: content.newAssignments,
            unreadNotifications: content.unreadNotifications,
          },
        }
      )

      // Log the digest
      await prisma.digestLog.create({
        data: {
          userId: user.id,
          digestType: type,
          contentJson: {
            pendingEvaluations: content.pendingEvaluations,
            upcomingDeadlines: content.upcomingDeadlines,
            newAssignments: content.newAssignments,
            unreadNotifications: content.unreadNotifications,
          },
        },
      })

      sent++
    } catch (error) {
      console.error(
        `[Digest] Failed to send ${type} digest to ${user.email}:`,
        error
      )
      errors++
    }
  }

  return { sent, errors }
}

/**
 * Compile digest content for a single user.
 */
async function getDigestContent(
  userId: string,
  enabledSections: string[]
): Promise<{
  sections: DigestSection[]
  pendingEvaluations: number
  upcomingDeadlines: number
  newAssignments: number
  unreadNotifications: number
}> {
  const now = new Date()
  const sections: DigestSection[] = []
  let pendingEvaluations = 0
  let upcomingDeadlines = 0
  let newAssignments = 0
  let unreadNotifications = 0

  // 1. Pending evaluations
  if (enabledSections.includes('pending_evaluations')) {
    const pendingAssignments = await prisma.assignment.findMany({
      where: {
        userId,
        isCompleted: false,
        round: {
          status: 'ROUND_ACTIVE',
          windowCloseAt: { gt: now },
        },
      },
      include: {
        project: { select: { id: true, title: true } },
        round: { select: { name: true, windowCloseAt: true } },
      },
    })

    pendingEvaluations = pendingAssignments.length
    if (pendingAssignments.length > 0) {
      sections.push({
        title: `Pending Evaluations (${pendingAssignments.length})`,
        items: pendingAssignments.map(
          (a) =>
            `${a.project.title} - ${a.round?.name ?? 'Unknown'}${
              a.round?.windowCloseAt
                ? ` (due ${a.round.windowCloseAt.toLocaleDateString('en-US', {
                    month: 'short',
                    day: 'numeric',
                  })})`
                : ''
            }`
        ),
      })
    }
  }

  // 2. Upcoming deadlines (rounds closing within 7 days)
  if (enabledSections.includes('upcoming_deadlines')) {
    const sevenDaysFromNow = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000)
    const upcomingRounds = await prisma.round.findMany({
      where: {
        status: 'ROUND_ACTIVE',
        windowCloseAt: {
          gt: now,
          lte: sevenDaysFromNow,
        },
        assignments: {
          some: {
            userId,
            isCompleted: false,
          },
        },
      },
      select: {
        name: true,
        windowCloseAt: true,
      },
    })

    upcomingDeadlines = upcomingRounds.length
    if (upcomingRounds.length > 0) {
      sections.push({
        title: 'Upcoming Deadlines',
        items: upcomingRounds.map(
          (s) =>
            `${s.name} - ${s.windowCloseAt?.toLocaleDateString('en-US', {
              weekday: 'short',
              month: 'short',
              day: 'numeric',
              hour: '2-digit',
              minute: '2-digit',
            })}`
        ),
      })
    }
  }

  // 3. New assignments since last digest
  if (enabledSections.includes('new_assignments')) {
    const lastDigest = await prisma.digestLog.findFirst({
      where: { userId },
      orderBy: { sentAt: 'desc' },
      select: { sentAt: true },
    })

    const sinceDate = lastDigest?.sentAt || new Date(now.getTime() - 24 * 60 * 60 * 1000)

    const recentAssignments = await prisma.assignment.findMany({
      where: {
        userId,
        createdAt: { gt: sinceDate },
      },
      include: {
        project: { select: { id: true, title: true } },
        round: { select: { name: true } },
      },
    })

    newAssignments = recentAssignments.length
    if (recentAssignments.length > 0) {
      sections.push({
        title: `New Assignments (${recentAssignments.length})`,
        items: recentAssignments.map(
          (a) => `${a.project.title} - ${a.round?.name ?? 'Unknown'}`
        ),
      })
    }
  }

  // 4. Unread notifications count
  if (enabledSections.includes('unread_notifications')) {
    const unreadCount = await prisma.inAppNotification.count({
      where: {
        userId,
        isRead: false,
      },
    })

    unreadNotifications = unreadCount
    if (unreadCount > 0) {
      sections.push({
        title: 'Notifications',
        items: [`You have ${unreadCount} unread notification${unreadCount !== 1 ? 's' : ''}`],
      })
    }
  }

  return {
    sections,
    pendingEvaluations,
    upcomingDeadlines,
    newAssignments,
    unreadNotifications,
  }
}
