<?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 SendEmailToAddressesForCustomEvents extends Action
{
    public function getId(): string
    {
        return 'send-email-to-addresses-for-custom-events';
    }

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

    public function getFields(): array
    {
        return [
            TextInput::make('data.emails')
                ->label('Email Addresses')
                ->helperText('Enter email addresses separated by commas (e.g., user1@example.com, user2@example.com). Supports magic attributes.')
                ->required()
                ->placeholder('email1@example.com, email2@example.com'),

            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 [
            'emails',
            '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);

            // Get the email addresses string
            $emailsString = $processedData['emails'] ?? '';

            if (empty($emailsString)) {
                $actionExecution->log('No email addresses provided. Skipping email sending.');

                return;
            }

            // Parse comma-separated emails and clean them
            $emails = array_map('trim', explode(',', $emailsString));
            $emails = array_filter($emails, function ($email) {
                return filter_var($email, FILTER_VALIDATE_EMAIL);
            });

            if (empty($emails)) {
                $actionExecution->log('No valid email addresses found after parsing.');

                return;
            }

            $actionExecution->log("Found ".count($emails)." valid email address(es) to send to.");

            $successCount = 0;
            $failureCount = 0;

            // Send email to each address
            foreach ($emails as $email) {
                try {
                    Mail::raw($processedData['message'], function ($message) use ($processedData, $email) {
                        $message
                            ->to($email)
                            ->subject($processedData['subject']);
                    });

                    $successCount++;
                    $actionExecution->log("Email sent to: {$email}");
                } catch (\Exception $e) {
                    $failureCount++;
                    $actionExecution->log("Failed to send email to {$email}: ".$e->getMessage());
                }
            }

            $actionExecution->log("Email sending completed. Success: {$successCount}, Failed: {$failureCount}");
        } catch (\Exception $e) {
            $actionExecution->log('Failed to send emails: '.$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 true;
    }

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

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