import type {
  BulkUserAppointment,
  BulkUserItem,
  TenantSummary,
} from "../../../lib/adminApi";

export function applyGeneralPlanningOfficePriority(
  user: BulkUserItem,
  tenants: TenantSummary[],
): BulkUserItem {
  const gpdtdcRepresentative = applyGPDTDCRepresentativeTenant(user, tenants);
  if (gpdtdcRepresentative) {
    return gpdtdcRepresentative;
  }

  const firstAdditional = user.additionalAppointments?.[0];
  const secondarySlug = firstAdditional?.tenantSlug;

  if (
    !firstAdditional ||
    !secondarySlug ||
    !isUnderGeneralPlanningOffice(secondarySlug, tenants) ||
    isUnderGeneralPlanningOffice(user.tenantSlug || "", tenants)
  ) {
    return user;
  }

  const primaryEmployeeId = stringValue(user.metadata.employee_id);
  const secondaryEmployeeId = stringValue(
    firstAdditional.metadata?.employee_id,
  );

  const metadata = { ...user.metadata };
  if (secondaryEmployeeId) {
    metadata.employee_id = secondaryEmployeeId;
  } else {
    delete metadata.employee_id;
  }

  const primaryAppointmentMetadata: Record<string, unknown> = {
    ...firstAdditional.metadata,
  };
  if (primaryEmployeeId) {
    primaryAppointmentMetadata.employee_id = primaryEmployeeId;
  } else {
    delete primaryAppointmentMetadata.employee_id;
  }

  return {
    ...user,
    tenantSlug: firstAdditional.tenantSlug,
    tenantImport: user.tenantImport
      ? {
          ...user.tenantImport,
          slug: firstAdditional.tenantSlug || "",
          name: firstAdditional.tenantName || firstAdditional.tenantSlug || "",
        }
      : user.tenantImport,
    department: firstAdditional.department,
    grade: firstAdditional.grade,
    position: firstAdditional.position,
    jobTitle: firstAdditional.jobTitle,
    metadata,
    additionalAppointments: [
      {
        ...firstAdditional,
        tenantSlug: user.tenantSlug,
        department: user.department,
        grade: user.grade,
        position: user.position,
        jobTitle: user.jobTitle,
        metadata: primaryAppointmentMetadata,
      },
      ...(user.additionalAppointments?.slice(1) ?? []),
    ],
  };
}

function applyGPDTDCRepresentativeTenant(
  user: BulkUserItem,
  tenants: TenantSummary[],
): BulkUserItem | undefined {
  const root = findGPDTDCRootTenant(tenants);
  if (!root) return undefined;

  const primarySlug = user.tenantSlug || "";
  const hasPrimaryUnderRoot = isUnderTenant(primarySlug, root, tenants);
  const hasAppointmentUnderRoot = (user.additionalAppointments ?? []).some(
    (appointment) => isUnderTenant(appointment.tenantSlug || "", root, tenants),
  );
  if (!hasPrimaryUnderRoot && !hasAppointmentUnderRoot) return undefined;
  if (primarySlug === root.slug) return undefined;

  const worksmobileAppointments: BulkUserAppointment[] = [];
  const seen = new Set<string>();
  const addAppointment = (
    appointment: BulkUserAppointment,
    fallbackKey: string,
  ) => {
    const key = appointment.tenantSlug || appointment.tenantId || fallbackKey;
    if (!key || key === root.slug || seen.has(key)) return;
    seen.add(key);
    worksmobileAppointments.push(appointment);
  };

  addAppointment(buildPrimaryAppointment(user), "primary");
  for (const appointment of user.additionalAppointments ?? []) {
    addAppointment(
      { ...appointment, isPrimary: false },
      appointment.tenantSlug || "",
    );
  }

  return {
    ...user,
    tenantSlug: root.slug,
    tenantImport: {
      ...(user.tenantImport ?? {}),
      sourceTenantId: undefined,
      slug: root.slug,
      name: root.name,
    },
    additionalAppointments:
      worksmobileAppointments.length > 0 ? worksmobileAppointments : undefined,
  };
}

function buildPrimaryAppointment(user: BulkUserItem): BulkUserAppointment {
  return {
    ...(user.tenantId ? { tenantId: user.tenantId } : {}),
    ...(user.tenantSlug ? { tenantSlug: user.tenantSlug } : {}),
    isPrimary: true,
    isOwner: false,
    ...(user.department ? { department: user.department } : {}),
    ...(user.grade ? { grade: user.grade } : {}),
    ...(user.position ? { position: user.position } : {}),
    ...(user.jobTitle ? { jobTitle: user.jobTitle } : {}),
    metadata: { ...user.metadata },
  };
}

function findGPDTDCRootTenant(tenants: TenantSummary[]) {
  return tenants.find((tenant) => {
    const slug = tenant.slug.trim().toLowerCase();
    const name = tenant.name.replace(/\s+/g, "").toLowerCase();
    return (
      slug === "gpdtdc" ||
      name === "gpdtdc" ||
      name.includes("총괄기획&기술개발센터") ||
      name.includes("총괄기획기술개발센터")
    );
  });
}

function isUnderGeneralPlanningOffice(
  tenantSlug: string,
  tenants: TenantSummary[],
): boolean {
  let current = tenants.find((tenant) => tenant.slug === tenantSlug);
  while (current) {
    if (current.name === "총괄기획실") return true;
    if (!current.parentId) break;
    current = tenants.find((tenant) => tenant.id === current?.parentId);
  }
  return false;
}

function isUnderTenant(
  tenantSlug: string,
  root: TenantSummary,
  tenants: TenantSummary[],
): boolean {
  let current = tenants.find((tenant) => tenant.slug === tenantSlug);
  while (current) {
    if (current.id === root.id || current.slug === root.slug) return true;
    if (!current.parentId) break;
    current = tenants.find((tenant) => tenant.id === current?.parentId);
  }
  return false;
}

function stringValue(value: unknown) {
  return typeof value === "string" ? value : undefined;
}
