/**
 * api/flow-templates.js — Client for the Hub /flow/templates CRUD endpoints.
 *
 * Mirrors services/targo-hub/lib/flow-templates.js. All requests go through
 * the Hub (which handles ERPNext auth server-side).
 *
 * Functions:
 *   listFlowTemplates({ category?, applies_to?, trigger_event?, is_active?, q? })
 *   getFlowTemplate(name)
 *   createFlowTemplate(body)
 *   updateFlowTemplate(name, patch)
 *   deleteFlowTemplate(name)
 *   duplicateFlowTemplate(name, newName?)
 *
 * All functions return the parsed JSON body or throw on network / 4xx / 5xx.
 */

import { HUB_URL } from 'src/config/hub'

/** Fetch helper with error normalization. */
async function hubFetch (path, { method = 'GET', body } = {}) {
  const opts = { method, headers: { 'Content-Type': 'application/json' } }
  if (body) opts.body = JSON.stringify(body)
  const res = await fetch(`${HUB_URL}${path}`, opts)
  const text = await res.text()
  let data
  try { data = text ? JSON.parse(text) : {} }
  catch { throw new Error(`Invalid JSON from ${path}: ${text.slice(0, 200)}`) }
  if (!res.ok) {
    const msg = data.error || `HTTP ${res.status}`
    const err = new Error(msg)
    err.status = res.status
    err.detail = data.detail
    throw err
  }
  return data
}

/**
 * List flow templates with optional filters.
 * @param {Object} filters { category, applies_to, trigger_event, is_active, q, limit }
 * @returns {Promise<Array>} list of templates (without flow_definition body)
 */
export async function listFlowTemplates (filters = {}) {
  const qs = new URLSearchParams()
  for (const [k, v] of Object.entries(filters)) {
    if (v !== undefined && v !== null && v !== '') qs.set(k, String(v))
  }
  const path = `/flow/templates${qs.toString() ? '?' + qs.toString() : ''}`
  const data = await hubFetch(path)
  return data.templates || []
}

/**
 * Fetch a single template with its parsed flow_definition.
 * @param {string} name  FT-00001 etc.
 */
export async function getFlowTemplate (name) {
  const data = await hubFetch(`/flow/templates/${encodeURIComponent(name)}`)
  return data.template
}

/**
 * Create a new (user) template. is_system is forced to 0 by the API.
 * @param {Object} body  { template_name, category, applies_to, flow_definition, ... }
 */
export async function createFlowTemplate (body) {
  const data = await hubFetch('/flow/templates', { method: 'POST', body })
  return data.template
}

/**
 * Patch an existing template. Version is auto-bumped by the API.
 * @param {string} name
 * @param {Object} patch  subset of fields
 */
export async function updateFlowTemplate (name, patch) {
  const data = await hubFetch(`/flow/templates/${encodeURIComponent(name)}`, {
    method: 'PUT', body: patch,
  })
  return data.template
}

/**
 * Delete a template. Blocked server-side if is_system=1.
 * @param {string} name
 */
export async function deleteFlowTemplate (name) {
  await hubFetch(`/flow/templates/${encodeURIComponent(name)}`, { method: 'DELETE' })
}

/**
 * Duplicate a template (e.g. to customize a system template).
 * Creates an inactive copy (is_active=0) for user to review before enabling.
 * @param {string} name
 * @param {string} [newName]  optional override (defaults to "<name> (copie)")
 */
export async function duplicateFlowTemplate (name, newName) {
  const body = newName ? { template_name: newName } : {}
  const data = await hubFetch(`/flow/templates/${encodeURIComponent(name)}/duplicate`, {
    method: 'POST', body,
  })
  return data.template
}
