'use strict';

const QUOTE_CHAR = '"';

function mapType(field) {
  switch (field.type) {
    case 'string':
      return `VARCHAR(${field.length})`;
    case 'text':
      return 'TEXT';
    case 'integer':
      return 'INTEGER';
    case 'bigint':
      return 'BIGINT';
    case 'decimal':
      return `DECIMAL(${field.precision},${field.scale})`;
    case 'boolean':
      return 'BOOLEAN';
    case 'date':
      return 'DATE';
    case 'timestamp':
      return 'TIMESTAMP';
    case 'uuid':
      return 'UUID';
    case 'json':
      return 'JSONB';
    default:
      throw new Error(`Unknown type: '${field.type}'`);
  }
}

function formatDefault(def) {
  if (def.kind === 'literal') {
    if (typeof def.value === 'boolean') return def.value ? 'TRUE' : 'FALSE';
    if (typeof def.value === 'number') return String(def.value);
    if (typeof def.value === 'string') return `'${def.value.replace(/'/g, "''")}'`;
    throw new Error(`Unknown literal type: '${typeof def.value}'`);
  }

  if (def.kind === 'function') {
    if (def.name === 'now') return 'CURRENT_TIMESTAMP';
    throw new Error(`Unknown function: '${def.name}'`);
  }

  if (def.kind === 'constant') {
    if (def.value === 'current_date') return 'CURRENT_DATE';
    throw new Error(`Unknown constant: '${def.value}'`);
  }

  throw new Error(`Unknown default kind: '${def.kind}'`);
}

function quoteIdentifier(identifier) {
  if (typeof identifier !== 'string' || identifier === '') {
    throw new Error('Identifier must be a non-empty string');
  }
  return identifier;
}

function formatTableIdentifier(ir) {
  if (!ir || typeof ir.tableName !== 'string' || ir.tableName === '') {
    throw new Error('formatTableIdentifier: ir.tableName must be a non-empty string');
  }
  if (ir.schemaName) {
    return `${quoteIdentifier(ir.schemaName)}.${quoteIdentifier(ir.tableName)}`;
  }
  return quoteIdentifier(ir.tableName);
}

function formatReferentialAction(action) {
  switch (action) {
    case 'cascade': return 'CASCADE';
    case 'restrict': return 'RESTRICT';
    case 'setNull': return 'SET NULL';
    case 'noAction': return 'NO ACTION';
    default:
      throw new Error(`Unknown referential action: '${action}'`);
  }
}

module.exports = {
  name: 'postgres',
  maxIdentifierLength: 63,
  // PostgreSQL punya tipe BOOLEAN native; dialect lain menyimpan boolean
  // sebagai VARCHAR 'true'/'false' dan butuh CHECK sebagai penanda boolean.
  nativeBoolean: true,
  mapType,
  formatDefault,
  quoteIdentifier,
  formatTableIdentifier,
  formatReferentialAction
};
