<?php

namespace App\Controllers\View;
use App\Controllers\BaseController;
use App\Controllers\View\EmailController;
use App\Models\NotificationModel;
use App\Models\UserNotificationModel;
use App\Models\UserModel;

class NotificationsController extends BaseController
{
    protected $notificationModel;
    protected $userNotificationModel;
    protected $userModel;

    public function __construct()
    {
        $this->notificationModel = new NotificationModel();
        $this->userNotificationModel = new UserNotificationModel();
        $this->userModel = new UserModel();
    }

    public function index()
    {
        $userId = session()->get('user_id');

        $notifications = $this->userNotificationModel
            ->select('notifications.*, user_notifications.is_read')
            ->join('notifications', 'notifications.id = user_notifications.notification_id')
            ->where('user_notifications.user_id', $userId)
            ->orderBy('notifications.created_at', 'DESC')
            ->findAll();

        return view('notifications/index', ['notifications' => $notifications]);
    }

    public function create()
    {
        return view('notifications/create');
    }

    public function send()
    {
        $title = $this->request->getPost('title');
        $message = $this->request->getPost('message');
        $group = $this->request->getPost('target_group');
        $channels = $this->request->getPost('channels'); // ['in_app', 'email', 'sms']

        $notifId = $this->notificationModel->insert([
            'title' => $title,
            'message' => $message,
            'target_group' => $group,
            'delivery_channels' => implode(',', $channels),
            'created_at' => utc_now()
        ]);

        $users = $this->userModel->where('role', $group)->findAll();

        foreach ($users as $user) {
            $this->userNotificationModel->insert([
                'notification_id' => $notifId,
                'user_id' => $user['id'],
                'is_read' => false
            ]);

            if (in_array('email', $channels)) {
                $this->sendEmail($user['email'], $title, $message);
            }

            if (in_array('sms', $channels) && !empty($user['phone'])) {
                $this->sendSMS($user['phone'], $message);
            }
        }

        return redirect()->back()->with('success', 'Notification sent successfully.');
    }

    public function markAsRead($id)
    {
        $userId = session()->get('user_id');
        $this->userNotificationModel->where('notification_id', $id)
            ->where('user_id', $userId)
            ->set(['is_read' => 1])
            ->update();

        return redirect()->back();
    }

    public function listActive()
    {
        helper('url');

        if ($redirect = $this->redirectWithoutLegacyTermFilters('notifications/active')) {
            return $redirect;
        }

        $targetGroup = $this->request->getGet('target_group');

        return view('notifications/list_active', [
            'notificationsEndpoint' => site_url('api/notifications/active'),
            'defaultTargetGroup'    => $targetGroup,
        ]);
    }

    public function listDeleted()
    {
        helper(['url', 'form']);

        if ($redirect = $this->redirectWithoutLegacyTermFilters('notifications/deleted')) {
            return $redirect;
        }

        return view('notifications/list_deleted', [
            'deletedNotificationsEndpoint' => site_url('api/notifications/deleted'),
            'restoreEndpoint'              => site_url('notifications/restore'),
            'csrfTokenName'                => csrf_token(),
            'csrfTokenValue'               => csrf_hash(),
        ]);
    }

    public function activeNotificationsData()
    {
        $targetGroup = $this->request->getGet('target_group');

        return $this->response->setJSON($this->buildActiveNotificationsPayload($targetGroup));
    }

    public function deletedNotificationsData()
    {
        return $this->response->setJSON($this->buildDeletedNotificationsPayload());
    }

    public function restore($id)
    {
        if ($this->notificationModel->restoreNotification($id)) {
            return redirect()->to(base_url('notifications/deleted'))->with('success', 'Notification restored successfully.');
        }

        return redirect()->to(base_url('notifications/deleted'))->with('error', 'Failed to restore notification.');
    }

    protected function sendEmail($to, $subject, $message)
    {
        $mailer = new EmailController();
        $mailer->sendEmail($to, $subject, $message);
    }

    protected function sendSMS($phone, $message)
    {
        log_message('info', "SMS to {$phone}: {$message}");
    }

    private function buildActiveNotificationsPayload(?string $targetGroup): array
    {
        $targetGroup = $targetGroup !== null ? trim($targetGroup) : null;
        if ($targetGroup === '') {
            $targetGroup = null;
        }

        $schoolYear = $this->currentSchoolYearName();
        if ($schoolYear !== '' && db_connect()->fieldExists('school_year', 'notifications')) {
            $this->notificationModel->where('school_year', $schoolYear);
        }

        $rows = $this->notificationModel->getActiveNotifications($targetGroup);
        if (!is_array($rows)) {
            $rows = [];
        }

        $now = time();

        $notifications = array_map(static function ($row) use ($now) {
            if (!is_array($row)) {
                return [];
            }

            $expiresAt = $row['expires_at'] ?? null;
            $expiryTs = $expiresAt ? strtotime((string) $expiresAt) : false;
            $isExpired = $expiryTs !== false && $expiryTs <= $now;

            return [
                'id'           => $row['id'] ?? null,
                'title'        => $row['title'] ?? null,
                'message'      => $row['message'] ?? null,
                'priority'     => $row['priority'] ?? null,
                'scheduled_at' => $row['scheduled_at'] ?? null,
                'expires_at'   => $expiresAt,
                'created_at'   => $row['created_at'] ?? null,
                'target_group' => $row['target_group'] ?? null,
                'isExpired'    => $isExpired,
            ];
        }, $rows);

        return [
            'notifications' => $notifications,
        ];
    }

    private function buildDeletedNotificationsPayload(): array
    {
        $rows = $this->notificationModel->getDeletedNotifications();
        if (!is_array($rows)) {
            $rows = [];
        }

        $notifications = array_map(static function ($row) {
            if (!is_array($row)) {
                return [];
            }

            return [
                'id'           => $row['id'] ?? null,
                'title'        => $row['title'] ?? null,
                'message'      => $row['message'] ?? null,
                'priority'     => $row['priority'] ?? null,
                'scheduled_at' => $row['scheduled_at'] ?? null,
                'expires_at'   => $row['expires_at'] ?? null,
                'deleted_at'   => $row['deleted_at'] ?? null,
            ];
        }, $rows);

        return [
            'notifications' => $notifications,
        ];
    }

    private function redirectWithoutLegacyTermFilters(string $route): ?\CodeIgniter\HTTP\RedirectResponse
    {
        $legacyTermKeys = ['school_year', 'schoolYear', 'year', 'semester'];
        $query = $this->request->getGet();
        $hasLegacyTermFilter = false;

        foreach ($legacyTermKeys as $key) {
            if (array_key_exists($key, $query)) {
                unset($query[$key]);
                $hasLegacyTermFilter = true;
            }
        }

        if (!$hasLegacyTermFilter) {
            return null;
        }

        $target = site_url($route) . (!empty($query) ? '?' . http_build_query($query) : '');
        return redirect()->to($target);
    }
}
