<?php
namespace App\Services;

use App\Repositories\NotificationRepository;
use App\Repositories\ActivityReminderRepository;
use App\Utils\Logger;

/**
 * Notification Service
 */
class NotificationService
{
    private $notificationRepo;
    private $reminderRepo;

    public function __construct(
        NotificationRepository $notificationRepo,
        ActivityReminderRepository $reminderRepo
    ) {
        $this->notificationRepo = $notificationRepo;
        $this->reminderRepo = $reminderRepo;
    }

    /**
     * Create a notification
     */
    public function create($userId, $type, $title, $message = null, $entityType = null, $entityId = null, $showPopup = true)
    {
        try {
            $id = $this->notificationRepo->create([
                'user_didar_id' => $userId,
                'type' => $type,
                'title' => $title,
                'message' => $message,
                'entity_type' => $entityType,
                'entity_id' => $entityId,
                'show_popup' => $showPopup
            ]);

            Logger::logInfo("Notification created", [
                'notification_id' => $id,
                'user_id' => $userId,
                'type' => $type,
                'show_popup' => $showPopup
            ]);

            return $id;
        } catch (\Exception $e) {
            Logger::logError("Failed to create notification", $e, [
                'user_id' => $userId,
                'type' => $type
            ]);
            return false;
        }
    }

    /**
     * Get unread notifications for user
     */
    public function getUnread($userId, $limit = 50)
    {
        return $this->notificationRepo->findUnreadByUser($userId, $limit);
    }

    /**
     * Get all notifications for user
     */
    public function getAll($userId, $limit = 50, $offset = 0)
    {
        return $this->notificationRepo->findAllByUser($userId, $limit, $offset);
    }

    /**
     * Get unread count
     */
    public function getUnreadCount($userId)
    {
        return $this->notificationRepo->countUnread($userId);
    }
    
    /**
     * Get notification by ID
     */
    public function getById($notificationId)
    {
        return $this->notificationRepo->findById($notificationId);
    }

    /**
     * Mark notification as read
     */
    public function markAsRead($notificationId, $userId)
    {
        return $this->notificationRepo->markAsRead($notificationId, $userId);
    }

    /**
     * Mark all notifications as read
     */
    public function markAllAsRead($userId)
    {
        return $this->notificationRepo->markAllAsRead($userId);
    }

    /**
     * Delete notification
     */
    public function delete($notificationId, $userId)
    {
        return $this->notificationRepo->delete($notificationId, $userId);
    }

    /**
     * Check and send activity reminders
     */
    public function checkActivityReminders()
    {
        Logger::logInfo("Checking activity reminders");
        
        $reminders = $this->reminderRepo->findDueReminders();
        
        Logger::logInfo("Found due reminders", [
            'count' => count($reminders),
            'reminders' => $reminders
        ]);
        
        $notifications = [];

        foreach ($reminders as $reminder) {
            try {
                Logger::logInfo("Processing reminder", [
                    'reminder_id' => $reminder['id'],
                    'activity_id' => $reminder['activity_didar_id'],
                    'owner_id' => $reminder['owner_didar_id'],
                    'reminder_time' => $reminder['reminder_time'],
                    'due_date' => $reminder['due_date']
                ]);
                
                // Create notification
                $notificationId = $this->create(
                    $reminder['owner_didar_id'],
                    'activity_reminder',
                    'یادآوری فعالیت',
                    "فعالیت '{$reminder['title']}' در " . date('Y-m-d H:i', strtotime($reminder['due_date'])) . " انجام شود",
                    'activity',
                    $reminder['activity_didar_id']
                );

                if ($notificationId) {
                    // Mark reminder as sent
                    $this->reminderRepo->markAsSent($reminder['id']);
                    $notifications[] = [
                        'id' => $notificationId,
                        'user_id' => $reminder['owner_didar_id'],
                        'type' => 'activity_reminder',
                        'title' => 'یادآوری فعالیت',
                        'message' => "فعالیت '{$reminder['title']}' در " . date('Y-m-d H:i', strtotime($reminder['due_date'])) . " انجام شود",
                        'show_popup' => true,
                        'entity_type' => 'activity',
                        'entity_id' => $reminder['activity_didar_id'],
                        'created_at' => date('Y-m-d H:i:s')
                    ];
                    
                    Logger::logInfo("Reminder processed successfully", [
                        'reminder_id' => $reminder['id'],
                        'notification_id' => $notificationId
                    ]);
                } else {
                    Logger::logError("Failed to create notification for reminder", null, [
                        'reminder_id' => $reminder['id']
                    ]);
                }
            } catch (\Exception $e) {
                Logger::logError("Failed to process reminder", $e, [
                    'reminder_id' => $reminder['id'],
                    'reminder_data' => $reminder
                ]);
            }
        }

        Logger::logInfo("Finished checking reminders", [
            'notifications_created' => count($notifications)
        ]);

        return $notifications;
    }

    /**
     * Schedule activity reminder
     */
    public function scheduleActivityReminder($activityId, $dueDate, $offsetMinutes = 1440)
    {
        // Calculate reminder time (due date minus offset)
        $dueTimestamp = strtotime($dueDate);
        if ($dueTimestamp === false) {
            Logger::logError("Invalid due date format in scheduleActivityReminder", null, [
                'activity_id' => $activityId,
                'due_date' => $dueDate,
                'offset_minutes' => $offsetMinutes
            ]);
            return false;
        }
        
        $reminderTime = date('Y-m-d H:i:s', $dueTimestamp - ($offsetMinutes * 60));
        
        Logger::logInfo("Scheduling activity reminder", [
            'activity_id' => $activityId,
            'due_date' => $dueDate,
            'offset_minutes' => $offsetMinutes,
            'reminder_time' => $reminderTime,
            'calculated_timestamp' => $dueTimestamp
        ]);
        
        $result = $this->reminderRepo->create($activityId, $reminderTime, $offsetMinutes);
        
        if ($result) {
            Logger::logInfo("Activity reminder scheduled successfully", [
                'activity_id' => $activityId,
                'reminder_time' => $reminderTime
            ]);
        } else {
            Logger::logError("Failed to schedule activity reminder", null, [
                'activity_id' => $activityId,
                'reminder_time' => $reminderTime
            ]);
        }
        
        return $result;
    }
    
    /**
     * Delete all reminders for an activity
     */
    public function deleteActivityReminders($activityId)
    {
        return $this->reminderRepo->deleteByActivityId($activityId);
    }

    /**
     * Get all active reminders with optional user filter
     */
    public function getRemindersList($userId = null, $isAdmin = false, ?array $ownerFilter = null)
    {
        return $this->reminderRepo->getAllReminders($userId, $isAdmin, $ownerFilter);
    }

    /**
     * Resend reminder notification
     */
    public function resendReminder($activityId, $userId)
    {
        // Reset reminder_sent flag and update reminder_time to now + small delay
        $pdo = $this->reminderRepo->getPdo();
        $stmt = $pdo->prepare("
            UPDATE activity_reminders
            SET reminder_sent = 0, reminder_time = DATE_ADD(NOW(), INTERVAL 1 MINUTE)
            WHERE activity_didar_id = ?
        ");
        $stmt->execute([$activityId]);

        // Log the action
        $this->auditService->log('reminder_resend', 'activity_reminders', $activityId, [
            'action' => 'resend_reminder',
            'user_id' => $userId
        ]);

        return true;
    }

    /**
     * Mark reminder as done
     */
    public function markReminderDone($activityId, $userId)
    {
        // Delete the reminder (since it's done)
        $pdo = $this->reminderRepo->getPdo();
        $stmt = $pdo->prepare("
            DELETE FROM activity_reminders
            WHERE activity_didar_id = ?
        ");
        $stmt->execute([$activityId]);

        // Log the action
        $this->auditService->log('reminder_done', 'activity_reminders', $activityId, [
            'action' => 'mark_done',
            'user_id' => $userId
        ]);

        return true;
    }

    /**
     * Snooze reminder by adding minutes to reminder_time
     */
    public function snoozeReminder($activityId, $minutes, $userId)
    {
        $pdo = $this->reminderRepo->getPdo();
        $stmt = $pdo->prepare("
            UPDATE activity_reminders
            SET reminder_time = DATE_ADD(reminder_time, INTERVAL ? MINUTE),
                reminder_sent = 0
            WHERE activity_didar_id = ?
        ");
        $stmt->execute([$minutes, $activityId]);

        // Log the action
        $this->auditService->log('reminder_snooze', 'activity_reminders', $activityId, [
            'action' => 'snooze',
            'minutes' => $minutes,
            'user_id' => $userId
        ]);

        return true;
    }

    /**
     * Create silent notification (without popup)
     */
    public function createSilent($userId, $type, $title, $message = null, $entityType = null, $entityId = null)
    {
        return $this->create($userId, $type, $title, $message, $entityType, $entityId, false);
    }

    /**
     * Notify lead assigned
     */
    public function notifyLeadAssigned($ownerId, $contactId, $leadName)
    {
        return $this->create(
            $ownerId,
            'lead_assigned',
            'لید جدید اختصاص داده شد',
            "لید جدید برای {$leadName} به شما اختصاص داده شد",
            'lead',
            $contactId,
            true
        );
    }

    /**
     * Notify new activity for lead
     */
    public function notifyNewActivity($leadOwnerId, $activityId, $activityTitle, $contactName)
    {
        return $this->create(
            $leadOwnerId,
            'activity_new',
            'فعالیت جدید برای لید شما',
            "فعالیت جدید '{$activityTitle}' برای لید {$contactName} ثبت شد",
            'activity',
            $activityId,
            true
        );
    }

    /**
     * Notify deal created
     */
    public function notifyDealCreated($ownerId, $dealId, $dealTitle, $contactName)
    {
        return $this->create(
            $ownerId,
            'deal_created',
            'معامله جدید ثبت شد',
            "معامله جدید '{$dealTitle}' برای لید {$contactName} ثبت شد",
            'deal',
            $dealId,
            true
        );
    }
}

