export type QueryResultTableRef = {
  tableName: string;
  metadataDbName: string;
  metadataTableName: string;
};

const stripIdentifierQuotes = (part: string): string => {
  const text = String(part || '').trim();
  if (!text) return '';
  if ((text.startsWith('`') && text.endsWith('`')) || (text.startsWith('"') && text.endsWith('"'))) {
    return text.slice(1, -1).trim();
  }
  if (text.startsWith('[') && text.endsWith(']')) {
    return text.slice(1, -1).trim();
  }
  return text;
};

const isOracleLikeDialect = (dialect: string): boolean => {
  const normalized = String(dialect || '').trim().toLowerCase();
  return normalized === 'oracle' || normalized === 'dameng' || normalized === 'dm' || normalized === 'dm8';
};

const keepsQualifiedTableNameForMetadata = (dialect: string): boolean => {
  const normalized = String(dialect || '').trim().toLowerCase();
  return normalized === 'duckdb';
};

const isQuotedIdentifier = (part: string): boolean => {
  const text = String(part || '').trim();
  if (!text) return false;
  return (text.startsWith('`') && text.endsWith('`'))
    || (text.startsWith('"') && text.endsWith('"'))
    || (text.startsWith('[') && text.endsWith(']'));
};

const normalizeIdentifierPart = (part: string, dialect: string): string => {
  const text = String(part || '').trim();
  const value = stripIdentifierQuotes(text);
  if (!value) return '';
  if (isOracleLikeDialect(dialect) && !isQuotedIdentifier(text)) {
    return value.toUpperCase();
  }
  return value;
};

const normalizeCurrentDbName = (currentDb: string, dialect: string): string => {
  const value = String(currentDb || '').trim();
  if (!value) return '';
  return isOracleLikeDialect(dialect) ? value.toUpperCase() : value;
};

const normalizeQualifiedNameParts = (raw: string, dialect: string): string[] => (
  String(raw || '')
    .split('.')
    .map((part) => normalizeIdentifierPart(part, dialect))
    .filter(Boolean)
);

export const extractQueryResultTableRef = (
  sql: string,
  dialect: string,
  currentDb: string,
): QueryResultTableRef | undefined => {
  const text = String(sql || '').trim();
  if (!text) return undefined;
  if (/\b(JOIN|UNION|INTERSECT|EXCEPT|MINUS)\b/i.test(text)) return undefined;
  if (/^\s*SELECT\s+DISTINCT\b/i.test(text)) return undefined;
  if (/\bGROUP\s+BY\b|\bHAVING\b/i.test(text)) return undefined;

  const tableMatch = text.match(/^\s*SELECT\s+.+?\s+FROM\s+((?:[`"\[]?\w+[`"\]]?)(?:\s*\.\s*(?:[`"\[]?\w+[`"\]]?)){0,2})\s*(?:$|[\s;])/im);
  if (!tableMatch) return undefined;

  const parts = normalizeQualifiedNameParts(tableMatch[1], dialect);
  if (parts.length === 0) return undefined;
  const metadataTableName = parts[parts.length - 1] || '';
  if (!metadataTableName) return undefined;

  const owner = parts.length >= 2 ? parts[parts.length - 2] : '';
  const metadataDbName = owner || normalizeCurrentDbName(currentDb, dialect);
  const tableName = (isOracleLikeDialect(dialect) || keepsQualifiedTableNameForMetadata(dialect)) && owner
    ? `${owner}.${metadataTableName}`
    : metadataTableName;
  const resolvedMetadataTableName = keepsQualifiedTableNameForMetadata(dialect) && owner
    ? `${owner}.${metadataTableName}`
    : metadataTableName;

  return {
    tableName,
    metadataDbName,
    metadataTableName: resolvedMetadataTableName,
  };
};
