import { DatabaseAccount } from "Contracts/DataModels";
import { CopyJobContextState, CopyJobErrorType, CopyJobType } from "./Types/CopyJobTypes";

const azurePortalMpacEndpoint = "https://ms.portal.azure.com/";

export const buildResourceLink = (resource: DatabaseAccount): string => {
  const resourceId = resource.id;
  let parentOrigin = window.location.ancestorOrigins?.[0] ?? window.location.origin;

  if (/\/\/localhost:/.test(parentOrigin)) {
    parentOrigin = azurePortalMpacEndpoint;
  } else if (/\/\/cosmos\.azure/.test(parentOrigin)) {
    parentOrigin = parentOrigin.replace("cosmos.azure", "portal.azure");
  }

  parentOrigin = parentOrigin.replace(/\/$/, "");

  return `${parentOrigin}/#resource${resourceId}`;
};

export const COSMOS_SQL_COMPONENT = "CosmosDBSql";

export const COPY_JOB_API_VERSION = "2025-05-01-preview";

export function buildDataTransferJobPath({
  subscriptionId,
  resourceGroup,
  accountName,
  jobName,
  action,
}: {
  subscriptionId: string;
  resourceGroup: string;
  accountName: string;
  jobName?: string;
  action?: string;
}) {
  let path = `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.DocumentDB/databaseAccounts/${accountName}/dataTransferJobs`;
  if (jobName) {
    path += `/${jobName}`;
  }
  if (action) {
    path += `/${action}`;
  }
  return path;
}

export function convertTime(timeStr: string): string | null {
  const timeParts = timeStr.split(":").map(Number);

  if (timeParts.length !== 3 || timeParts.some(isNaN)) {
    return null;
  }
  const formatPart = (value: number, unit: string) => {
    if (unit === "seconds") {
      value = Math.round(value);
    }
    return value > 0 ? `${value.toString().padStart(2, "0")} ${unit}` : "";
  };

  const [hours, minutes, seconds] = timeParts;
  const formattedTimeParts = [
    formatPart(hours, "hours"),
    formatPart(minutes, "minutes"),
    formatPart(seconds, "seconds"),
  ]
    .filter(Boolean)
    .join(", ");

  return formattedTimeParts || "0 seconds";
}

export function formatUTCDateTime(utcStr: string): { formattedDateTime: string; timestamp: number } | null {
  const date = new Date(utcStr);
  if (isNaN(date.getTime())) {
    return null;
  }

  return {
    formattedDateTime: new Intl.DateTimeFormat("en-US", {
      dateStyle: "short",
      timeStyle: "medium",
      timeZone: "UTC",
    }).format(date),
    timestamp: date.getTime(),
  };
}

export function convertToCamelCase(str: string): string {
  const formattedStr = str
    .split(/\s+/)
    .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
    .join("");
  return formattedStr;
}

export function extractErrorMessage(error: CopyJobErrorType): CopyJobErrorType {
  return {
    ...error,
    message: error.message.split("\r\n\r\n")[0],
  };
}

export function getAccountDetailsFromResourceId(accountId: string | undefined) {
  if (!accountId) {
    return null;
  }
  const pattern = new RegExp(
    "/subscriptions/([^/]+)/resourceGroups/([^/]+)/providers/Microsoft\\.DocumentDB?/databaseAccounts/([^/]+)",
    "i",
  );
  const matches = accountId.match(pattern);
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const [_, subscriptionId, resourceGroup, accountName] = matches || [];
  return { subscriptionId, resourceGroup, accountName };
}

export function getContainerIdentifiers(container: CopyJobContextState["source"] | CopyJobContextState["target"]) {
  return {
    accountId: container?.account?.id || "",
    databaseId: container?.databaseId || "",
    containerId: container?.containerId || "",
  };
}

export function isIntraAccountCopy(sourceAccountId: string | undefined, targetAccountId: string | undefined): boolean {
  const sourceAccountDetails = getAccountDetailsFromResourceId(sourceAccountId);
  const targetAccountDetails = getAccountDetailsFromResourceId(targetAccountId);
  return (
    sourceAccountDetails?.subscriptionId === targetAccountDetails?.subscriptionId &&
    sourceAccountDetails?.resourceGroup === targetAccountDetails?.resourceGroup &&
    sourceAccountDetails?.accountName === targetAccountDetails?.accountName
  );
}

export function isEqual(prevJobs: CopyJobType[], newJobs: CopyJobType[]): boolean {
  if (prevJobs.length !== newJobs.length) {
    return false;
  }
  return prevJobs.every((prevJob: CopyJobType) => {
    const newJob = newJobs.find((job) => job.Name === prevJob.Name);
    if (!newJob) {
      return false;
    }
    return prevJob.Status === newJob.Status && prevJob.CompletionPercentage === newJob.CompletionPercentage;
  });
}

const truncateLength = 5;
export const truncateName = (name: string, length: number = truncateLength): string => {
  return name.length <= length ? name : name.slice(0, length);
};

export function getDefaultJobName(
  selectedDatabaseAndContainers: {
    sourceDatabaseName?: string;
    sourceContainerName?: string;
    targetDatabaseName?: string;
    targetContainerName?: string;
  }[],
): string {
  if (selectedDatabaseAndContainers.length === 1) {
    const { sourceDatabaseName, sourceContainerName, targetDatabaseName, targetContainerName } =
      selectedDatabaseAndContainers[0];
    const timestamp = new Date().getTime().toString();
    const sourcePart = `${truncateName(sourceDatabaseName)}.${truncateName(sourceContainerName)}`;
    const targetPart = `${truncateName(targetDatabaseName)}.${truncateName(targetContainerName)}`;
    return `${sourcePart}_${targetPart}_${timestamp}`;
  }
  return "";
}
