<?php

namespace App\Services;

use App\Models\Notification;
use App\Models\User;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;

class NotificationService
{
    /**
     * Send notification to user
     */
    public function send(
        User $user,
        string $type,
        string $title,
        string $body,
        ?array $data = null,
        ?string $actionType = null,
        ?string $actionUrl = null,
        bool $sendPush = true,
        bool $sendEmail = false
    ): Notification {
        // Create in-app notification
        $notification = Notification::create([
            'user_id' => $user->id,
            'company_id' => $user->company_id,
            'type' => $type,
            'title' => $title,
            'body' => $body,
            'data' => $data,
            'action_type' => $actionType,
            'action_url' => $actionUrl,
            'sent_at' => now(),
        ]);

        // Send push notification
        if ($sendPush && $user->fcm_token) {
            $this->sendPushNotification($notification);
        }

        // Send email notification
        if ($sendEmail && $user->email) {
            $this->sendEmailNotification($notification);
        }

        return $notification;
    }

    /**
     * Send notification to multiple users
     */
    public function sendToMany(
        array $userIds,
        string $type,
        string $title,
        string $body,
        ?array $data = null,
        ?string $actionType = null,
        ?string $actionUrl = null,
        bool $sendPush = true,
        bool $sendEmail = false
    ): array {
        $notifications = [];

        $users = User::whereIn('id', $userIds)->get();

        foreach ($users as $user) {
            $notifications[] = $this->send(
                $user,
                $type,
                $title,
                $body,
                $data,
                $actionType,
                $actionUrl,
                $sendPush,
                $sendEmail
            );
        }

        return $notifications;
    }

    /**
     * Send attendance reminder
     */
    public function sendAttendanceReminder(User $user): Notification
    {
        return $this->send(
            user: $user,
            type: 'reminder',
            title: 'Pengingat Absensi',
            body: 'Anda belum melakukan absensi hari ini. Jangan lupa untuk check-in!',
            data: ['reminder_type' => 'attendance'],
            actionType: 'navigate',
            actionUrl: '/attendance',
            sendPush: true,
            sendEmail: false
        );
    }

    /**
     * Send checkout reminder
     */
    public function sendCheckoutReminder(User $user): Notification
    {
        return $this->send(
            user: $user,
            type: 'reminder',
            title: 'Pengingat Check-out',
            body: 'Jangan lupa untuk melakukan check-out sebelum pulang!',
            data: ['reminder_type' => 'checkout'],
            actionType: 'navigate',
            actionUrl: '/attendance',
            sendPush: true,
            sendEmail: false
        );
    }

    /**
     * Send business trip approval notification
     */
    public function sendBusinessTripApproval(User $user, string $tripTitle, string $status): Notification
    {
        $statusText = match ($status) {
            'approved' => 'disetujui',
            'rejected' => 'ditolak',
            default => $status,
        };

        return $this->send(
            user: $user,
            type: 'approval',
            title: 'Status Perjalanan Dinas',
            body: "Perjalanan dinas \"{$tripTitle}\" telah {$statusText}.",
            data: [
                'trip_title' => $tripTitle,
                'status' => $status,
            ],
            actionType: 'navigate',
            actionUrl: '/business-trips',
            sendPush: true,
            sendEmail: true
        );
    }

    /**
     * Send new business trip request notification to approvers
     */
    public function sendBusinessTripRequest(User $approver, User $requester, string $tripTitle): Notification
    {
        return $this->send(
            user: $approver,
            type: 'business_trip',
            title: 'Pengajuan Perjalanan Dinas Baru',
            body: "{$requester->name} mengajukan perjalanan dinas \"{$tripTitle}\".",
            data: [
                'requester_id' => $requester->id,
                'requester_name' => $requester->name,
                'trip_title' => $tripTitle,
            ],
            actionType: 'navigate',
            actionUrl: '/business-trips/pending',
            sendPush: true,
            sendEmail: true
        );
    }

    /**
     * Send attendance notification (check-in/out success)
     */
    public function sendAttendanceNotification(User $user, string $action, string $time): Notification
    {
        $actionText = $action === 'check_in' ? 'Check-in' : 'Check-out';

        return $this->send(
            user: $user,
            type: 'attendance',
            title: "{$actionText} Berhasil",
            body: "{$actionText} tercatat pada pukul {$time}.",
            data: [
                'action' => $action,
                'time' => $time,
            ],
            actionType: 'navigate',
            actionUrl: '/attendance',
            sendPush: false,
            sendEmail: false
        );
    }

    /**
     * Send system notification
     */
    public function sendSystemNotification(User $user, string $title, string $body): Notification
    {
        return $this->send(
            user: $user,
            type: 'system',
            title: $title,
            body: $body,
            actionType: 'none',
            sendPush: true,
            sendEmail: false
        );
    }

    /**
     * Send push notification via FCM
     */
    protected function sendPushNotification(Notification $notification): bool
    {
        try {
            $user = $notification->user;

            if (!$user->fcm_token) {
                return false;
            }

            $serverKey = config('services.fcm.server_key');

            if (!$serverKey) {
                Log::warning('FCM server key not configured');
                return false;
            }

            $payload = [
                'to' => $user->fcm_token,
                'notification' => [
                    'title' => $notification->title,
                    'body' => $notification->body,
                    'sound' => 'default',
                    'badge' => $this->getUnreadCount($user->id),
                ],
                'data' => [
                    'notification_id' => $notification->id,
                    'type' => $notification->type,
                    'action_type' => $notification->action_type,
                    'action_url' => $notification->action_url,
                    'data' => json_encode($notification->data),
                    'click_action' => 'FLUTTER_NOTIFICATION_CLICK',
                ],
            ];

            $headers = [
                'Authorization: key=' . $serverKey,
                'Content-Type: application/json',
            ];

            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send');
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            if ($httpCode === 200) {
                $notification->update(['is_push_sent' => true]);
                return true;
            }

            Log::error('FCM push failed', [
                'http_code' => $httpCode,
                'response' => $response,
            ]);

            return false;
        } catch (\Exception $e) {
            Log::error('FCM push error: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * Send email notification
     */
    protected function sendEmailNotification(Notification $notification): bool
    {
        try {
            $user = $notification->user;

            if (!$user->email) {
                return false;
            }

            Mail::send('emails.notification', [
                'notification' => $notification,
                'user' => $user,
            ], function ($message) use ($user, $notification) {
                $message->to($user->email, $user->name)
                    ->subject($notification->title);
            });

            $notification->update(['is_email_sent' => true]);

            return true;
        } catch (\Exception $e) {
            Log::error('Email notification error: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * Get unread notification count
     */
    public function getUnreadCount(int $userId): int
    {
        return Notification::where('user_id', $userId)
            ->whereNull('read_at')
            ->count();
    }

    /**
     * Mark notification as read
     */
    public function markAsRead(int $notificationId): bool
    {
        $notification = Notification::find($notificationId);

        if ($notification) {
            $notification->markAsRead();
            return true;
        }

        return false;
    }

    /**
     * Mark all notifications as read for a user
     */
    public function markAllAsRead(int $userId): int
    {
        return Notification::where('user_id', $userId)
            ->whereNull('read_at')
            ->update(['read_at' => now()]);
    }
}
