#ifndef DIDACTYL_TRIGGER_MANAGER_H
#define DIDACTYL_TRIGGER_MANAGER_H

#include <pthread.h>
#include <time.h>

#include "config.h"
#include "cjson/cJSON.h"
#include "nostr_handler.h"
#include "../nostr_core_lib/nostr_core/nostr_core.h"

#define TRIGGER_DEFAULT_MAX_ACTIVE 16
#define TRIGGER_SKILL_D_TAG_MAX 65
#define TRIGGER_SKILL_CONTENT_MAX 4096
#define TRIGGER_FILTER_JSON_MAX 2048

typedef enum {
    TRIGGER_ACTION_LLM = 0,
    TRIGGER_ACTION_TEMPLATE = 1
} trigger_action_type_t;

typedef enum {
    TRIGGER_TYPE_NOSTR_SUBSCRIPTION = 0,
    TRIGGER_TYPE_WEBHOOK = 1,
    TRIGGER_TYPE_CRON = 2,
    TRIGGER_TYPE_CHAIN = 3,
    TRIGGER_TYPE_DM = 4
} trigger_type_t;

typedef struct {
    char skill_d_tag[TRIGGER_SKILL_D_TAG_MAX];
    char skill_content[TRIGGER_SKILL_CONTENT_MAX];
    char filter_json[TRIGGER_FILTER_JSON_MAX];
    trigger_action_type_t action_type;
    int enabled;
    trigger_type_t trigger_type;
    time_t last_fired;
    time_t last_seen_created_at;
    time_t last_cron_fire;
    char cron_expr[64];
    char llm_spec[256];
    char tools_policy[256];
    int has_max_tokens;
    int max_tokens;
    int has_temperature;
    double temperature;
    int has_seed;
    int seed;
    nostr_pool_subscription_t* subscription;
    void* subscription_ctx;
} active_trigger_t;

typedef struct trigger_manager {
    active_trigger_t* triggers;
    int count;
    int capacity;
    didactyl_config_t* cfg;
    pthread_mutex_t mutex;
    time_t last_poll_at;
} trigger_manager_t;

int trigger_manager_init(trigger_manager_t* mgr, didactyl_config_t* cfg);
int trigger_manager_load_from_skills(trigger_manager_t* mgr);
int trigger_manager_load_from_startup_events(trigger_manager_t* mgr);
trigger_type_t trigger_type_from_string(const char* s);
const char* trigger_type_to_string(trigger_type_t t);

int trigger_manager_add(trigger_manager_t* mgr,
                        const char* skill_d_tag,
                        const char* content,
                        const char* filter_json,
                        trigger_action_type_t action_type,
                        const char* trigger_type_str,
                        int enabled,
                        const char* llm_spec,
                        const char* tools_policy,
                        int has_max_tokens,
                        int max_tokens,
                        int has_temperature,
                        double temperature,
                        int has_seed,
                        int seed);
int trigger_manager_remove(trigger_manager_t* mgr, const char* skill_d_tag);
int trigger_manager_find(trigger_manager_t* mgr, const char* skill_d_tag, active_trigger_t* out);
int trigger_manager_update(trigger_manager_t* mgr,
                           const char* skill_d_tag,
                           const char* content,
                           const char* filter_json,
                           trigger_action_type_t action_type,
                           const char* trigger_type_str,
                           int enabled,
                           const char* llm_spec,
                           const char* tools_policy,
                           int has_max_tokens,
                           int max_tokens,
                           int has_temperature,
                           double temperature,
                           int has_seed,
                           int seed);
int trigger_manager_fire(trigger_manager_t* mgr,
                         const char* skill_d_tag,
                         cJSON* event,
                         const char* source_label);
int trigger_manager_fire_chains(trigger_manager_t* mgr,
                                const char* source_skill_d_tag,
                                cJSON* source_event,
                                const char* source_label);
int trigger_manager_get_dm_skills(trigger_manager_t* mgr,
                                  const char* sender_pubkey_hex,
                                  didactyl_sender_tier_t tier,
                                  char** out_d_tags,
                                  int max_d_tags);
int trigger_manager_active_count(trigger_manager_t* mgr);
int trigger_manager_poll(trigger_manager_t* mgr);
char* trigger_manager_status_json(trigger_manager_t* mgr);
void trigger_manager_cleanup(trigger_manager_t* mgr);

#endif