import { ReactNode, MutableRefObject } from 'react';

import { v4 } from 'uuid';
import { uuidv7 } from 'uuidv7';

import Link from '@material-hu/mui/Link';

const urlOnlyRegex = /https?:\/\/[^\s]+|www\.[^\s]+/g;

const processLinksOnly = (text: string): ReactNode[] => {
  if (!urlOnlyRegex.test(text)) {
    return [text];
  }

  const parts: ReactNode[] = [];
  let lastIndex = 0;
  let match;

  urlOnlyRegex.lastIndex = 0;
  while ((match = urlOnlyRegex.exec(text)) !== null) {
    if (match.index > lastIndex) {
      parts.push(text.substring(lastIndex, match.index));
    }

    const href = match[0].startsWith('www.') ? `https://${match[0]}` : match[0];
    parts.push(
      <Link
        key={`link-${match[0]}-${match.index}`}
        href={href}
        target="_blank"
        rel="noopener noreferrer"
        sx={{
          color: theme => theme.palette.ilustrations?.primaryIlus,
          textDecoration: 'none',
          fontWeight: 'fontWeightSemiBold',
          '&:hover': {
            textDecoration: 'underline',
          },
        }}
      >
        {match[0]}
      </Link>,
    );

    lastIndex = match.index + match[0].length;
  }

  if (lastIndex < text.length) {
    parts.push(text.substring(lastIndex));
  }

  return parts;
};

export const mapNewLines = (text: string): Array<ReactNode> => {
  if (!text) return [];

  return text.split('\n').map((item, i, arr) => {
    const lineContent = processLinksOnly(item);
    const line = <span key={i}>{lineContent}</span>;

    if (i === arr.length - 1) {
      return line;
    }

    return [line, <br key={`${i}br`} />];
  });
};

export const isTextClamped = (textRef: MutableRefObject<any>): boolean => {
  if (!textRef?.current) return false;

  const element = textRef.current;
  return element.scrollHeight > element.clientHeight;
};

export const isUrl = (str: string) => {
  const pattern = new RegExp(
    '^(https?:\\/\\/)' + // protocolo
      '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // nombre de dominio
      '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR dirección IP
      '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // puerto y path
      '(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
      '(\\#[-a-z\\d_]*)?$',
    'i',
  ); // fragmento de la URL
  return !!pattern.test(str);
};

export const getUuid = (version: 'v4' | 'v7' = 'v7'): string => {
  return version === 'v4' ? v4().toString() : uuidv7();
};

export const capitalizeText = (text: string) =>
  text.toLowerCase().replace(/\b\w/g, (char: string) => char.toUpperCase());

export const capitalizeFirstLetter = (text: string) =>
  String(text).charAt(0).toUpperCase() + String(text).slice(1);

export const truncateText = (text: string, limit: number) => {
  if (text.length <= limit) return text;
  return text.slice(0, limit - 3) + '...';
};

export const getUrlHost = (url: string) => {
  try {
    const urlObj = new URL(url);
    return urlObj.hostname;
  } catch (error) {
    return '';
  }
};

export const getEmailDomain = ({
  email,
  employeeInternalId,
}: {
  email?: string;
  employeeInternalId: string;
}): string => {
  const emailToUse = email || employeeInternalId;
  const emailRegex = /^[^\s@]+@([^\s@]+\.[^\s@]+)$/;
  const match = emailToUse.match(emailRegex);
  return match ? match[1].toLowerCase() : '';
};

export const getAbsoluteUrlPath = (url: string): string => {
  if (!url) return '';
  const path = new URL(url).pathname;
  const segments = path.split('/');

  return (
    '/' +
    segments
      .filter(
        segment =>
          segment && !/^\d+$/.test(segment) && !/^[A-Z0-9]{26}$/.test(segment),
      )
      .join('/')
  );
};

/** Function to remove UUID v7 from a stringAdd a comment on lines R94 to R96Add diff commentMarkdown input:  edit mode selected.WritePreviewAdd a suggestionHeadingBoldItalicQuoteCodeLinkUnordered listNumbered listTask listMentionReferenceSaved repliesAdd FilesPaste, drop, or click to add filesCancelCommentStart a reviewReturn to code
 *
 * @param str string to remove UUID v7 from
 * @returns string without UUID v7
 *
 * REGEX EXPLANATION:
 * - [0-9a-f]{8}           → 8 hex chars
 * - -                     → literal dash
 * - [0-9a-f]{4}           → 4 hex chars
 * - -
 * - [47][0-9a-f]{3}       → version nibble (4 or 7) + 3 hex chars
 * - -
 * - [89ab][0-9a-f]{3}     → variant nibble (8, 9, a, or b) + 3 hex chars
 * - -
 * - [0-9a-f]{12}          → 12 hex chars
 * \b boundaries + 'i'     → word boundaries, case-insensitive
 * 'g' flag                → match all occurrences
 */
export const removeUUID = (str: string) => {
  const uuidV7Regex =
    /\b[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\b/gi;

  return str
    .replace(uuidV7Regex, '')
    .replace(/\s{2,}/g, ' ')
    .trim();
};
