import { afterAll, describe, expect, it } from 'vitest'
import { prisma, createCaller } from '../setup'
import {
  createTestProgram,
  createTestProject,
  cleanupTestData,
  uid,
} from '../helpers'
import { mentorRouter } from '../../src/server/routers/mentor'
import { applicantRouter } from '../../src/server/routers/applicant'
import type { UserRole } from '@prisma/client'

async function createUserWithRoles(primaryRole: UserRole, rolesArray: UserRole[]) {
  const id = uid('user')
  return prisma.user.create({
    data: {
      id,
      email: `${id}@test.local`,
      name: `Test ${primaryRole}`,
      role: primaryRole,
      roles: rolesArray,
      status: 'ACTIVE',
    },
  })
}

describe('mentor.getRecentMessages', () => {
  const programIds: string[] = []
  const userIds: string[] = []

  afterAll(async () => {
    for (const programId of programIds) {
      await prisma.mentorAssignment.deleteMany({ where: { project: { programId } } })
      await cleanupTestData(programId, [])
    }
    if (userIds.length > 0) {
      await prisma.user.deleteMany({ where: { id: { in: userIds } } })
    }
  })

  it('returns recent unread messages from team across mentor assignments', async () => {
    const program = await createTestProgram({ name: `recent-msgs-${uid()}` })
    programIds.push(program.id)
    const mentor = await createUserWithRoles('MENTOR', ['MENTOR'])
    const applicant = await createUserWithRoles('APPLICANT', ['APPLICANT'])
    userIds.push(mentor.id, applicant.id)
    const project = await createTestProject(program.id)
    const ma = await prisma.mentorAssignment.create({
      data: {
        projectId: project.id,
        mentorId: mentor.id,
        method: 'MANUAL',
        workspaceEnabled: true,
      },
    })
    await prisma.mentorMessage.create({
      data: {
        projectId: project.id,
        senderId: applicant.id,
        message: 'Question 1',
        workspaceId: ma.id,
        isRead: false,
      },
    })
    await prisma.mentorMessage.create({
      data: {
        projectId: project.id,
        senderId: applicant.id,
        message: 'Question 2',
        workspaceId: ma.id,
        isRead: false,
      },
    })
    await prisma.mentorMessage.create({
      data: {
        projectId: project.id,
        senderId: applicant.id,
        message: 'old',
        workspaceId: ma.id,
        isRead: true,
      },
    })

    const caller = createCaller(mentorRouter, { id: mentor.id, email: mentor.email, role: 'MENTOR' })
    const result = await caller.getRecentMessages({ limit: 5 })

    expect(result.unread.length).toBe(2)
    expect(result.unread[0].message).toContain('Question')
  })
})

describe('applicant.getMentorConversationPreview', () => {
  const programIds: string[] = []
  const userIds: string[] = []

  afterAll(async () => {
    for (const programId of programIds) {
      await prisma.mentorAssignment.deleteMany({ where: { project: { programId } } })
      await cleanupTestData(programId, [])
    }
    if (userIds.length > 0) {
      await prisma.user.deleteMany({ where: { id: { in: userIds } } })
    }
  })

  it('returns last 3 messages + unread count for the project', async () => {
    const program = await createTestProgram({ name: `conv-preview-${uid()}` })
    programIds.push(program.id)
    const mentor = await createUserWithRoles('MENTOR', ['MENTOR'])
    const applicant = await createUserWithRoles('APPLICANT', ['APPLICANT'])
    userIds.push(mentor.id, applicant.id)
    const project = await createTestProject(program.id)
    await prisma.teamMember.create({
      data: { projectId: project.id, userId: applicant.id, role: 'LEAD' },
    })
    const ma = await prisma.mentorAssignment.create({
      data: {
        projectId: project.id,
        mentorId: mentor.id,
        method: 'MANUAL',
        workspaceEnabled: true,
      },
    })
    for (let i = 0; i < 5; i++) {
      await prisma.mentorMessage.create({
        data: {
          projectId: project.id,
          senderId: mentor.id,
          message: `mentor msg ${i}`,
          workspaceId: ma.id,
          isRead: i < 2,
        },
      })
    }

    const caller = createCaller(applicantRouter, {
      id: applicant.id,
      email: applicant.email,
      role: 'APPLICANT',
    })
    const result = await caller.getMentorConversationPreview({ projectId: project.id })

    expect(result.messages.length).toBe(3)
    expect(result.unreadCount).toBe(3)
    expect(result.mentor?.id).toBe(mentor.id)
  })
})
