'use strict';

const crypto = require('crypto');
const { getAgentConfig, isConfigured } = require('../../agent/agentConfig');
const { postJson } = require('../../agent/syncClient');

const TOKEN_PATH = '/api/agent/mefacturo/tickets/token';

function validateTicketToken(value) {
  const token = String(value || '').trim();
  if (!/^tkt_[A-Za-z0-9_-]{16,}$/.test(token)) throw new Error('cloud_ticket_token_invalid');
  return token;
}

function slugFromPublicUrl(value) {
  try {
    const parts = new URL(String(value || '')).pathname.split('/').filter(Boolean);
    const tokenIndex = parts.indexOf('t');
    return tokenIndex > 0 ? decodeURIComponent(parts[tokenIndex - 1]) : '';
  } catch (_) {
    return '';
  }
}

function sha256(value) {
  return crypto.createHash('sha256').update(String(value || '')).digest('hex');
}

function extractToken(response) {
  return response?.ticketToken
    || response?.ticket_token
    || response?.ticket?.ticket_token
    || response?.ticket?.ticketToken;
}

function extractPortalUrl(response) {
  return response?.portalUrl || response?.portal_url || response?.public_url || null;
}

async function requestTicketToken(parsed = {}, options = {}) {
  const config = options.agentConfig || getAgentConfig();
  if (!isConfigured(config)) throw new Error('cloud_agent_not_configured');
  const billingCode = String(parsed.cfacturacion || parsed.billingCode || '').trim().toUpperCase();
  if (!billingCode) throw new Error('billing_code_required');
  const request = options.postJson || postJson;
  const branchId = parsed.branchId || options.branchId || config.branchId || null;
  const tenantId = parsed.tenantId || options.tenantId || config.tenantId || null;
  const branchCode = parsed.branchCode || options.branchCode || config.branchCode || process.env.ARKHON_BRANCH_CODE || null;
  const branchSlug = parsed.branchSlug || options.branchSlug || config.branchSlug || process.env.ARKHON_BRANCH_SLUG || null;
  const folio = parsed.folio || null;
  const total = parsed.total == null ? null : Number(parsed.total);
  const idempotencyKey = sha256(`${tenantId || ''}${branchId || ''}${billingCode}${folio || ''}${total == null ? '' : total}`);
  const response = await request(config, TOKEN_PATH, {
    tenantId,
    branchId,
    branchCode,
    branchSlug,
    billingCode,
    billing_code: billingCode,
    folio,
    total,
    issuedAt: parsed.issuedAt || parsed.fechaHora || parsed.fecha || null,
    source: 'softrestaurant_prn',
    documentType: parsed.documentType || null,
    agentId: config.agentId || null,
    hwid: config.hwid || config.hardwareId || process.env.ARKHON_HWID || null,
    idempotencyKey,
  });
  const token = validateTicketToken(extractToken(response));
  const portalUrl = extractPortalUrl(response);
  return {
    token,
    slug: response?.branchSlug || slugFromPublicUrl(portalUrl),
    publicUrl: portalUrl,
    expiresAt: response?.expiresAt || response?.expires_at || response?.ticket?.expires_at || null,
    reused: response?.reused === true,
    idempotencyKey,
  };
}

module.exports = {
  TOKEN_PATH,
  sha256,
  validateTicketToken,
  requestTicketToken,
};
