<?php

namespace Modules\Workflows\Services\Actions;

use PDO;

class UpdateRecordAction implements ActionInterface {
    private string $tenantId;
    private PDO $pdo;

    public function __construct(string $tenantId) {
        $this->tenantId = $tenantId;
        $this->pdo = \Gestoreasy\Core\Tenant\ConnectionManager::forTenant($tenantId);
    }

    public function execute(array $config, array $context): array {
        $table = $config['table'] ?? '';
        $where = $config['where'] ?? [];
        $data = $config['data'] ?? [];

        if (!$table) {
            throw new \Exception('Table name is required');
        }

        if (empty($where)) {
            throw new \Exception('Where clause is required for update');
        }

        // Resolver variáveis
        $resolvedData = $this->resolveVariables($data, $context);
        $resolvedWhere = $this->resolveVariables($where, $context);

        // Construir query UPDATE
        $setParts = [];
        foreach ($resolvedData as $key => $value) {
            $setParts[] = "{$key} = :set_{$key}";
        }

        $whereParts = [];
        foreach ($resolvedWhere as $key => $value) {
            $whereParts[] = "{$key} = :where_{$key}";
        }

        $sql = "UPDATE {$table} SET " . implode(', ', $setParts) . " WHERE " . implode(' AND ', $whereParts);
        $stmt = $this->pdo->prepare($sql);

        foreach ($resolvedData as $key => $value) {
            $stmt->bindValue(":set_{$key}", $value);
        }

        foreach ($resolvedWhere as $key => $value) {
            $stmt->bindValue(":where_{$key}", $value);
        }

        $stmt->execute();
        $affected = $stmt->rowCount();

        return [
            'updated' => true,
            'table' => $table,
            'affected_rows' => $affected
        ];
    }

    private function resolveVariables(array $data, array $context): array {
        $resolved = [];
        foreach ($data as $key => $value) {
            if (is_string($value)) {
                $resolved[$key] = $this->resolveVariable($value, $context);
            } elseif (is_array($value)) {
                $resolved[$key] = $this->resolveVariables($value, $context);
            } else {
                $resolved[$key] = $value;
            }
        }
        return $resolved;
    }

    private function resolveVariable(string $value, array $context): string {
        return preg_replace_callback('/\{\{([^}]+)\}\}/', function($matches) use ($context) {
            $var = trim($matches[1]);
            $parts = explode('.', $var);
            $result = $context;

            foreach ($parts as $part) {
                if (isset($result[$part])) {
                    $result = $result[$part];
                } else {
                    return $matches[0];
                }
            }

            return is_scalar($result) ? (string)$result : $matches[0];
        }, $value);
    }
}

