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

export function parseUserCSV(text: string): BulkUserItem[] {
  const records = parseCSVRecords(text.replace(/^\uFEFF/, ""));
  if (records.length < 2) {
    return [];
  }

  const headers = records[0].map(normalizeHeader);
  const data: BulkUserItem[] = [];

  for (let i = 1; i < records.length; i++) {
    const values = records[i].map((v) => v.trim());
    if (values.every((value) => value === "")) continue;
    const item: Partial<BulkUserItem> & { metadata: Record<string, string> } = {
      metadata: {},
    };
    const additionalAppointment: BulkUserAppointment & {
      metadata: Record<string, string>;
    } = {
      metadata: {},
    };

    for (let index = 0; index < headers.length; index++) {
      const header = headers[index];
      const value = values[index];
      if (value === undefined || value === "") continue;

      if (header === "email") {
        item.email = value;
      } else if (header === "name") {
        item.name = value;
      } else if (header === "phone") {
        item.phone = value;
      } else if (header === "role") {
        item.role = value;
      } else if (header === "tenant") {
        item.tenantSlug = value;
      } else if (header === "tenant_slug" || header === "companycode") {
        item.tenantSlug = value;
        item.tenantImport = {
          ...(item.tenantImport ?? {}),
          slug: value,
        };
      } else if (header === "tenant_id") {
        item.tenantId = value;
        item.tenantImport = {
          ...(item.tenantImport ?? {}),
          sourceTenantId: value,
        };
      } else if (header === "tenant_name") {
        item.tenantImport = {
          ...(item.tenantImport ?? {}),
          name: value,
        };
      } else if (header === "tenant_type") {
        item.tenantImport = {
          ...(item.tenantImport ?? {}),
          type: value,
        };
      } else if (header === "parent_tenant_id") {
        item.tenantImport = {
          ...(item.tenantImport ?? {}),
          parentTenantId: value,
        };
      } else if (header === "parent_tenant_slug") {
        item.tenantImport = {
          ...(item.tenantImport ?? {}),
          parentTenantSlug: value,
        };
      } else if (header === "parent_tenant_name") {
        item.tenantImport = {
          ...(item.tenantImport ?? {}),
          parentTenantName: value,
        };
      } else if (header === "tenant_memo") {
        item.tenantImport = {
          ...(item.tenantImport ?? {}),
          memo: value,
        };
      } else if (header === "email_domain" || header === "tenant_domain") {
        item.emailDomain = value;
        item.tenantImport = {
          ...(item.tenantImport ?? {}),
          emailDomain: value,
        };
      } else if (header === "department") {
        item.department = value;
      } else if (header === "grade") {
        item.grade = value;
      } else if (header === "position") {
        item.position = value;
      } else if (header === "jobtitle") {
        item.jobTitle = value;
      } else if (header === "employee_id") {
        item.metadata.employee_id = value;
      } else if (header === "tenant_slug1") {
        additionalAppointment.tenantSlug = value;
      } else if (header === "department1") {
        additionalAppointment.department = value;
      } else if (header === "grade1") {
        additionalAppointment.grade = value;
      } else if (header === "position1") {
        additionalAppointment.position = value;
      } else if (header === "jobtitle1") {
        additionalAppointment.jobTitle = value;
      } else if (header === "employee_id1") {
        additionalAppointment.metadata.employee_id = value;
      } else if (header === "lastname") {
        item.metadata.naverworks_last_name = value;
      } else if (header === "firstname") {
        item.metadata.naverworks_first_name = value;
      } else if (header === "id") {
        item.loginId = value;
        item.metadata.naverworks_id = value;
      } else if (header === "personalemail") {
        item.metadata.personal_email = value;
      } else if (header === "subemail") {
        item.metadata.naverworks_sub_email = value;
        item.email = firstEmailToken(value) || item.email;
      } else if (header === "nickname") {
        item.metadata.naverworks_nickname = value;
      } else if (header === "usertype") {
        item.metadata.naverworks_user_type = value;
      } else if (header === "level") {
        item.grade = value;
        item.metadata.naverworks_level = value;
      } else if (header === "organization") {
        item.metadata.naverworks_organization_path = value;
        const parts = splitOrganizationPath(value);
        const leaf = parts.at(-1) ?? "";
        const parent = parts.at(-2) ?? "";
        if (leaf) {
          item.department = leaf;
          item.tenantImport = {
            ...(item.tenantImport ?? {}),
            name: leaf,
            parentTenantName: parent,
          };
        }
      } else if (header === "companymainphone") {
        item.metadata.naverworks_company_main_phone = value;
      } else if (header === "mobilecountrycode") {
        item.metadata.naverworks_mobile_country_code = value;
      } else if (header === "mobilenumbers") {
        item.metadata.naverworks_mobile_numbers = value;
      } else if (header === "language") {
        item.metadata.naverworks_language = value;
      } else if (header === "responsibilities") {
        item.jobTitle = value;
      } else if (header === "workplace") {
        item.metadata.naverworks_workplace = value;
      } else if (header === "sns") {
        item.metadata.naverworks_sns = value;
      } else if (header === "snsid") {
        item.metadata.naverworks_sns_id = value;
      } else if (header === "birthdaysolarlunar") {
        item.metadata.naverworks_birthday_calendar = value;
      } else if (header === "birthday") {
        item.metadata.naverworks_birthday = value;
      } else if (header === "entrydate") {
        item.metadata.naverworks_entry_date = value;
      } else if (header === "employeenumber") {
        item.metadata.employee_id = value;
      } else if (header === "accountactivationtime") {
        item.metadata.naverworks_account_activation_time = value;
      } else {
        item.metadata[header] = value;
      }
    }

    applyNaverWorksFallbacks(item);
    if (additionalAppointment.tenantSlug) {
      item.additionalAppointments = [
        cleanAdditionalAppointment(additionalAppointment),
      ];
    }

    if (item.email && item.name) {
      data.push(item as BulkUserItem);
    }
  }

  return data;
}

function cleanAdditionalAppointment(
  appointment: BulkUserAppointment & { metadata: Record<string, string> },
) {
  const metadata =
    Object.keys(appointment.metadata).length > 0
      ? appointment.metadata
      : undefined;
  return {
    ...(appointment.tenantId ? { tenantId: appointment.tenantId } : {}),
    ...(appointment.tenantSlug ? { tenantSlug: appointment.tenantSlug } : {}),
    ...(appointment.tenantName ? { tenantName: appointment.tenantName } : {}),
    ...(appointment.isPrimary !== undefined
      ? { isPrimary: appointment.isPrimary }
      : {}),
    ...(appointment.isOwner !== undefined
      ? { isOwner: appointment.isOwner }
      : {}),
    ...(appointment.department ? { department: appointment.department } : {}),
    ...(appointment.grade ? { grade: appointment.grade } : {}),
    ...(appointment.position ? { position: appointment.position } : {}),
    ...(appointment.jobTitle ? { jobTitle: appointment.jobTitle } : {}),
    ...(metadata ? { metadata } : {}),
  };
}

function normalizeHeader(header: string) {
  return header
    .trim()
    .toLowerCase()
    .replace(/^\uFEFF/, "")
    .replace(/[^a-z0-9_]/g, "");
}

function parseCSVRecords(text: string) {
  const records: string[][] = [];
  let field = "";
  let row: string[] = [];
  let quoted = false;

  for (let index = 0; index < text.length; index++) {
    const char = text[index];
    const next = text[index + 1];

    if (char === '"') {
      if (quoted && next === '"') {
        field += '"';
        index++;
      } else {
        quoted = !quoted;
      }
      continue;
    }

    if (char === "," && !quoted) {
      row.push(field);
      field = "";
      continue;
    }

    if ((char === "\n" || char === "\r") && !quoted) {
      if (char === "\r" && next === "\n") index++;
      row.push(field);
      records.push(row);
      field = "";
      row = [];
      continue;
    }

    field += char;
  }

  if (field !== "" || row.length > 0) {
    row.push(field);
    records.push(row);
  }

  return records;
}

function firstEmailToken(value: string) {
  return (
    value
      .split(/[;,]/)
      .map((token) => token.trim())
      .find((token) => token.includes("@")) ?? ""
  );
}

function splitOrganizationPath(value: string) {
  return value
    .split("|")
    .map((part) => part.trim())
    .filter(Boolean);
}

function applyNaverWorksFallbacks(
  item: Partial<BulkUserItem> & { metadata: Record<string, string> },
) {
  if (!item.name) {
    const firstName = item.metadata.naverworks_first_name ?? "";
    const lastName = item.metadata.naverworks_last_name ?? "";
    item.name = [firstName, lastName].filter(Boolean).join(" ").trim();
    if (!item.name && item.metadata.naverworks_nickname) {
      item.name = item.metadata.naverworks_nickname;
    }
  }

  if (!item.email) {
    item.email = item.metadata.personal_email;
  }

  if (!item.phone) {
    const countryCode = item.metadata.naverworks_mobile_country_code ?? "";
    const number = item.metadata.naverworks_mobile_numbers ?? "";
    item.phone = `${countryCode}${number}`.replace(/\s/g, "");
  }

  if (!item.grade && item.metadata.naverworks_level) {
    item.grade = item.metadata.naverworks_level;
  }
}
