<?php

namespace App\Filament\Workflows\Actions;

use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Mail;
use Monzer\FilamentWorkflows\Contracts\Action;
use Monzer\FilamentWorkflows\Models\WorkflowActionExecution;

class SendEmailForCustomEvents extends Action
{
    public function getId(): string
    {
        return 'send-email-for-custom-events';
    }

    public function getName(): string
    {
        return 'Send Email (Custom Events)';
    }

    public function getFields(): array
    {
        return [
            TextInput::make('data.email')
                ->helperText('Supports magic attributes')
                ->required(),

            TextInput::make('data.subject')
                ->helperText('Supports magic attributes')
                ->required(),

            Textarea::make('data.message')
                ->helperText('Supports magic attributes')
                ->required()
                ->rows(5),
        ];
    }

    public function getMagicAttributeFields(): array
    {
        return [
            'email',
            'subject',
            'message',
        ];
    }

    public function execute(array $data, WorkflowActionExecution $actionExecution, ?Model $model, array $custom_event_data, array &$shared_data): void
    {
        try {
            // Log the custom event data for debugging
            $actionExecution->log('Processing custom event data: '.json_encode($custom_event_data));

            // Process magic attributes using custom event data
            $processedData = $this->processMagicAttributesForCustomEvents($data, $custom_event_data);

            // Log processed data
            $actionExecution->log("Processed email data - To: {$processedData['email']}, Subject: {$processedData['subject']}");

            Mail::raw($processedData['message'], function ($message) use ($processedData) {
                $message
                    ->to($processedData['email'])
                    ->subject($processedData['subject']);
            });

            $actionExecution->log("Email successfully sent to: {$processedData['email']} regarding: {$processedData['subject']}");
        } catch (\Exception $e) {
            $actionExecution->log('Failed to send email: '.$e->getMessage());
            throw $e;
        }
    }

    /**
     * Process magic attributes using custom event data instead of model
     */
    public function processMagicAttributesForCustomEvents(array $data, array $custom_event_data): array
    {
        $magicAttributeFields = $this->getMagicAttributeFields();

        foreach ($data as $key => $value) {
            if (in_array($key, $magicAttributeFields)) {
                if (is_string($value)) {
                    $data[$key] = $this->processMagicAttributeForCustomEvents($custom_event_data, $value);
                }
                if (is_array($value)) {
                    $arr_data = [];
                    foreach ($value as $k => $subValue) {
                        if (is_string($subValue)) {
                            $arr_data[$k] = $this->processMagicAttributeForCustomEvents($custom_event_data, $subValue);
                        }
                    }
                    $data[$key] = $arr_data;
                }
            }
        }

        return $data;
    }

    /**
     * Process magic attribute using custom event data
     */
    public function processMagicAttributeForCustomEvents(array $custom_event_data, string $data): string
    {
        $segments = explode(' ', $data);
        foreach ($segments as $segment) {
            // Look for patterns like @key@ or @nested.key@
            preg_match('~@(.*?)@~', $segment, $output);
            if (array_key_exists(1, $output)) {
                $key = $output[1];
                $fullMatch = $output[0]; // @key@

                if (str($key)->contains('.')) {
                    // Handle nested keys like @association.email@
                    $keyParts = explode('.', $key);
                    $value = $custom_event_data;

                    foreach ($keyParts as $keyPart) {
                        if (is_array($value) && array_key_exists($keyPart, $value)) {
                            $value = $value[$keyPart];
                        } elseif (is_object($value) && property_exists($value, $keyPart)) {
                            $value = $value->{$keyPart};
                        } else {
                            $value = null;
                            break;
                        }
                    }

                    if ($value !== null) {
                        $data = str($data)->replace($fullMatch, $value)->value();
                    }
                } else {
                    // Handle simple keys like @email@
                    if (array_key_exists($key, $custom_event_data)) {
                        $value = $custom_event_data[$key];
                        if (is_scalar($value) || (is_object($value) && method_exists($value, '__toString'))) {
                            $data = str($data)->replace($fullMatch, $value)->value();
                        }
                    }
                }
            }
        }

        return $data;
    }

    public function canBeUsedWithScheduledWorkflows(): bool
    {
        return false;
    }

    public function canBeUsedWithRecordEventWorkflows(): bool
    {
        return false;
    }

    public function canBeUsedWithCustomEventWorkflows(): bool
    {
        return true;
    }

    public function requireInstalledPackages(): array
    {
        return [];
    }
}
