<?php

namespace App\Http\Livewire;

use Livewire\Component;

class ReactionButton extends Component
{
    public $targetModel = null;
    public $modelClass = null;
    public $modelId = null;
    public $count = 0;
    public $activeProfile;
    public $reactedByReactor = false;
    public $typeName;
    public $showCounter = true;
    public $isEnabled = false;
    public $canReact = false;
    public $requiresInteraction = false;
    public $hasInteraction = false;
    public $interactionMethod = null;
    public $disabledReason = null;
    public $size = 'w-10 h-10'; // Default size, can be overridden
    public $showConfirmModal = false;
    public $inverseColors = false; // Use light/background colors instead of reaction colors
    public ?string $redirectUrl = null; // When set and user is not logged in, clicking redirects here

    public function mount($typeName = 'like', $showCounter = true, $reactionCounter = null, $modelInstance = null, $modelClass = null, $modelId = null, $inverseColors = false, $redirectUrl = null)
    {
        $this->typeName = $typeName;
        $this->count = $reactionCounter ?? 0;
        $this->showCounter = $showCounter;
        $this->inverseColors = $inverseColors;
        $this->redirectUrl = $redirectUrl;
        $this->activeProfile = getActiveProfile();

        // Handle different ways of passing model data
        if ($modelInstance !== null) {
            // Traditional way: full model instance passed
            $this->targetModel = $modelInstance;

            // For reserve reactions on Posts, ensure meeting is loaded
            if ($typeName === 'reserve' && $modelInstance instanceof \App\Models\Post) {
                if (!$modelInstance->relationLoaded('meeting')) {
                    $this->targetModel->load('meeting');
                }
            }
        } elseif ($modelClass !== null && $modelId !== null) {
            // New way: class and ID passed separately
            $this->modelClass = $modelClass;
            $this->modelId = $modelId;
            try {
                if ($typeName === 'reserve' && $modelClass === 'App\Models\Post') {
                    $this->targetModel = $modelClass::with('meeting')->find($modelId);
                } else {
                    $this->targetModel = $modelClass::find($modelId);
                }
            } catch (\Exception $e) {
                \Log::error('ReactionButton: Failed to load model: ' . $e->getMessage());
                $this->targetModel = null;
            }
        } else {
            $this->targetModel = null;
        }

        // If model not found or invalid, set component as disabled and return early
        if (!$this->targetModel || !is_object($this->targetModel)) {
            $this->isEnabled = false;
            $this->canReact = false;
            $this->disabledReason = 'model_not_found';
            return;
        }

        $this->initializeReactionSettings();
        $this->checkReactionPermissions();
        $this->checkIfReacted();
    }

    private function initializeReactionSettings()
    {
        // Check if this reaction type is enabled in config
        $this->isEnabled = timebank_config("reactions.{$this->typeName}.enabled", false);

        // Check if interaction is required for this reaction type
        $this->requiresInteraction = timebank_config("reactions.{$this->typeName}.only_with_interaction", false);

        // Get the interaction method to use for checking
        $this->interactionMethod = timebank_config("reactions.{$this->typeName}.interaction", 'hasTransactionsWith');
    }

    private function checkReactionPermissions()
    {
        // If reaction type is not enabled, early return
        if (!$this->isEnabled) {
            $this->canReact = false;
            $this->disabledReason = 'reaction_disabled';
            return;
        }

        // Guests cannot react
        if (!$this->activeProfile) {
            $this->canReact = false;
            $this->disabledReason = 'not_logged_in';
            return;
        }

        // Admins cannot react
        if ($this->activeProfile instanceof \App\Models\Admin) {
            $this->canReact = false;
            $this->disabledReason = 'admin_cannot_react';
            return;
        }

        // Profile must be registered as love reacter
        if (
            !method_exists($this->activeProfile, 'isRegisteredAsLoveReacter') ||
            !$this->activeProfile->isRegisteredAsLoveReacter()
        ) {
            $this->canReact = false;
            $this->disabledReason = 'not_registered_reacter';
            return;
        }

        // Cannot react to your own profile/model
        if ($this->isOwnProfile()) {
            $this->canReact = false;
            $this->disabledReason = 'cannot_react_own_profile';
            return;
        }

        // Check interaction requirement
        if ($this->requiresInteraction) {
            // Use the configured interaction method
            if (method_exists($this->activeProfile, $this->interactionMethod)) {
                $this->hasInteraction = $this->activeProfile->{$this->interactionMethod}($this->targetModel);
                if (!$this->hasInteraction) {
                    $this->canReact = false;
                    $this->disabledReason = 'no_interaction';
                    return;
                }
            } else {
                // Fallback if method doesn't exist - treat as no interaction
                $this->canReact = false;
                $this->disabledReason = 'no_interaction';
                return;
            }
        }

        $this->canReact = true;
        $this->disabledReason = null;
    }

    private function isOwnProfile()
    {
        // Safety check - ensure we have a valid model object
        if (!$this->targetModel || !is_object($this->targetModel) || !isset($this->targetModel->id)) {
            return false;
        }

        try {
            // Get the model class name safely
            $modelClass = get_class($this->targetModel);
            $modelId = $this->targetModel->id;

            return session('activeProfileType') === $modelClass &&
                session('activeProfileId') === $modelId;
        } catch (\Exception $e) {
            \Log::error('ReactionButton isOwnProfile error: ' . $e->getMessage());
            return false;
        }
    }

    private function checkIfReacted()
    {
        if (!$this->canReact || !$this->activeProfile->isRegisteredAsLoveReacter()) {
            $this->reactedByReactor = false;
            return;
        }

        $this->reactedByReactor = $this->activeProfile
            ->viaLoveReacter()
            ->hasReactedTo($this->targetModel, $this->typeName);
    }

    public function react()
    {
        // For reserve reaction type, show confirmation modal first
        if ($this->typeName === 'reserve') {
            $this->showConfirmModal = true;
            return;
        }

        $this->confirmReaction();
    }

    public function confirmReaction()
    {
        // Close modal if open
        $this->showConfirmModal = false;

        // Security checks
        if (!$this->canReactSecurityCheck()) {
            return;
        }

        // Don't react if already reacted
        if ($this->reactedByReactor) {
            return;
        }

        try {
            $this->activeProfile->viaLoveReacter()->reactTo($this->targetModel, $this->typeName);

            // Update count and reacted state
            $this->count++;
            $this->reactedByReactor = true;

            // Optional: dispatch browser event for success feedback
            $this->dispatch('reaction-added', [
                'type' => $this->typeName,
                'model' => get_class($this->targetModel),
                'modelId' => $this->targetModel->id
            ]);
        } catch (\Exception $e) {
            // Log error and show user-friendly message
            \Log::error('Failed to add reaction: ' . $e->getMessage());
            $this->dispatch('reaction-error', ['message' => 'Failed to add reaction. Please try again.']);
        }
    }

    public function unReact()
    {
        // Security checks
        if (!$this->canReactSecurityCheck()) {
            return;
        }

        // Don't unreact if not reacted
        if (!$this->reactedByReactor) {
            return;
        }

        try {
            $this->activeProfile->viaLoveReacter()->unReactTo($this->targetModel, $this->typeName);
            $this->count = max(0, $this->count - 1); // Prevent negative counts
            $this->reactedByReactor = false;

            // Optional: dispatch browser event for success feedback
            $this->dispatch('reaction-removed', [
                'type' => $this->typeName,
                'model' => get_class($this->targetModel),
                'modelId' => $this->targetModel->id
            ]);
        } catch (\Exception $e) {
            // Log error and show user-friendly message
            \Log::error('Failed to remove reaction: ' . $e->getMessage());
            $this->dispatch('reaction-error', ['message' => 'Failed to remove reaction. Please try again.']);
        }
    }

    private function canReactSecurityCheck()
    {
        // Re-run all security checks on each action for security
        if (!$this->targetModel || (method_exists($this->targetModel, 'isRemoved') && $this->targetModel->isRemoved())) {
            return false;
        }

        if (!$this->isEnabled) {
            return false;
        }

        if ($this->activeProfile instanceof \App\Models\Admin) {
            return false;
        }

        if (
            !method_exists($this->activeProfile, 'isRegisteredAsLoveReacter') ||
            !$this->activeProfile->isRegisteredAsLoveReacter()
        ) {
            return false;
        }

        if ($this->isOwnProfile()) {
            return false;
        }

        if (
            $this->requiresInteraction &&
            method_exists($this->activeProfile, $this->interactionMethod) &&
            !$this->activeProfile->{$this->interactionMethod}($this->targetModel)
        ) {
            return false;
        }

        return true;
    }

    private function getDisabledReasonText()
    {
        // Only show text for specific disabled reasons that should be visible to users
        $visibleReasons = [
            'cannot_react_own_profile',
            'no_interaction'
        ];

        if (!in_array($this->disabledReason, $visibleReasons)) {
            return null; // Don't show text for other reasons
        }

        // Get reaction-specific disabled reason text
        $reason = timebank_config("reactions.{$this->typeName}.disabled_reasons.{$this->disabledReason}");

        // Fallback to default messages if reaction-specific ones don't exist
        if (!$reason) {
            $fallbackReasons = [
                'cannot_react_own_profile' => __('You cannot react to your own content.'),
                'no_interaction' => __('You need an interaction to react.'),
            ];
            $reason = $fallbackReasons[$this->disabledReason] ?? '';
        }

        return $reason;
    }

    private function shouldShowComponent()
    {
        // Hide component if model is not loaded
        if (!$this->targetModel) {
            return false;
        }

        // Hide component for these reasons instead of showing disabled state
        $hiddenReasons = [
            'reaction_disabled',
            'admin_cannot_react',
            'not_registered_reacter',
            'model_not_found'
        ];

        return !in_array($this->disabledReason, $hiddenReasons);
    }

    private function getIconSvg($typeName)
    {
        // Get icon file from config
        $iconFile = timebank_config("reactions.{$typeName}.icon_file");

        if (!$iconFile) {
            return '';
        }

        $svgPath = public_path('storage/app-images/' . $iconFile);

        if (!file_exists($svgPath)) {
            return '';
        }

        $svgContent = file_get_contents($svgPath);

        // Extract only the path content from the SVG (remove outer svg tag)
        if (preg_match('/<path[^>]*>.*?<\/path>|<path[^>]*\/>/s', $svgContent, $matches)) {
            return $matches[0];
        }

        // If no path found, try to extract circle or other shapes
        if (preg_match('/<(?:circle|rect|polygon|line)[^>]*>.*?<\/(?:circle|rect|polygon|line)>|<(?:circle|rect|polygon|line)[^>]*\/>/s', $svgContent, $matches)) {
            return $matches[0];
        }

        return $svgContent;
    }

    public function render()
    {
        $iconSvg = $this->getIconSvg($this->typeName);
        $shouldShow = $this->shouldShowComponent();
        $disabledReasonText = $this->getDisabledReasonText();

        return view('livewire.reaction-button', [
            'iconSvg' => $iconSvg,
            'disabledReasonText' => $disabledReasonText,
            'shouldShow' => $shouldShow,
            'inverseColors' => $this->inverseColors,
            'redirectUrl' => $this->redirectUrl,
        ])->layout('layouts.app');
    }
}
