/**
 * Token Live Data Orchestrator (Phase 2)
 * Fetches real content for each token category using existing REST endpoints.
 * Returns a normalized map:
 * { track:{ title,artist,album,artwork }, weather:{ temperature,condition,location }, ... }
 *
 * Architecture:
 * - Track metadata: fetches directly from global metadata API via /metadata/proxy
 *   This is "now playing" data - global to all track_info blocks regardless of which one you're editing.
 * - Weather & Location/Time: user approved ADMIN-ONLY styling placeholders if live-data returns descriptive boilerplate.
 * - Shoutout / Sponsor / Promo: use existing unified endpoints returning first active item.
 * - Custom API (future): will use separate token namespace ({{custom.fieldName}}) with block-specific endpoints.
 * - Artwork fallback: left blank here; canvas editor will supply branding fallback if empty.
 */

import { isValidToken } from './token-registry.js';

const API_BASE = window.ccveApiBase || '/wp-json/castconductor/v5';

async function _json(url) {
  try {
    const headers = { 'Content-Type': 'application/json' };
    try { if (window.castconductorCanvasAjax?.nonce) headers['X-WP-Nonce'] = window.castconductorCanvasAjax.nonce; } catch(_) {}
    const r = await fetch(url, { credentials: 'same-origin', headers });
    if (!r.ok) throw new Error(r.status + ' ' + r.statusText);
    return await r.json();
  } catch (e) {
    console.warn('[CCVE][tokens] fetch failed', url, e.message);
    return null;
  }
}

async function fetchTrack(context) {
  // Fetch track data directly from global metadata API
  // Track tokens are global "now playing" data, not block-specific
  const metadataUrl = window.castconductorCanvasAjax?.metadata_url;
  
  if (!metadataUrl) {
    console.warn('[CCVE][tokens] No metadata URL configured');
    return {};
  }
  
  try {
    const resp = await _json(`${API_BASE}/metadata/proxy?url=${encodeURIComponent(metadataUrl)}`);
    const song = resp?.now_playing?.song || resp?.data?.now_playing?.song || {};
    
    return {
      title: song.title || song.text?.split(' - ')[1] || '',
      artist: song.artist || song.text?.split(' - ')[0] || '',
      album: song.album || '',
      artwork: song.art || song.artwork_url || ''
    };
  } catch (e) {
    console.warn('[CCVE][tokens] Failed to fetch track from metadata proxy', e.message);
    return {};
  }
}

async function fetchWeather() {
  // Rely on content block for now (first weather block)
  const list = await _json(`${API_BASE}/content-blocks?type=weather&per_page=1`);
  const id = Array.isArray(list) && list[0]?.id;
  if (!id) return {};
  const live = await _json(`${API_BASE}/content-blocks/${id}/live-data`);
  const data = live?.data?.live_data || {};
  // Admin styling placeholder exception (approved by user) if values look like boilerplate
  const temp = data.temperature && !/Configure|Required/i.test(data.temperature) ? data.temperature : '72';
  const cond = data.condition && !/Setup|Required/i.test(data.condition) ? data.condition : 'Sunny';
  const loc = data.location && !/Setup|Required/i.test(data.location) ? data.location : 'Tijuana';
  const unit = data.unit || '°F';
  return { temperature: temp, condition: cond, location: loc, unit };
}

async function fetchLocationTime() {
  const list = await _json(`${API_BASE}/content-blocks?type=location_time&per_page=1`);
  const id = Array.isArray(list) && list[0]?.id;
  if (!id) return {};
  const live = await _json(`${API_BASE}/content-blocks/${id}/live-data`);
  const data = live?.data?.live_data || {};
  // Admin placeholder exceptions (time/date keep server values if present)
  return {
    time: data.time || '3:14 PM',
    date: data.date || '',
    city: data.city && !/Live Viewer City/i.test(data.city) ? data.city : 'Tijuana',
    state: data.state && !/Real Geolocation/i.test(data.state) ? data.state : 'BC'
  };
}

async function fetchUnified(type) {
  // Maps: shoutout, sponsor, promo → existing endpoints
  const endpointMap = {
    shoutout: 'content/shoutouts/active',
    sponsor: 'content/sponsors/active',
    promo: 'content/promos/active'
  };
  const ep = endpointMap[type];
  if (!ep) return {};
  const resp = await _json(`${API_BASE}/${ep}`);
  const item = resp?.data?.[0];
  if (!item) return {};
  switch (type) {
    case 'shoutout':
      return { name: item.name || '', location: item.location || '', message: item.message || '' };
    case 'sponsor':
      return { title: item.title || '', content: item.content || '', artwork: item.featured_media_url || '' };
    case 'promo':
      return { title: item.title || '', content: item.content || '', artwork: item.featured_media_url || '' };
    default: return {};
  }
}

async function fetchCustom() {
  const list = await _json(`${API_BASE}/content-blocks?type=custom&per_page=1`);
  const id = Array.isArray(list) && list[0]?.id;
  if (!id) return {};
  const live = await _json(`${API_BASE}/content-blocks/${id}/live-data`);
  const data = live?.data?.live_data || {};
  return { text: data.content || '' };
}

/**
 * Fetch custom_api category data from the first custom_api content block
 * Maps API response fields to standard token names: primary, secondary, number, date, image, link
 */
async function fetchCustomApi(context) {
  // Prefer the current block if it's a custom_api type
  let id = null;
  try {
    if (context?.currentBlockType === 'custom_api' && context?.currentBlockId) {
      id = context.currentBlockId;
    }
  } catch(_) {}
  
  // Otherwise find first custom_api block
  if (!id) {
    const list = await _json(`${API_BASE}/content-blocks?type=custom_api&per_page=1`);
    id = Array.isArray(list) && list[0]?.id;
  }
  
  if (!id) {
    console.debug('[CCVE][tokens] No custom_api content block found');
    return {};
  }
  
  const live = await _json(`${API_BASE}/content-blocks/${id}/live-data`);
  const data = live?.data?.live_data || {};
  
  // Map API fields to standard token names
  // The backend returns: primary_text, secondary_text, number_display, date_value, image_url, link_url
  return {
    primary: data.primary_text || '',
    secondary: data.secondary_text || '',
    number: data.number_display || data.number_value || '',
    date: data.date_value || '',
    image: data.image_url || '',
    link: data.link_url || ''
  };
}

export async function fetchTokenCategories(categories, context = {}) {
  const unique = Array.from(new Set(categories.filter(Boolean)));
  const out = {};
  await Promise.all(unique.map(async (cat) => {
    try {
      switch (cat) {
        case 'track': out.track = await fetchTrack(context); break;
        case 'weather': out.weather = await fetchWeather(); break;
        case 'location': out.location = await fetchLocationTime(); break;
        case 'shoutout': out.shoutout = await fetchUnified('shoutout'); break;
        case 'sponsor': out.sponsor = await fetchUnified('sponsor'); break;
        case 'promo': out.promo = await fetchUnified('promo'); break;
        case 'custom': out.custom = await fetchCustom(); break;
        case 'custom_api': out.custom_api = await fetchCustomApi(context); break;
        default: break; // ignore unknown
      }
    } catch (e) {
      console.warn('[CCVE][tokens] category fetch error', cat, e);
    }
  }));
  return out;
}

export function deriveCategoriesFromTokens(tokenPaths) {
  const cats = new Set();
  for (const p of tokenPaths) {
    if (isValidToken(p)) cats.add(p.split('.')[0]);
  }
  return Array.from(cats);
}

// Dev helper: window.ccveFetchTokenData(['track','weather']).then(console.log)
try { window.ccveFetchTokenData = fetchTokenCategories; } catch(_) {}

export default { fetchTokenCategories, deriveCategoriesFromTokens };
