<?php

namespace EasyLinkAutomations\Models;

if (!defined('ABSPATH')) {
    exit;
}

use EasyLinkAutomations\Config;

/**
 * Model for automation_actions table.
 *
 * phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name from Config::withDBPrefix(), escaped via escapeIdentifier().
 */
final class AutomationAction
{
    private const CACHE_GROUP = 'easylink_automations_automation_actions';

    /**
     * Get table name with prefix.
     */
    private static function table(): string
    {
        return Config::withDBPrefix('automation_actions');
    }

    /**
     * Escape a SQL identifier (table name) for use in queries.
     */
    private static function escapeIdentifier(string $identifier): string
    {
        return '`' . str_replace('`', '``', $identifier) . '`';
    }

    /**
     * Find an action by ID.
     */
    public static function find(int $id): ?array
    {
        $cache_key = 'id_' . $id;
        $cached    = wp_cache_get($cache_key, self::CACHE_GROUP);
        if (false !== $cached) {
            return $cached;
        }

        global $wpdb;
        $table  = self::escapeIdentifier(self::table());
        $result = $wpdb->get_row(
            $wpdb->prepare(
                "SELECT * FROM {$table} WHERE id = %d",
                $id
            ),
            ARRAY_A
        );
        $row = $result ?: null;
        wp_cache_set($cache_key, $row, self::CACHE_GROUP, 300);

        return $row;
    }

    /**
     * Find all actions for an automation.
     *
     * @return array<array>
     */
    public static function findByAutomation(int $automationId): array
    {
        $cache_key = 'automation_' . $automationId;
        $cached    = wp_cache_get($cache_key, self::CACHE_GROUP);
        if (false !== $cached) {
            return $cached;
        }

        global $wpdb;
        $table = self::escapeIdentifier(self::table());
        $rows  = $wpdb->get_results(
            $wpdb->prepare(
                "SELECT * FROM {$table} WHERE automation_id = %d ORDER BY action_order ASC",
                $automationId
            ),
            ARRAY_A
        ) ?: [];
        wp_cache_set($cache_key, $rows, self::CACHE_GROUP, 300);

        return $rows;
    }

    /**
     * Create a new automation action.
     *
     * @return int|false Insert ID or false on failure
     */
    public static function create(array $data): int|false
    {
        global $wpdb;

        $result = $wpdb->insert(self::table(), $data);
        if ($result) {
            $automation_id = (int) ($data['automation_id'] ?? 0);
            if ($automation_id) {
                wp_cache_delete('automation_' . $automation_id, self::CACHE_GROUP);
            }
            return $wpdb->insert_id;
        }
        return false;
    }

    /**
     * Update an action.
     */
    public static function update(int $id, array $data): bool
    {
        global $wpdb;

        $ok = $wpdb->update(self::table(), $data, ['id' => $id]) !== false;
        if ($ok) {
            wp_cache_delete('id_' . $id, self::CACHE_GROUP);
            $automation_id = (int) ($data['automation_id'] ?? 0);
            if ($automation_id) {
                wp_cache_delete('automation_' . $automation_id, self::CACHE_GROUP);
            }
        }
        return $ok;
    }

    /**
     * Delete an action.
     */
    public static function delete(int $id): bool
    {
        global $wpdb;

        $ok = $wpdb->delete(self::table(), ['id' => $id]) !== false;
        if ($ok) {
            wp_cache_delete('id_' . $id, self::CACHE_GROUP);
        }
        return $ok;
    }

    /**
     * Delete all actions for an automation.
     */
    public static function deleteByAutomation(int $automationId): bool
    {
        global $wpdb;

        $ok = $wpdb->delete(self::table(), ['automation_id' => $automationId]) !== false;
        if ($ok) {
            wp_cache_delete('automation_' . $automationId, self::CACHE_GROUP);
        }
        return $ok;
    }
}
