#!/usr/bin/env node
/**
 * CLI: pull pharmacies from webhook and insert into database
 *
 *   npm run import-farmacias
 *   FARMACIAS_WEBHOOK_URL=https://... npm run import-farmacias
 *
 * Region (adds ?lat=&lon=&radio= in metres), e.g. your city:
 *   node import-farmacias.js --lat 41.5631 --lon 2.0038 --radio 1500
 *   node import-farmacias.js "https://n8n.example/webhook/farmacias" --lat 41.5631 --lon 2.0038 --radio 1500
 *
 * Env defaults for region: FARMACIAS_IMPORT_LAT, FARMACIAS_IMPORT_LON, FARMACIAS_IMPORT_RADIO
 *
 * Uses PostgreSQL when PG_URL is set, otherwise falls back to local SQLite.
 */

import sqlite3 from 'sqlite3';
import { promisify } from 'util';
import path from 'path';
import { fileURLToPath } from 'url';
import pg from 'pg';
import {
  runFarmaciaWebhookImport,
  DEFAULT_FARMACIAS_WEBHOOK,
} from './farmacias-webhook-import.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const PG_URL = process.env.PG_URL;
let pool = null;
let db = null;

let dbRun, dbGet;

if (PG_URL) {
  pool = new pg.Pool({ connectionString: PG_URL });

  function toPositional(sql) {
    let i = 0;
    return sql.replace(/\?/g, () => `$${++i}`);
  }

  dbGet = async (sql, params = []) => {
    const res = await pool.query(toPositional(sql), params);
    return res.rows[0] ?? null;
  };

  dbRun = async (sql, params = []) => {
    const res = await pool.query(toPositional(sql), params);
    return { lastID: res.rows[0]?.id, changes: res.rowCount };
  };
} else {
  const dbPath = path.join(__dirname, 'database.sqlite');
  db = new sqlite3.Database(dbPath);

  dbRun = (sql, params = []) =>
    new Promise((resolve, reject) => {
      db.run(sql, params, function (err) {
        if (err) reject(err);
        else resolve({ lastID: this.lastID, changes: this.changes });
      });
    });

  dbGet = promisify(db.get.bind(db));
}

function parseCli(argv) {
  const region = {};
  const positional = [];
  for (let i = 2; i < argv.length; i++) {
    const a = argv[i];
    if (a === '--lat' && argv[i + 1] != null) {
      region.lat = argv[++i];
      continue;
    }
    if ((a === '--lon' || a === '--lng') && argv[i + 1] != null) {
      region.lon = argv[++i];
      continue;
    }
    if (a === '--radio' && argv[i + 1] != null) {
      region.radio = argv[++i];
      continue;
    }
    if (a.startsWith('--')) {
      console.warn('Unknown flag:', a);
      continue;
    }
    positional.push(a);
  }
  if (process.env.FARMACIAS_IMPORT_LAT && region.lat == null) region.lat = process.env.FARMACIAS_IMPORT_LAT;
  if (process.env.FARMACIAS_IMPORT_LON && region.lon == null) region.lon = process.env.FARMACIAS_IMPORT_LON;
  if (process.env.FARMACIAS_IMPORT_RADIO && region.radio == null) {
    region.radio = process.env.FARMACIAS_IMPORT_RADIO;
  }
  const url = positional[0] || DEFAULT_FARMACIAS_WEBHOOK;
  const hasRegion =
    region.lat != null || region.lon != null || region.radio != null;
  return { url, region: hasRegion ? region : null };
}

async function main() {
  const { url, region } = parseCli(process.argv);
  console.log('Fetching pharmacies from:', url);
  if (region) console.log('Region query:', region);
  console.log('Using:', PG_URL ? 'PostgreSQL' : 'SQLite');

  try {
    const result = await runFarmaciaWebhookImport(dbGet, dbRun, url, region);
    console.log('Done.');
    console.log('  Total rows in response:', result.totalReceived);
    console.log('  Inserted:', result.inserted);
    console.log('  Skipped (duplicate name+address):', result.skipped);
    console.log('  Invalid (missing name or address):', result.invalid);
    if (result.errors.length) {
      console.log('  Row errors:', result.errors.length);
      console.log(result.errors.slice(0, 5));
    }
  } catch (e) {
    console.error('Import failed:', e.message);
    if (e.message.includes('Unused Respond to Webhook')) {
      console.error(
        '\n  Hint: In n8n, connect the Webhook to a single "Respond to Webhook" node, or remove unused ones.'
      );
    }
    process.exitCode = 1;
  } finally {
    if (pool) await pool.end();
    else if (db) db.close();
  }
}

main();
