<?php

namespace App\Livewire\User;

use App\Jobs\SendPushNotificationJob;
use App\Models\App;
use App\Models\AppNotification;
use Illuminate\Support\Facades\Storage;
use Livewire\Attributes\On;
use Livewire\Component;
use Livewire\WithFileUploads;

class SendNotificationModal extends Component
{
    use WithFileUploads;

    public $showModal = false;

    public $notificationId = null;

    public $isEditing = false;

    public $existingImageUrl = null;

    public $app_id = '';

    public $title = '';

    public $body = '';

    public $image_file;

    public $notification_style = 'text';

    public $schedule_type = 'now';

    public $scheduled_at = '';

    public $userApps = [];

    protected function rules()
    {
        // When editing with existing image, don't require new upload
        $imageRule = 'nullable';
        if ($this->notification_style === 'image') {
            if ($this->isEditing && $this->existingImageUrl && ! $this->image_file) {
                $imageRule = 'nullable';
            } elseif (! $this->isEditing || ! $this->existingImageUrl) {
                $imageRule = 'required|image|mimes:jpeg,png,jpg|max:1024';
            }
        }

        return [
            'app_id' => 'required|exists:apps,id',
            'title' => 'required|string|max:255',
            'body' => 'required|string|max:1000',
            'image_file' => $imageRule,
            'notification_style' => 'required|in:text,image',
            'schedule_type' => 'required|in:now,later',
            'scheduled_at' => 'required_if:schedule_type,later|nullable|date|after:now',
        ];
    }

    protected $messages = [
        'app_id.required' => 'Please select an app.',
        'title.required' => 'Notification title is required.',
        'body.required' => 'Notification body is required.',
        'image_file.required' => 'Please upload an image.',
        'image_file.image' => 'The file must be an image.',
        'image_file.max' => 'Image size must not exceed 1MB.',
        'scheduled_at.after' => 'Scheduled time must be in the future.',
    ];

    public function mount()
    {
        $this->loadUserApps();
    }

    public function loadUserApps()
    {
        $this->userApps = App::where('user_id', auth()->id())
            ->whereHas('pushNotificationConfig', function ($query) {
                $query->where('enabled', true);
            })
            ->get();
    }

    #[On('open-send-notification-modal')]
    public function open()
    {
        $this->resetForm();
        $this->loadUserApps();
        $this->showModal = true;
    }

    #[On('edit-notification')]
    public function edit(int $id): void
    {
        $notification = AppNotification::where('id', $id)
            ->where('user_id', auth()->id())
            ->whereIn('status', ['pending', 'scheduled'])
            ->first();

        if (! $notification) {
            $this->dispatch('show-toast',
                type: 'error',
                message: __('user.notification_edit_failed')
            );

            return;
        }

        $this->resetForm();
        $this->loadUserApps();

        $this->notificationId = $notification->id;
        $this->isEditing = true;
        $this->app_id = $notification->app_id;
        $this->title = $notification->title;
        $this->body = $notification->body;
        $this->notification_style = $notification->notification_style;
        $this->existingImageUrl = $notification->image_url;
        $this->schedule_type = $notification->scheduled_at ? 'later' : 'now';
        $this->scheduled_at = $notification->scheduled_at?->format('Y-m-d\TH:i') ?? '';

        $this->showModal = true;
    }

    protected function resetForm(): void
    {
        $this->reset([
            'notificationId',
            'isEditing',
            'existingImageUrl',
            'app_id',
            'title',
            'body',
            'image_file',
            'notification_style',
            'schedule_type',
            'scheduled_at',
        ]);
    }

    public function updatedNotificationStyle($value)
    {
        if ($value === 'text') {
            $this->image_file = null;
            $this->existingImageUrl = null;
        }
    }

    public function send()
    {
        $this->validate();

        // Verify app belongs to user and has FCM enabled
        $app = App::where('id', $this->app_id)
            ->where('user_id', auth()->id())
            ->whereHas('pushNotificationConfig', function ($query) {
                $query->where('enabled', true);
            })
            ->first();

        if (! $app) {
            $this->addError('app_id', __('common.notification_invalid_app'));

            return;
        }

        // Handle image upload
        $imageUrl = $this->existingImageUrl;
        if ($this->notification_style === 'image' && $this->image_file) {
            $imagePath = $this->image_file->store('notifications/'.$app->id, 'public');
            $imageUrl = url(Storage::url($imagePath));
        } elseif ($this->notification_style === 'text') {
            $imageUrl = null;
        }

        // Determine status based on schedule
        $status = $this->schedule_type === 'later' ? 'scheduled' : 'pending';

        if ($this->isEditing && $this->notificationId) {
            // Update existing notification
            $notification = AppNotification::where('id', $this->notificationId)
                ->where('user_id', auth()->id())
                ->first();

            if (! $notification) {
                $this->addError('app_id', __('user.notification_edit_failed'));

                return;
            }

            $notification->update([
                'app_id' => $this->app_id,
                'title' => $this->title,
                'body' => $this->body,
                'image_url' => $imageUrl,
                'notification_style' => $this->notification_style,
                'status' => $status,
                'scheduled_at' => $this->schedule_type === 'later' ? $this->scheduled_at : null,
            ]);

            // If sending now, dispatch the job
            if ($this->schedule_type === 'now') {
                SendPushNotificationJob::dispatch($notification);
            }

            $this->showModal = false;
            $this->dispatch('notificationUpdated');

            $this->dispatch('show-toast',
                type: 'success',
                message: $this->schedule_type === 'later'
                    ? __('user.notification_updated_scheduled')
                    : __('user.notification_updated_sending')
            );
        } else {
            // Create new notification
            $notification = AppNotification::create([
                'app_id' => $this->app_id,
                'user_id' => auth()->id(),
                'title' => $this->title,
                'body' => $this->body,
                'image_url' => $imageUrl,
                'notification_style' => $this->notification_style,
                'status' => $status,
                'scheduled_at' => $this->schedule_type === 'later' ? $this->scheduled_at : null,
            ]);

            // If sending now, dispatch the job immediately
            if ($this->schedule_type === 'now') {
                SendPushNotificationJob::dispatch($notification);
            }

            $this->showModal = false;
            $this->dispatch('notificationSent');

            $this->dispatch('show-toast',
                type: 'success',
                message: $this->schedule_type === 'later'
                    ? __('common.notification_scheduled')
                    : __('common.notification_sent')
            );
        }
    }

    public function render()
    {
        return view('livewire.user.send-notification-modal');
    }
}
