const SOURCE_TYPE_LABELS = {
  manual: 'Manual',
  file_import: 'File import',
  provider_sync: 'Provider sync',
};

function sourceTypeLabel(type) {
  return SOURCE_TYPE_LABELS[type] || String(type || 'Unknown');
}

function sourceLabel(source = {}) {
  if (source.type === 'manual' || source.provider === 'manual') return source.name || 'Manual Entry';
  if (source.name && source.provider) return `${source.name} (${source.provider})`;
  return source.name || source.provider || sourceTypeLabel(source.type);
}

function decorateDataSource(row) {
  if (!row) return null;
  const safe = { ...row };
  delete safe.encrypted_secret;
  return {
    ...safe,
    source_label: sourceLabel(row),
    source_type_label: sourceTypeLabel(row.type),
  };
}

function decorateTransaction(row) {
  if (!row) return null;
  const source = row.data_source_id ? {
    id: row.data_source_id,
    user_id: row.user_id,
    type: row.data_source_type || row.source_type,
    provider: row.data_source_provider,
    name: row.data_source_name,
    status: row.data_source_status,
  } : null;

  return {
    ...row,
    source_label: source ? sourceLabel(source) : sourceTypeLabel(row.source_type),
    source_type_label: sourceTypeLabel(row.source_type),
    data_source: source ? decorateDataSource(source) : null,
  };
}

function ensureManualDataSource(db, userId) {
  const existing = db.prepare(`
    SELECT *
    FROM data_sources
    WHERE user_id = ? AND type = 'manual' AND provider = 'manual'
    ORDER BY id ASC
    LIMIT 1
  `).get(userId);
  if (existing) {
    if (existing.name !== 'Manual Entry' || existing.status !== 'active') {
      db.prepare(`
        UPDATE data_sources
        SET name = 'Manual Entry', status = 'active', updated_at = datetime('now')
        WHERE id = ? AND user_id = ?
      `).run(existing.id, userId);
      return db.prepare('SELECT * FROM data_sources WHERE id = ? AND user_id = ?').get(existing.id, userId);
    }
    return existing;
  }

  const result = db.prepare(`
    INSERT INTO data_sources (user_id, type, provider, name, status)
    VALUES (?, 'manual', 'manual', 'Manual Entry', 'active')
  `).run(userId);
  return db.prepare('SELECT * FROM data_sources WHERE id = ? AND user_id = ?').get(result.lastInsertRowid, userId);
}

function getTransactionForUser(db, userId, id) {
  return db.prepare(`
    SELECT
      t.id, t.user_id, t.data_source_id, t.account_id, t.provider_transaction_id,
      t.source_type, t.transaction_type, t.posted_date, t.transacted_at, t.amount,
      t.currency, t.description, t.payee, t.memo, t.category, t.matched_bill_id,
      t.match_status, t.ignored, t.pending, t.created_at, t.updated_at,
      ds.type AS data_source_type, ds.provider AS data_source_provider,
      ds.name AS data_source_name, ds.status AS data_source_status,
      fa.name AS account_name, fa.org_name AS account_org_name,
      fa.account_type AS account_type,
      b.name AS matched_bill_name
    FROM transactions t
    LEFT JOIN data_sources ds ON ds.id = t.data_source_id AND ds.user_id = t.user_id
    LEFT JOIN financial_accounts fa ON fa.id = t.account_id AND fa.user_id = t.user_id
    LEFT JOIN bills b ON b.id = t.matched_bill_id AND b.user_id = t.user_id AND b.deleted_at IS NULL
    WHERE t.id = ? AND t.user_id = ?
      AND (t.account_id IS NULL OR fa.id IS NULL OR fa.monitored = 1)
  `).get(id, userId);
}

module.exports = {
  SOURCE_TYPE_LABELS,
  decorateDataSource,
  decorateTransaction,
  ensureManualDataSource,
  getTransactionForUser,
  sourceLabel,
  sourceTypeLabel,
};
