<?php

namespace App\Services;

use App\Models\RevocationSchedule;
use App\Models\ReminderLog;
use App\Models\EmployeeAccessDetail;
use App\Models\User;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Log;

class ReminderService
{
    protected $telegramService;

    public function __construct(TelegramService $telegramService)
    {
        $this->telegramService = $telegramService;
    }

    /**
     * Send reminder for specific schedule
     */
    public function sendReminder(RevocationSchedule $schedule, string $type): bool
    {
        $accessDetail = $schedule->employeeAccessDetail;
        $employee = $accessDetail->employee;
        $accessCatalog = $accessDetail->accessCatalog;

        $daysLeft = $accessDetail->daysUntilExpiry();
        $expiryDate = $accessDetail->current_expiry_date->format('d M Y');

        // Get users to notify
        $notifyUsers = $this->getUsersToNotify($employee->department_id);

        $success = true;

        foreach ($notifyUsers as $user) {
            // Send Email
            if ($user->notificationSetting?->email_enabled) {
                $emailSent = $this->sendEmailReminder(
                    $user->email,
                    $type,
                    $employee,
                    $accessCatalog,
                    $expiryDate,
                    $daysLeft
                );

                $this->logReminder($schedule, $user, $type, 'email', $emailSent);
                $success = $success && $emailSent;
            }

            // Send Telegram
            if ($user->notificationSetting?->telegram_enabled && $user->telegram_chat_id) {
                $telegramSent = $this->telegramService->sendReminder(
                    $user->telegram_chat_id,
                    $employee->name,
                    $accessCatalog->name,
                    $expiryDate,
                    $daysLeft,
                    $accessDetail->id
                );

                $this->logReminder($schedule, $user, $type, 'telegram', $telegramSent);
                $success = $success && $telegramSent;
            }
        }

        return $success;
    }

    /**
     * Send email reminder
     */
    protected function sendEmailReminder(string $email, string $type, $employee, $accessCatalog, string $expiryDate, int $daysLeft): bool
    {
        try {
            $subject = $this->getEmailSubject($type, $employee->name);
            
            $data = [
                'type' => $type,
                'employee' => $employee,
                'accessCatalog' => $accessCatalog,
                'expiryDate' => $expiryDate,
                'daysLeft' => $daysLeft,
                'priority' => $this->getPriority($daysLeft),
            ];

            Mail::send('emails.reminder', $data, function ($message) use ($email, $subject) {
                $message->to($email)
                        ->subject($subject)
                        ->from(config('mail.from.address'), config('mail.from.name'));
            });

            Log::info('Email reminder sent', ['email' => $email, 'type' => $type]);
            return true;

        } catch (\Exception $e) {
            Log::error('Email reminder failed: ' . $e->getMessage(), ['email' => $email]);
            return false;
        }
    }

    /**
     * Get users to notify based on department
     */
    protected function getUsersToNotify(int $departmentId): array
    {
        return User::where(function ($query) use ($departmentId) {
                // Super admin gets all notifications
                $query->where('role', 'super_admin')
                      // Admin HR gets all
                      ->orWhere('role', 'admin_hr')
                      // IT Security gets all
                      ->orWhere('role', 'it_security')
                      // Department managers get their dept only
                      ->orWhere(function ($q) use ($departmentId) {
                          $q->where('role', 'manager')
                            ->where('department_id', $departmentId);
                      });
            })
            ->where('is_active', true)
            ->with('notificationSetting')
            ->get()
            ->filter(function ($user) use ($departmentId) {
                // Check if user wants notifications for this department
                $setting = $user->notificationSetting;
                if (!$setting) return true; // Default notify all
                
                $deptFilter = $setting->notify_for_departments;
                if (empty($deptFilter)) return true; // No filter = all departments
                
                return in_array($departmentId, $deptFilter);
            })
            ->all();
    }

    /**
     * Log reminder to database
     */
    protected function logReminder(RevocationSchedule $schedule, User $user, string $type, string $channel, bool $success): void
    {
        ReminderLog::create([
            'employee_id' => $schedule->employeeAccessDetail->employee_id,
            'employee_access_detail_id' => $schedule->employee_access_detail_id,
            'revocation_schedule_id' => $schedule->id,
            'reminder_type' => $type,
            'channel' => $channel,
            'recipient_email' => $channel === 'email' ? $user->email : null,
            'recipient_telegram' => $channel === 'telegram' ? $user->telegram_chat_id : null,
            'message_content' => $this->getMessagePreview($type),
            'status' => $success ? 'sent' : 'failed',
            'sent_at' => $success ? now() : null,
            'error_message' => $success ? null : 'Failed to send',
        ]);
    }

    /**
     * Resend failed reminder
     */
    public function resendReminder(ReminderLog $reminderLog): bool
    {
        $schedule = $reminderLog->revocationSchedule;
        
        if (!$schedule) {
            Log::error('Cannot resend: schedule not found');
            return false;
        }

        return $this->sendReminder($schedule, $reminderLog->reminder_type);
    }

    /**
     * Send test notification
     */
    public function sendTestNotification(string $email, string $type): bool
    {
        try {
            $testData = [
                'type' => 'access_revoke_7',
                'employee' => (object)['name' => 'Test Employee'],
                'accessCatalog' => (object)['name' => 'Test Access'],
                'expiryDate' => now()->addDays(7)->format('d M Y'),
                'daysLeft' => 7,
                'priority' => 'medium',
            ];

            Mail::send('emails.reminder', $testData, function ($message) use ($email) {
                $message->to($email)
                        ->subject('[TEST] ACM System Notification')
                        ->from(config('mail.from.address'), config('mail.from.name'));
            });

            return true;

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

    /**
     * Send daily summary to admins
     */
    public function sendDailySummary(): void
    {
        $stats = [
            'overdue' => EmployeeAccessDetail::expiredButNotRevoked()->count(),
            'expiring_7d' => EmployeeAccessDetail::expiringInDays(7)->count(),
            'expiring_30d' => EmployeeAccessDetail::expiringInDays(30)->count(),
            'pending_extensions' => \App\Models\ExtensionRequest::pending()->count(),
        ];

        $superAdmins = User::where('role', 'super_admin')
            ->where('is_active', true)
            ->whereNotNull('telegram_chat_id')
            ->get();

        foreach ($superAdmins as $admin) {
            $this->telegramService->sendDailySummary($admin->telegram_chat_id, $stats);
        }
    }

    /**
     * Get email subject
     */
    protected function getEmailSubject(string $type, string $employeeName): string
    {
        $subjects = [
            'retirement_30' => "[ACM] Peringatan: {$employeeName} akan pensiun dalam 30 hari",
            'retirement_7' => "[URGENT] {$employeeName} pensiun dalam 7 hari",
            'retirement_1' => "[URGENT] {$employeeName} BESOK pensiun!",
            'retirement_0' => "[URGENT] {$employeeName} HARI INI pensiun!",
            'access_revoke_7' => "[ACM] Peringatan: Akses {$employeeName} expire dalam 7 hari",
            'access_revoke_1' => "[URGENT] Akses {$employeeName} expire BESOK",
            'access_revoke_0' => "[URGENT] Akses {$employeeName} HARI INI expire!",
            'extended_reminder' => "[ACM] Reminder: Akses extended {$employeeName}",
        ];

        return $subjects[$type] ?? "[ACM] Notification";
    }

    /**
     * Get priority level
     */
    protected function getPriority(int $daysLeft): string
    {
        if ($daysLeft <= 0) return 'critical';
        if ($daysLeft <= 1) return 'high';
        if ($daysLeft <= 7) return 'medium';
        return 'low';
    }

    /**
     * Get message preview for logging
     */
    protected function getMessagePreview(string $type): string
    {
        $previews = [
            'retirement_30' => 'Reminder pensiun 30 hari',
            'retirement_7' => 'Reminder pensiun 7 hari',
            'retirement_1' => 'Reminder pensiun 1 hari',
            'retirement_0' => 'Reminder pensiun hari ini',
            'access_revoke_7' => 'Reminder cabut akses 7 hari',
            'access_revoke_1' => 'Reminder cabut akses 1 hari',
            'access_revoke_0' => 'Reminder cabut akses hari ini',
            'extended_reminder' => 'Reminder perpanjangan',
        ];

        return $previews[$type] ?? 'Notification';
    }
}