import { GATEWAY_URL } from '../auth/authConfig';

// ── Helpers ──

function authHeaders(sessionToken) {
  const h = { 'Content-Type': 'application/json' };
  if (sessionToken) h['Authorization'] = `Bearer ${sessionToken}`;
  const tid = localStorage.getItem('adplatform_tenantId');
  if (tid) h['X-Tenant-Id'] = tid;
  return h;
}

async function gw(method, path, body, sessionToken) {
  try {
    const opts = { method, headers: authHeaders(sessionToken) };
    if (body && method !== 'GET') opts.body = JSON.stringify(body);
    const res = await fetch(`${GATEWAY_URL}${path}`, opts);
    const data = await res.json().catch(() => null);
    return {
      ok: res.ok && data?.ok !== false,
      status: res.status,
      data,
      error: res.ok ? null : (data?.error || data?.message || `HTTP ${res.status}`)
    };
  } catch (e) {
    return { ok: false, status: 0, data: null, error: e.message };
  }
}

function qs(params) {
  const sp = new URLSearchParams();
  Object.entries(params).forEach(([k, v]) => {
    if (v != null) sp.set(k, String(v));
  });
  const s = sp.toString();
  return s ? '?' + s : '';
}

// ── Initiative CRUD ──

export function createInitiative(data, sessionToken) {
  return gw('POST', '/api/initiative', data, sessionToken);
}

export function getInitiative(initiativeId, sessionToken) {
  return gw('GET', `/api/initiative/${initiativeId}`, null, sessionToken);
}

export function listInitiatives(sessionToken, status, page, pageSize) {
  return gw('GET', `/api/initiative${qs({ status, page, pageSize })}`, null, sessionToken);
}

export function updateInitiative(initiativeId, data, sessionToken) {
  return gw('PUT', `/api/initiative/${initiativeId}`, data, sessionToken);
}

export function updateInitiativeStatus(initiativeId, status, sessionToken) {
  return gw('PATCH', `/api/initiative/${initiativeId}/status`, { status }, sessionToken);
}

export function deleteInitiative(initiativeId, sessionToken) {
  return gw('DELETE', `/api/initiative/${initiativeId}`, null, sessionToken);
}

// ── Launch / Dispatch ──

/**
 * Stage an initiative — saves to DB with "staged" status and returns
 * server-calculated billing breakdown (ad spend + management fee + total).
 * Call this before launch to populate the confirmation modal.
 */
export function stageInitiative(data, sessionToken) {
  return gw('POST', '/api/initiative/stage', data, sessionToken);
}

/**
 * Get billing breakdown for an already-staged initiative.
 * Re-displays the modal without re-staging.
 */
export function getBilling(initiativeId, sessionToken) {
  return gw('GET', `/api/initiative/${initiativeId}/billing`, null, sessionToken);
}

/**
 * Launch an initiative — dispatches each channel campaign to its provider service.
 * Call after user confirms the billing shown by stageInitiative.
 * Returns per-channel dispatch results.
 */
export function launchInitiative(initiativeId, sessionToken) {
  return gw('POST', `/api/initiative/${initiativeId}/launch`, {}, sessionToken);
}

// ── Channel Campaigns ──

export function listChannelCampaigns(initiativeId, sessionToken) {
  return gw('GET', `/api/initiative/${initiativeId}/channels`, null, sessionToken);
}

export function getChannelCampaign(channelCampaignId, sessionToken) {
  return gw('GET', `/api/initiative/channel/${channelCampaignId}`, null, sessionToken);
}

/**
 * Sync channel campaign status from provider.
 * providerStatus is the raw provider value (e.g. "ENABLED", "DELIVERY_OK").
 * channelType identifies which mapping table to use (e.g. "google_ads", "meta").
 * The Gateway auto-normalizes providerStatus → platform status.
 */
export function syncChannelStatus(channelCampaignId, { channelType, providerStatus, status, externalCampaignId } = {}, sessionToken) {
  return gw('PATCH', `/api/initiative/channel/${channelCampaignId}/sync`, {
    channelType,
    providerStatus,
    status,
    externalCampaignId,
  }, sessionToken);
}

// ── Status Normalization ──

/**
 * Get provider → platform status mappings for diagnostics/admin.
 * Pass channelType to get a specific channel, or omit for all channels.
 */
export function getStatusMappings(sessionToken, channelType) {
  return gw('GET', `/api/initiative/channels/status-mappings${qs({ channelType })}`, null, sessionToken);
}

// ── Budget Allocation ──

export function getAllocation(initiativeId, sessionToken) {
  return gw('GET', `/api/initiative/${initiativeId}/allocation`, null, sessionToken);
}

export function updateAllocation(initiativeId, allocations, reason, sessionToken) {
  return gw('PUT', `/api/initiative/${initiativeId}/allocation`, { allocations, reason }, sessionToken);
}

export function getRecommendation(initiativeId, sessionToken, businessCategory, objective) {
  return gw('GET', `/api/initiative/${initiativeId}/allocation/recommend${qs({ businessCategory, objective })}`, null, sessionToken);
}

export function applyAllocation(initiativeId, data, sessionToken) {
  return gw('POST', `/api/initiative/${initiativeId}/allocation/apply`, data, sessionToken);
}

export function getAllocationHistory(initiativeId, sessionToken, limit) {
  return gw('GET', `/api/initiative/${initiativeId}/allocation/history${qs({ limit })}`, null, sessionToken);
}

// ── Reference Data ──

export function getAvailableChannels(sessionToken) {
  return gw('GET', '/api/initiative/channels/available', null, sessionToken);
}

export function getTemplates(sessionToken, businessCategory, objective) {
  return gw('GET', `/api/initiative/templates${qs({ businessCategory, objective })}`, null, sessionToken);
}

// ── Performance Metrics ──

export function getMetricsSummary(initiativeId, sessionToken, fromDate, toDate) {
  return gw('GET', `/api/initiative/${initiativeId}/metrics${qs({ fromDate, toDate })}`, null, sessionToken);
}

export function getMetricsComparison(initiativeId, sessionToken, lookbackDays) {
  return gw('GET', `/api/initiative/${initiativeId}/metrics/compare${qs({ lookbackDays })}`, null, sessionToken);
}
