import {
  ALIAS_PATTERN,
  ALIAS_MAX_LENGTH,
  isReservedAlias,
  isTechnicalAlias,
  isValidAliasFormat
} from '../constants/aliases';
import { ERROR_MESSAGES, ERROR_CODES } from '../constants/errors';

export interface AliasValidationResult {
  valid: boolean;
  error?: {
    message: string;
    code: string;
  };
}

export const validateAliasFormat = (alias: string): AliasValidationResult => {
  if (!alias) {
    return {
      valid: false,
      error: {
        message: 'Alias is required',
        code: ERROR_CODES.VALIDATION_ERROR,
      },
    };
  }

  if (!alias.startsWith('@')) {
    return {
      valid: false,
      error: {
        message: ERROR_MESSAGES.INVALID_ALIAS_FORMAT,
        code: ERROR_CODES.INVALID_ALIAS_FORMAT,
      },
    };
  }

  if (alias.length > ALIAS_MAX_LENGTH) {
    return {
      valid: false,
      error: {
        message: `Alias must not exceed ${ALIAS_MAX_LENGTH} characters`,
        code: ERROR_CODES.VALIDATION_ERROR,
      },
    };
  }

  if (!ALIAS_PATTERN.test(alias)) {
    return {
      valid: false,
      error: {
        message: ERROR_MESSAGES.INVALID_ALIAS_FORMAT,
        code: ERROR_CODES.INVALID_ALIAS_FORMAT,
      },
    };
  }

  return { valid: true };
};

export const validateAliasNotReserved = (alias: string): AliasValidationResult => {
  if (isReservedAlias(alias)) {
    return {
      valid: false,
      error: {
        message: ERROR_MESSAGES.RESERVED_ALIAS,
        code: ERROR_CODES.RESERVED_ALIAS,
      },
    };
  }

  return { valid: true };
};

export const validateAliasForAssignment = (alias: string): AliasValidationResult => {
  const formatResult = validateAliasFormat(alias);
  if (!formatResult.valid) {
    return formatResult;
  }

  return validateAliasNotReserved(alias);
};

export const validateTechnicalAliasWithFlow = (
  alias: string,
  flowId?: string
): AliasValidationResult => {
  if (isTechnicalAlias(alias) && !flowId) {
    return {
      valid: false,
      error: {
        message: ERROR_MESSAGES.TECHNICAL_ALIAS_REQUIRES_FLOW,
        code: ERROR_CODES.TECHNICAL_ALIAS_REQUIRES_FLOW,
      },
    };
  }

  return { valid: true };
};

/**
 * Extract all aliases from a prompt text
 * Pattern: space followed by @ followed by alphanumeric, dash, or underscore
 * Example: "Create image based on @hero and @background" -> ["@hero", "@background"]
 */
export const extractAliasesFromPrompt = (prompt: string): string[] => {
  if (!prompt || typeof prompt !== 'string') {
    return [];
  }

  // Pattern: space then @ then word characters (including dash and underscore)
  // Also match @ at the beginning of the string
  const aliasPattern = /(?:^|\s)(@[\w-]+)/g;
  const matches: string[] = [];
  let match;

  while ((match = aliasPattern.exec(prompt)) !== null) {
    const alias = match[1]!;
    // Validate format and max length
    if (isValidAliasFormat(alias)) {
      matches.push(alias);
    }
  }

  // Remove duplicates while preserving order
  return Array.from(new Set(matches));
};
