import { get, post, patch, del } from './client.js';

/**
 * @typedef {import('$lib/types/rules.types.js').RuleDef} RuleDef
 * @typedef {import('$lib/types/rules.types.js').RuleAction} RuleAction
 * @typedef {import('$lib/types/rules.types.js').RuleWithActions} RuleWithActions
 * @typedef {import('$lib/types/rules.types.js').RuleWithLinks} RuleWithLinks
 * @typedef {import('$lib/types/rules.types.js').LinkedTestSummary} LinkedTestSummary
 * @typedef {import('$lib/types/rules.types.js').RulesListResponse} RulesListResponse
 * @typedef {import('$lib/types/rules.types.js').RuleDetailResponse} RuleDetailResponse
 * @typedef {import('$lib/types/rules.types.js').RuleActionsListResponse} RuleActionsListResponse
 * @typedef {import('$lib/types/rules.types.js').ValidateExprResponse} ValidateExprResponse
 * @typedef {import('$lib/types/rules.types.js').TestRuleMapping} TestRuleMapping
 */

/**
 * List rules
 * Filter by TestSiteID to see rules linked to a specific test
 * @param {{ EventCode?: string, Active?: 0|1|number, TestSiteID?: number, search?: string }} [params]
 * @returns {Promise<RulesListResponse>}
 */
export async function fetchRules(params = {}) {
  const query = new URLSearchParams(params).toString();
  return get(query ? `/api/rule?${query}` : '/api/rule');
}

/**
 * Get rule (with actions and linked tests)
 * @param {number} id
 * @returns {Promise<RuleDetailResponse>}
 */
export async function fetchRule(id) {
  return get(`/api/rule/${id}`);
}

/**
 * Create a rule with test mappings and optional initial actions
 * @param {Partial<RuleDef> & { TestSiteIDs: number[], actions?: Array<Partial<RuleAction>> }} payload
 * @returns {Promise<any>}
 */
export async function createRule(payload) {
  return post('/api/rule', payload);
}

/**
 * Update a rule and its test mappings
 * @param {number} id
 * @param {Partial<RuleDef> & { TestSiteIDs?: number[] }} payload
 * @returns {Promise<any>}
 */
export async function updateRule(id, payload) {
  return patch(`/api/rule/${id}`, payload);
}

/**
 * Soft delete a rule
 * @param {number} id
 * @returns {Promise<any>}
 */
export async function deleteRule(id) {
  return del(`/api/rule/${id}`);
}

/**
 * Link a test to a rule (many-to-many mapping)
 * @param {number} ruleId
 * @param {number} testSiteId
 * @returns {Promise<any>}
 */
export async function linkTestToRule(ruleId, testSiteId) {
  return post(`/api/rule/${ruleId}/link`, { TestSiteID: testSiteId });
}

/**
 * Unlink a test from a rule
 * @param {number} ruleId
 * @param {number} testSiteId
 * @returns {Promise<any>}
 */
export async function unlinkTestFromRule(ruleId, testSiteId) {
  return post(`/api/rule/${ruleId}/unlink`, { TestSiteID: testSiteId });
}

/**
 * Validate/evaluate an expression
 * @param {string} expr
 * @param {Record<string, any>} [context]
 * @returns {Promise<ValidateExprResponse>}
 */
export async function validateExpression(expr, context = {}) {
  return post('/api/rule/validate', { expr, context });
}

/**
 * Compile a DSL expression into compiled payload
 * @param {string} expr
 * @returns {Promise<{ compiled: any; conditionExprCompiled: string }>}
 */
export async function compileRuleExpr(expr) {
  return post('/api/rule/compile', { expr });
}

/**
 * List actions for a rule
 * @param {number} id
 * @returns {Promise<RuleActionsListResponse>}
 */
export async function fetchRuleActions(id) {
  return get(`/api/rule/${id}/actions`);
}

/**
 * Create action for a rule
 * @param {number} id
 * @param {Partial<RuleAction>} payload
 * @returns {Promise<any>}
 */
export async function createRuleAction(id, payload) {
  return post(`/api/rule/${id}/actions`, payload);
}

/**
 * Update action
 * @param {number} id
 * @param {number} actionId
 * @param {Partial<RuleAction>} payload
 * @returns {Promise<any>}
 */
export async function updateRuleAction(id, actionId, payload) {
  return patch(`/api/rule/${id}/actions/${actionId}`, payload);
}

/**
 * Soft delete action
 * @param {number} id
 * @param {number} actionId
 * @returns {Promise<any>}
 */
export async function deleteRuleAction(id, actionId) {
  return del(`/api/rule/${id}/actions/${actionId}`);
}
