const crypto = require('crypto');
const { INVIMA_DATASETS } = require('../APIinvima');

const cleanText = (value) => {
  if (value === null || value === undefined) return null;
  const text = String(value).trim();
  if (!text) return null;
  if (text.toLowerCase() === 'null') return null;
  return text;
};

const pickFirst = (row, keys) => {
  for (const key of keys) {
    const value = cleanText(row[key]);
    if (value) return value;
  }
  return null;
};

const parseDateFlexible = (value) => {
  const text = cleanText(value);
  if (!text) return null;

  const slashDate = text.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/);
  if (slashDate) {
    const month = slashDate[1].padStart(2, '0');
    const day = slashDate[2].padStart(2, '0');
    return `${slashDate[3]}-${month}-${day}`;
  }

  const parsed = new Date(text);
  if (Number.isNaN(parsed.getTime())) return null;
  return parsed.toISOString().slice(0, 10);
};

const buildUid = (datasetKey, rawParts, row) => {
  const parts = rawParts.map(cleanText).filter(Boolean);
  const base = parts.length ? `${datasetKey}|${parts.join('|')}` : `${datasetKey}|${JSON.stringify(row)}`;
  return crypto.createHash('sha1').update(base).digest('hex');
};

const baseRecord = (dataset, row) => ({
  source_dataset_key: dataset.key,
  source_dataset_id: dataset.id,
  source_dataset_name: dataset.name,
  categoria_linea: dataset.defaultCategory,
  expediente: null,
  registro_sanitario: null,
  producto: null,
  titular: null,
  estado_registro: null,
  fecha_expedicion: null,
  fecha_vencimiento: null,
  modalidad: null,
  grupo: null,
  marca: null,
  principio_activo: null,
  forma_farmaceutica: null,
  presentacion_comercial: null,
  atc: null,
  rol_nombre: null,
  rol_tipo: null,
  ciudad_titular: null,
  pais_titular: null,
  fabricante: null,
  importador: null,
  vigencia: null,
  extra: row
});

const buildAdapter = (datasetKey, normalize) => {
  const dataset = INVIMA_DATASETS[datasetKey];
  if (!dataset) {
    throw new Error(`Dataset no configurado en APIinvima.json: ${datasetKey}`);
  }
  return {
    ...dataset,
    normalize
  };
};

const invimaAdapters = {
  dispositivos: buildAdapter('dispositivos', (row) => {
    const record = baseRecord(INVIMA_DATASETS.dispositivos, row);
    record.expediente = cleanText(row.expediente);
    record.registro_sanitario = pickFirst(row, ['registro_sanitario']);
    record.producto = pickFirst(row, ['prodcuto', 'producto']);
    record.titular = cleanText(row.titular);
    record.estado_registro = cleanText(row.estado_registro);
    record.fecha_vencimiento = parseDateFlexible(row.fecha_vencimiento);
    record.modalidad = cleanText(row.modalidad);
    record.grupo = cleanText(row.grupo);
    record.marca = cleanText(row.marca);
    record.rol_nombre = cleanText(row.nombre_rol);
    record.rol_tipo = cleanText(row.rol);
    record.ciudad_titular = cleanText(row.ciudad_titular);
    record.pais_titular = cleanText(row.pais_titular);
    record.vigencia = cleanText(row.estado_registro);
    return {
      ...record,
      source_uid: buildUid(
        'dispositivos',
        [row.registro_sanitario, row.expediente, row.prodcuto, row.nombre_rol, row.modalidad],
        row
      )
    };
  }),

  rs_nso: buildAdapter('rs_nso', (row) => {
    const record = baseRecord(INVIMA_DATASETS.rs_nso, row);
    record.categoria_linea = cleanText(row.grupo) || INVIMA_DATASETS.rs_nso.defaultCategory;
    record.expediente = cleanText(row.expediente);
    record.registro_sanitario = cleanText(row.rsynso);
    record.producto = cleanText(row.producto);
    record.titular = cleanText(row.titular);
    record.estado_registro = cleanText(row.estadoregistro);
    record.fecha_expedicion = parseDateFlexible(row.fechaexpedicion);
    record.fecha_vencimiento = parseDateFlexible(row.fechavencimiento);
    record.modalidad = cleanText(row.modalidad);
    record.grupo = cleanText(row.grupo);
    record.rol_nombre = cleanText(row.nombrerol);
    record.rol_tipo = cleanText(row.rol);
    record.vigencia = cleanText(row.estadoregistro);
    return {
      ...record,
      source_uid: buildUid('rs_nso', [row.rsynso, row.expediente, row.producto, row.nombrerol], row)
    };
  }),

  medicamentos: buildAdapter('medicamentos', (row) => {
    const record = baseRecord(INVIMA_DATASETS.medicamentos, row);
    record.expediente = cleanText(row.expediente);
    record.registro_sanitario = cleanText(row.registrosanitario);
    record.producto = cleanText(row.producto);
    record.titular = cleanText(row.titular);
    record.estado_registro = cleanText(row.estadoregistro);
    record.fecha_expedicion = parseDateFlexible(row.fechaexpedicion);
    record.fecha_vencimiento = parseDateFlexible(row.fechavencimiento);
    record.modalidad = cleanText(row.modalidad);
    record.principio_activo = cleanText(row.principioactivo);
    record.forma_farmaceutica = cleanText(row.formafarmaceutica);
    record.presentacion_comercial = cleanText(row.descripcioncomercial);
    record.atc = cleanText(row.atc);
    record.rol_nombre = cleanText(row.nombrerol);
    record.rol_tipo = cleanText(row.tiporol);
    record.vigencia = cleanText(row.estadocum) || cleanText(row.estadoregistro);
    return {
      ...record,
      source_uid: buildUid(
        'medicamentos',
        [row.registrosanitario, row.expedientecum, row.consecutivocum, row.producto],
        row
      )
    };
  }),

  cum_vigentes: buildAdapter('cum_vigentes', (row) => {
    const record = baseRecord(INVIMA_DATASETS.cum_vigentes, row);
    record.expediente = cleanText(row.expediente);
    record.registro_sanitario = cleanText(row.registrosanitario);
    record.producto = cleanText(row.producto);
    record.titular = cleanText(row.titular);
    record.estado_registro = cleanText(row.estadoregistro);
    record.fecha_expedicion = parseDateFlexible(row.fechaexpedicion);
    record.modalidad = cleanText(row.modalidad);
    record.principio_activo = cleanText(row.principioactivo);
    record.forma_farmaceutica = cleanText(row.formafarmaceutica);
    record.presentacion_comercial = cleanText(row.descripcioncomercial);
    record.atc = cleanText(row.atc);
    record.rol_nombre = cleanText(row.nombrerol);
    record.rol_tipo = cleanText(row.tiporol);
    record.vigencia = cleanText(row.estadocum) || cleanText(row.estadoregistro);
    return {
      ...record,
      source_uid: buildUid(
        'cum_vigentes',
        [row.registrosanitario, row.expedientecum, row.consecutivocum, row.producto],
        row
      )
    };
  }),

  homeopaticos: buildAdapter('homeopaticos', (row) => {
    const record = baseRecord(INVIMA_DATASETS.homeopaticos, row);
    record.expediente = cleanText(row.expediente);
    record.registro_sanitario = cleanText(row.registro_sanitario);
    record.producto = cleanText(row.producto);
    record.titular = cleanText(row.titular);
    record.estado_registro = cleanText(row.estado_registro);
    record.fecha_expedicion = parseDateFlexible(row.fecha_expedicion);
    record.modalidad = cleanText(row.modalidad);
    record.marca = cleanText(row.marca);
    record.principio_activo = cleanText(row.principio_activo);
    record.forma_farmaceutica = cleanText(row.forma_farmaceutica);
    record.presentacion_comercial = cleanText(row.presentacioncomercial);
    record.rol_tipo = cleanText(row.rol);
    record.ciudad_titular = cleanText(row.ciudad_titular);
    record.vigencia = cleanText(row.estado_registro);
    return {
      ...record,
      source_uid: buildUid('homeopaticos', [row.registro_sanitario, row.expediente, row.producto], row)
    };
  }),

  fitoterapeuticos: buildAdapter('fitoterapeuticos', (row) => {
    const record = baseRecord(INVIMA_DATASETS.fitoterapeuticos, row);
    record.expediente = cleanText(row.expediente);
    record.registro_sanitario = cleanText(row.registro_sanitario);
    record.producto = cleanText(row.producto);
    record.titular = cleanText(row.titular);
    record.fecha_expedicion = parseDateFlexible(row.fecha_expedicion);
    record.fecha_vencimiento = parseDateFlexible(row.fecha_vencimiento);
    record.modalidad = cleanText(row.modalidad);
    record.marca = cleanText(row.marca);
    record.principio_activo = cleanText(row.principio_activo);
    record.forma_farmaceutica = cleanText(row.forma_farmaceutica);
    record.presentacion_comercial = cleanText(row.presentacioncomercial);
    record.rol_tipo = cleanText(row.rol);
    record.ciudad_titular = cleanText(row.ciudad_titular);
    record.vigencia = cleanText(row.fecha_vencimiento);
    return {
      ...record,
      source_uid: buildUid('fitoterapeuticos', [row.registro_sanitario, row.expediente, row.producto], row)
    };
  }),

  suplementos: buildAdapter('suplementos', (row) => {
    const record = baseRecord(INVIMA_DATASETS.suplementos, row);
    record.expediente = cleanText(row.expediente);
    record.registro_sanitario = cleanText(row.registro_sanitario);
    record.producto = cleanText(row.producto);
    record.titular = cleanText(row.titular);
    record.estado_registro = cleanText(row.estado_registro);
    record.fecha_expedicion = parseDateFlexible(row.fecha_expedicion);
    record.fecha_vencimiento = parseDateFlexible(row.fecha_vencimiento);
    record.modalidad = cleanText(row.modalidad);
    record.marca = cleanText(row.marca);
    record.forma_farmaceutica = cleanText(row.forma_farmaceutica);
    record.presentacion_comercial = cleanText(row.presentacioncomercial);
    record.ciudad_titular = cleanText(row.ciudad_titular);
    record.vigencia = cleanText(row.estado_registro);
    return {
      ...record,
      source_uid: buildUid('suplementos', [row.registro_sanitario, row.expediente, row.producto], row)
    };
  }),

  vacunas: buildAdapter('vacunas', (row) => {
    const record = baseRecord(INVIMA_DATASETS.vacunas, row);
    record.expediente = cleanText(row.expediente);
    record.registro_sanitario = cleanText(row.registro_sanitario);
    record.producto = cleanText(row.producto);
    record.titular = cleanText(row.titular);
    record.estado_registro = cleanText(row.vigencia);
    record.modalidad = cleanText(row.via_de_administraci_n);
    record.principio_activo = cleanText(row.principio_activo);
    record.forma_farmaceutica = cleanText(row.forma_farmac_utica);
    record.presentacion_comercial = cleanText(row.presentaci_n_comercial);
    record.atc = cleanText(row.atc);
    record.fabricante = cleanText(row.fabricante);
    record.importador = cleanText(row.importador);
    record.vigencia = cleanText(row.vigencia);
    return {
      ...record,
      source_uid: buildUid('vacunas', [row.consec, row.registro_sanitario, row.expediente, row.producto], row)
    };
  })
};

const adapterKeys = Object.keys(invimaAdapters);

module.exports = {
  invimaAdapters,
  adapterKeys,
  cleanText,
  parseDateFlexible,
  pickFirst
};
