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

const DEFAULT_STAKEHOLDER_TYPES = ['Ministry', 'Private Sector'];

type SeedStakeholder = {
  name: string;
  type: 'Ministry' | 'Private Sector';
  // For a working group: the Ministry name it pairs with.
  relatedTo?: string;
  coChair?: string;
  description?: string;
};

// The canonical list of stakeholders to seed. Edit names / co-chairs /
// descriptions / relations here — this is the single source of truth (names are
// NOT taken from the user seed). Seed users are linked to these by matching name.
// NOTE: coChair / description below are MOCK sample values — replace with real
// data. Leave a field off to keep it null.
const STAKEHOLDERS: SeedStakeholder[] = [
  // --- Ministries ---
  {
    name: 'MAFF',
    type: 'Ministry',
    coChair: 'H.E. Mr. DITH TINA',
    description: 'Ministry of Agriculture, Forestry and Fisheries',
  },
  {
    name: 'MoT',
    type: 'Ministry',
    coChair: 'H.E. Mr. HUOT HAK',
    description: 'Ministry of Tourism',
  },
  {
    name: 'MISTI',
    type: 'Ministry',
    coChair: 'H.E. Mr. HEM VANNDY',
    description: 'Minister of Industry, Science, Technology & Innovation',
  },
  {
    name: 'MEF',
    type: 'Ministry',
    coChair: 'H.E. Dr. AUU PORNMONIROTH',
    description: 'Ministry of Economy and Finance',
  },
  {
    name: 'NBC',
    type: 'Ministry',
    coChair: 'H.E. Mrs. CHEA SEREY',
    description: 'National Bank of Cambodia',
  },
  {
    name: 'MPWT',
    type: 'Ministry',
    coChair: 'H.E. Mr. PENG PONEANG',
    description: 'Ministry of Public Works and Transport',
  },
  {
    name: 'MoC',
    type: 'Ministry',
    coChair: 'H.E. Mrs. CHAM NIMUL',
    description: 'Ministry of Commerce',
  },
  {
    name: 'MoLVT',
    type: 'Ministry',
    coChair: 'H.E. Mr. HENG SOUR',
    description: 'Ministry of Labour and Vocational Training',
  },
  {
    name: 'MME',
    type: 'Ministry',
    coChair: 'H.E. Mr. KEO ROTTANAK',
    description: 'Ministry of Mines and Energy',
  },
  {
    name: 'MoEYS',
    type: 'Ministry',
    coChair: 'H.E. Dr. HANGCHUON NARON',
    description: 'Ministry of Education, Youth and Sport',
  },
  {
    name: 'MoH',
    type: 'Ministry',
    coChair: 'H.E. Mr. CHHEANG RA',
    description: 'Ministry of Health',
  },
  {
    name: 'MLMUPC',
    type: 'Ministry',
    coChair: 'H.E. Mr. SAY SAMAL',
    description: 'Ministry of Land Management, Urban Planning and Construction',
  },
  {
    name: 'NBFSA',
    type: 'Ministry',
    coChair: 'H.E. Dr. AUN PORNMONIROTH',
    description: 'Non-Bank Financial Services Authority',
  },

  // --- Private-sector working groups ---
  {
    name: 'Agriculture & Agro-Industry',
    type: 'Private Sector',
    relatedTo: 'MAFF',
    coChair: 'OKNHA MONG RETHTHA',
    description: 'WG A: Agriculture & Agro-Industry',
  },
  {
    name: 'Tourism',
    type: 'Private Sector',
    relatedTo: 'MoT',
    coChair: 'OKNHA LUU MENG',
    description: 'WG B: Tourism',
  },
  {
    name: 'Manufacturing & SMEs',
    type: 'Private Sector',
    relatedTo: 'MISTI',
    coChair: 'OKNHA TE TAING POR',
    description: 'WG C: Manufacturing & SMEs',
  },
  {
    name: 'Law, Tax, and Governance',
    type: 'Private Sector',
    relatedTo: 'MEF',
    coChair: 'Mr. ARNAUD DARC',
    description: 'WG D: Law, Tax, and Governance',
  },
  {
    name: 'Banking and Financial Services',
    type: 'Private Sector',
    relatedTo: 'NBC',
    coChair: 'NEAK OKNHA KITH MENG',
    description: 'WG E: Banking and Financial Services',
  },
  {
    name: 'Transport and Infrastructure',
    type: 'Private Sector',
    relatedTo: 'MPWT',
    coChair: 'OKNHA SO NGUON',
    description: 'WG F: Transport and Infrastructure',
  },
  {
    name: 'Export Processing and Trade Facilitation',
    type: 'Private Sector',
    relatedTo: 'MoC',
    coChair: 'OKNHA KOUCH PHENG',
    description: 'WG G: Export Processing and Trade Facilitation',
  },
  {
    name: 'Industrial Relations',
    type: 'Private Sector',
    relatedTo: 'MoLVT',
    coChair: 'OKNHA Dr. NANG SOTHY',
    description: 'WG H: Industrial Relations',
  },
  {
    name: 'Rice and Paddy',
    type: 'Private Sector',
    coChair: 'OKNHA CHAN SOKHEANG',
    description: 'WG I: Rice and Paddy',
  },
  {
    name: 'Energy and Mineral Resources',
    type: 'Private Sector',
    relatedTo: 'MME',
    coChair: 'OKNHA UN YUTHY',
    description: 'WG J: Energy and Mineral Resources',
  },
  {
    name: 'Education',
    type: 'Private Sector',
    relatedTo: 'MoEYS',
    coChair: 'OKNHA Dr. HENG VANNDA',
    description: 'WG K: Education',
  },
  {
    name: 'Health',
    type: 'Private Sector',
    relatedTo: 'MoH',
    coChair: 'OKNHA Dr. TAN KIM MENG',
    description: 'WG L: Health',
  },
  {
    name: 'Construction and Real Estate',
    type: 'Private Sector',
    relatedTo: 'MLMUPC',
    coChair: 'OKNHA Dr. TAN MONIVANN',
    description: 'WG M: Construction and Real Estate',
  },
  {
    name: 'Non-Bank Financial Services',
    type: 'Private Sector',
    relatedTo: 'NBFSA',
    coChair: 'NEAK OKNHA KITH MENG',
    description: 'WG N: Non-Bank Financial Services',
  },
];

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

  // An owner user is needed to create the stakeholder types.
  if (!userSeed.ownerUserId) {
    return {
      stakeholderNames,
      stakeholderTypeNames: DEFAULT_STAKEHOLDER_TYPES,
    };
  }

  // Ensure the stakeholder types exist.
  const stakeholderTypesByName = new Map<string, { id: number }>();

  for (const name of DEFAULT_STAKEHOLDER_TYPES) {
    let stakeholderType = await prisma.stakeholderTypes.findFirst({
      where: { name, deletedAt: null },
      select: { id: true },
    });

    if (!stakeholderType) {
      stakeholderType = await prisma.stakeholderTypes.create({
        data: { name, userId: userSeed.ownerUserId },
        select: { id: true },
      });
    }

    stakeholderTypesByName.set(name, stakeholderType);
  }

  const createOrUpdateStakeholder = async (data: {
    name: string;
    stakeholderTypeId: number;
    coChair?: string | null;
    description?: string | null;
  }) => {
    const existing = await prisma.stakeholder.findFirst({
      where: {
        name: data.name,
        stakeholderTypeId: data.stakeholderTypeId,
        deletedAt: null,
      },
      select: { id: true },
    });

    const payload = {
      coChair: data.coChair ?? null,
      description: data.description ?? null,
      active: true,
    };

    if (existing) {
      await prisma.stakeholder.update({
        where: { id: existing.id },
        data: payload,
      });
      return existing.id;
    }

    const created = await prisma.stakeholder.create({
      data: {
        name: data.name,
        stakeholderTypeId: data.stakeholderTypeId,
        ...payload,
      },
      select: { id: true },
    });
    return created.id;
  };

  // Pass 1: create/update every stakeholder and record its id by name so a
  // working group can reference its ministry in the next pass.
  const idByName = new Map<string, number>();

  for (const stakeholder of STAKEHOLDERS) {
    const type = stakeholderTypesByName.get(stakeholder.type);
    if (!type) continue;

    const id = await createOrUpdateStakeholder({
      name: stakeholder.name,
      stakeholderTypeId: type.id,
      coChair: stakeholder.coChair ?? null,
      description: stakeholder.description ?? null,
    });

    idByName.set(stakeholder.name, id);
    stakeholderNames.push(stakeholder.name);
  }

  // Pass 2: link each working group to its related ministry by name. The
  // relation is mutual (one-to-one), so we set BOTH sides: the working group
  // points to the ministry AND the ministry points back to the working group.
  // This is why a Ministry response can include its related working group.
  for (const stakeholder of STAKEHOLDERS) {
    if (!stakeholder.relatedTo) continue;

    const id = idByName.get(stakeholder.name);
    const relatedId = idByName.get(stakeholder.relatedTo);

    if (id && relatedId) {
      await prisma.stakeholder.update({
        where: { id },
        data: { relatedStakeholderId: relatedId },
      });
      await prisma.stakeholder.update({
        where: { id: relatedId },
        data: { relatedStakeholderId: id },
      });
    }
  }

  // Link seed users to stakeholders by name so the app can resolve a logged-in
  // user's stakeholder. Users whose stakeholderName is not in the list above are
  // simply left unlinked.
  for (const user of userSeed.users) {
    if (!user.stakeholderName) continue;

    const stakeholderId = idByName.get(user.stakeholderName);
    if (!stakeholderId) continue;

    await prisma.stakeholderUser.upsert({
      where: {
        userId_stakeholderId: { userId: user.id, stakeholderId },
      },
      update: {},
      create: { userId: user.id, stakeholderId },
    });
  }

  return {
    stakeholderNames,
    stakeholderTypeNames: DEFAULT_STAKEHOLDER_TYPES,
  };
}
