import {
  MeetingRequestStatus,
  type PrismaClient,
} from '../../src/generated/prisma/client';
import type { SeedUsersResult } from './user.seed';

// One meeting request to seed.
// - ownerWorkingGroup: the Private Sector stakeholder whose user owns the
//   request. The request's userId is that working group's private-sector user.
// - agencies: ministry stakeholder names invited to the meeting.
// - issueTitles: titles of already-seeded issues to attach to this request
//   (their meetingRequestId is set to point at this request).
type SeedMeetingRequest = {
  ownerWorkingGroup: string;
  title: string;
  description: string;
  status: MeetingRequestStatus;
  agencies: string[];
  issueTitles: string[];
};

// Placeholder letter path. The file does not need to exist for seeding; it is
// only a reference shown in the UI.
const PLACEHOLDER_LETTER = '/uploads/meeting-requests/seed-meeting-request.pdf';

const MEETING_REQUESTS: SeedMeetingRequest[] = [
  // This request is linked to a meeting with a draft summary. The request
  // remains Scheduled until that summary is submitted and completes it.
  {
    ownerWorkingGroup: 'Agriculture & Agro-Industry',
    title:
      'សំណើសុំប្រជុំស្តីពីដំណើរការចេញវិញ្ញាបនបត្រផលិតផលកសិកម្ម និងនីតិវិធីនាំចេញ',
    description:
      '<p>ក្រុមការងារវិស័យកសិកម្ម និងកសិឧស្សាហកម្ម ស្នើសុំរៀបចំកិច្ចប្រជុំដើម្បីពិភាក្សាអំពីបញ្ហាប្រឈមសំខាន់ៗដែលវិស័យឯកជនកំពុងជួបប្រទះ រួមមាន ដំណើរការចេញវិញ្ញាបនបត្រផលិតផលកសិកម្ម ការនាំចេញផលិតផលកសិកម្ម ថ្លៃដើមខ្ពស់នៃធាតុចូលកសិកម្ម និងការខ្វះខាតហេដ្ឋារចនាសម្ព័ន្ធគាំទ្រដូចជា ឃ្លាំងត្រជាក់ និងប្រព័ន្ធភស្តុភារ។</p><p>កិច្ចប្រជុំនេះមានគោលបំណងប្រមូលមតិយោបល់ពីភាគីពាក់ព័ន្ធ ពិនិត្យបញ្ហាប្រឈមជាក់ស្តែង និងពិភាក្សាអំពីដំណោះស្រាយសមស្រប។</p>',
    status: MeetingRequestStatus.SCHEDULED,
    agencies: ['MAFF', 'MEF', 'MISTI', 'MLMUPC', 'MME'],
    issueTitles: [
      'ការយឺតយ៉ាវក្នុងដំណើរការចេញវិញ្ញាបនបត្រផលិតផលកសិកម្ម',
      'បញ្ហាការនាំចេញផលិតផលកសិកម្មទៅទីផ្សារអន្តរជាតិ',
    ],
  },
  {
    ownerWorkingGroup: 'Tourism',
    title: 'សំណើសុំប្រជុំស្តីពីការអភិវឌ្ឍធនធានមនុស្សក្នុងវិស័យទេសចរណ៍',
    description:
      '<p>ក្រុមការងារវិស័យទេសចរណ៍ ស្នើសុំរៀបចំកិច្ចប្រជុំដើម្បីពិភាក្សាអំពីការខ្វះខាតបុគ្គលិកជំនាញ និងការបណ្តុះបណ្តាលធនធានមនុស្សក្នុងវិស័យទេសចរណ៍។</p>',
    status: MeetingRequestStatus.SUBMITTED,
    agencies: ['MoT', 'MoEYS', 'MoLVT'],
    issueTitles: ['ការខ្វះខាតបុគ្គលិកជំនាញក្នុងវិស័យទេសចរណ៍'],
  },
  {
    ownerWorkingGroup: 'Manufacturing & SMEs',
    title: 'សំណើសុំប្រជុំស្តីពីហិរញ្ញប្បទានសម្រាប់សហគ្រាសធុនតូច និងមធ្យម',
    description:
      '<p>ក្រុមការងារផលិតកម្ម និង SMEs ស្នើសុំរៀបចំកិច្ចប្រជុំដើម្បីពិភាក្សាអំពីការលំបាកក្នុងការទទួលបានហិរញ្ញប្បទាន និងដំណោះស្រាយសម្រាប់សហគ្រាសធុនតូច និងមធ្យម។</p>',
    status: MeetingRequestStatus.DRAFT,
    agencies: ['MISTI', 'MEF', 'NBC'],
    issueTitles: [
      'ការលំបាកក្នុងការទទួលបានហិរញ្ញប្បទានសម្រាប់សហគ្រាសធុនតូច និងមធ្យម',
    ],
  },
  {
    ownerWorkingGroup: 'Banking and Financial Services',
    title: 'សំណើសុំប្រជុំស្តីពីបទប្បញ្ញត្តិសេវាហិរញ្ញវត្ថុឌីជីថល',
    description:
      '<p>ក្រុមការងារធនាគារ និងសេវាហិរញ្ញវត្ថុ ស្នើសុំរៀបចំកិច្ចប្រជុំដើម្បីពិភាក្សាអំពីការអនុវត្តបទប្បញ្ញត្តិថ្មីស្តីពីសេវាហិរញ្ញវត្ថុឌីជីថល។</p>',
    status: MeetingRequestStatus.DRAFT,
    agencies: ['NBC', 'MEF'],
    issueTitles: ['ការអនុវត្តបទប្បញ្ញត្តិថ្មីស្តីពីសេវាហិរញ្ញវត្ថុឌីជីថល'],
  },
];

export async function seedMeetingRequests(
  prisma: PrismaClient,
  userSeed: SeedUsersResult,
) {
  const seededTitles: string[] = [];

  // Stakeholder id by name (working group or ministry).
  const stakeholderIdByName = new Map<string, number>();
  const stakeholders = await prisma.stakeholder.findMany({
    where: { deletedAt: null },
    select: { id: true, name: true },
  });
  for (const stakeholder of stakeholders) {
    stakeholderIdByName.set(stakeholder.name, stakeholder.id);
  }

  // The private-sector user that belongs to each working group.
  const userIdByStakeholderName = new Map<string, number>();
  for (const user of userSeed.users) {
    if (user.stakeholderName) {
      userIdByStakeholderName.set(user.stakeholderName, user.id);
    }
  }

  for (const request of MEETING_REQUESTS) {
    const ownerStakeholderId = stakeholderIdByName.get(
      request.ownerWorkingGroup,
    );
    const userId = userIdByStakeholderName.get(request.ownerWorkingGroup);

    if (!ownerStakeholderId || !userId) {
      console.warn(
        `Skipping meeting request "${request.title}" (missing owner stakeholder or user).`,
      );
      continue;
    }

    // Resolve the ministry agencies that exist.
    const agencyStakeholderIds = request.agencies
      .map((name) => stakeholderIdByName.get(name))
      .filter((id): id is number => typeof id === 'number');

    // Idempotent: reuse an existing request with the same title + owner user.
    const existing = await prisma.meetingRequests.findFirst({
      where: { title: request.title, userId, deletedAt: null },
      select: { id: true },
    });

    let meetingRequestId: number;

    if (existing) {
      // Keep the existing meetingRequestLetter (a real uploaded file) on
      // update; only the placeholder is used when creating from scratch.
      await prisma.meetingRequests.update({
        where: { id: existing.id },
        data: {
          title: request.title,
          description: request.description,
          status: request.status,
          userId,
        },
      });
      meetingRequestId = existing.id;

      // Reset the agency list so re-seeding stays consistent.
      await prisma.governmentAgencyMeetingRequest.deleteMany({
        where: { meetingRequestId },
      });
    } else {
      const created = await prisma.meetingRequests.create({
        data: {
          title: request.title,
          description: request.description,
          meetingRequestLetter: PLACEHOLDER_LETTER,
          status: request.status,
          userId,
        },
        select: { id: true },
      });
      meetingRequestId = created.id;
    }

    // (Re)create the government agencies invited to this request.
    if (agencyStakeholderIds.length > 0) {
      await prisma.governmentAgencyMeetingRequest.createMany({
        data: agencyStakeholderIds.map((stakeholderId) => ({
          meetingRequestId,
          stakeholderId,
        })),
        skipDuplicates: true,
      });
    }

    // Attach the seeded issues to this request (the working group's own issues,
    // matched by title). An attached issue's status reflects the request
    // lifecycle and is set in the issue seed: New Submission once the request is
    // sent (Submitted), or Saved while the request is still a draft.
    if (request.issueTitles.length > 0) {
      await prisma.issues.updateMany({
        where: {
          title: { in: request.issueTitles },
          stakeholderId: ownerStakeholderId,
          deletedAt: null,
        },
        data: { meetingRequestId },
      });
    }

    seededTitles.push(request.title);
  }

  return { seededTitles };
}
