<?php
namespace Controllers\Admin;

use Core\Controller;

class NotificationController extends Controller {

    public function index(): void {
        $this->requireRole('super-admin', 'admin');
        $sid  = $this->schoolId();
        $page = max(1, (int)$this->request->get('page', 1));
        $tab  = $this->request->get('tab', 'send');

        // History filters
        $filters = [
            'search'  => $this->request->get('search', ''),
            'type'    => $this->request->get('type', ''),
            'channel' => $this->request->get('channel', ''),
            'date_from'=> $this->request->get('date_from', ''),
            'date_to'  => $this->request->get('date_to', ''),
        ];
        $where  = "n.school_id=?";
        $params = [$sid];
        if ($filters['search'])   { $where .= " AND (n.title LIKE ? OR n.message LIKE ?)"; $params[] = '%'.$filters['search'].'%'; $params[] = '%'.$filters['search'].'%'; }
        if ($filters['type'])     { $where .= " AND n.type=?";    $params[] = $filters['type']; }
        if ($filters['channel'])  { $where .= " AND n.channel=?"; $params[] = $filters['channel']; }
        if ($filters['date_from']){ $where .= " AND DATE(n.sent_at)>=?"; $params[] = $filters['date_from']; }
        if ($filters['date_to'])  { $where .= " AND DATE(n.sent_at)<=?"; $params[] = $filters['date_to']; }

        $notifications = $this->db->paginate(
            "SELECT n.*, u.name AS recipient_name FROM notifications n
             LEFT JOIN users u ON u.id=n.user_id
             WHERE $where ORDER BY n.id DESC",
            $params, $page, 25
        );
        // Stats
        $stats = $this->db->fetch(
            "SELECT COUNT(*) AS total,
                    SUM(CASE WHEN channel='sms' OR channel='all' THEN 1 ELSE 0 END) AS sms_count,
                    SUM(CASE WHEN is_read=1 THEN 1 ELSE 0 END) AS read_count
             FROM notifications WHERE school_id=?", [$sid]
        ) ?? [];

        $templates = $this->db->fetchAll(
            "SELECT * FROM sms_templates WHERE school_id=? ORDER BY type, name", [$sid]
        );
        $this->view('admin/notifications/index', compact('notifications','templates','tab','filters','stats'));
    }

    public function viewNotification(string $id): void {
        $this->requireRole('super-admin', 'admin');
        $n = $this->db->fetch(
            "SELECT n.*, u.name AS recipient_name, u.phone, u.role AS recipient_role
             FROM notifications n LEFT JOIN users u ON u.id=n.user_id
             WHERE n.id=? AND n.school_id=?", [(int)$id, $this->schoolId()]
        );
        if (!$n) { $this->json(['error'=>'Not found'], 404); return; }
        $this->json($n);
    }

    public function delete(string $id): void {
        $this->requireRole('super-admin', 'admin');
        $this->verifyCsrf();
        $this->db->query("DELETE FROM notifications WHERE id=? AND school_id=?", [(int)$id, $this->schoolId()]);
        $this->withSuccess('Notification deleted.');
        $this->redirect('admin/notifications?tab=history');
    }

    public function bulkDelete(): void {
        $this->requireRole('super-admin', 'admin');
        $this->verifyCsrf();
        $ids = $this->request->post('ids', []);
        if (empty($ids)) { $this->withError('No items selected.'); $this->redirect('admin/notifications?tab=history'); return; }
        $placeholders = implode(',', array_fill(0, count($ids), '?'));
        $params = array_merge(array_map('intval', $ids), [$this->schoolId()]);
        $this->db->query("DELETE FROM notifications WHERE id IN ($placeholders) AND school_id=?", $params);
        $this->withSuccess(count($ids).' notifications deleted.');
        $this->redirect('admin/notifications?tab=history');
    }

    public function saveTemplate(): void {
        $this->requireRole('super-admin', 'admin');
        $this->verifyCsrf();
        $data = $this->request->all();
        $sid  = $this->schoolId();
        if (!empty($data['id'])) {
            $this->db->update('sms_templates', [
                'name'       => htmlspecialchars($data['name'], ENT_QUOTES),
                'type'       => $data['type'],
                'title'      => htmlspecialchars($data['title'], ENT_QUOTES),
                'body'       => $data['body'],
                'updated_at' => date('Y-m-d H:i:s'),
            ], 'id=? AND school_id=?', [(int)$data['id'], $sid]);
        } else {
            $this->db->insert('sms_templates', [
                'school_id'  => $sid,
                'name'       => htmlspecialchars($data['name'], ENT_QUOTES),
                'type'       => $data['type'],
                'title'      => htmlspecialchars($data['title'], ENT_QUOTES),
                'body'       => $data['body'],
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s'),
            ]);
        }
        $this->withSuccess('Template saved.');
        $this->redirect('admin/notifications?tab=templates');
    }

    public function deleteTemplate(string $id): void {
        $this->requireRole('super-admin', 'admin');
        $this->verifyCsrf();
        $this->db->query("DELETE FROM sms_templates WHERE id=? AND school_id=?", [(int)$id, $this->schoolId()]);
        $this->withSuccess('Template deleted.');
        $this->redirect('admin/notifications?tab=templates');
    }

    public function send(): void {
        $this->requireRole('super-admin', 'admin');
        $this->verifyCsrf();
        $sid     = $this->schoolId();
        $data    = $this->request->all();
        $errors  = $this->request->validate([
            'title'   => 'required|max:200',
            'message' => 'required',
            'type'    => 'required|in:fee,result,attendance,announcement,alert,general',
        ]);
        if ($errors) { $this->withErrors($errors); $this->redirect('admin/notifications'); return; }

        $target  = $data['target'] ?? 'all';   // all | role | student
        $channel = $data['channel'] ?? 'in-app';

        // Determine recipients
        $recipients = [];
        if ($target === 'all') {
            $recipients = $this->db->fetchAll(
                "SELECT id FROM users WHERE school_id=? AND is_active=1", [$sid]
            );
        } elseif ($target === 'parents') {
            $recipients = $this->db->fetchAll(
                "SELECT id FROM users WHERE school_id=? AND role='parent' AND is_active=1", [$sid]
            );
        } elseif ($target === 'teachers') {
            $recipients = $this->db->fetchAll(
                "SELECT id FROM users WHERE school_id=? AND role='teacher' AND is_active=1", [$sid]
            );
        }

        $now = date('Y-m-d H:i:s');
        $smsSent = 0; $smsFailed = 0;
        $school = $this->db->fetch("SELECT name FROM schools WHERE id=?", [$sid]);

        foreach ($recipients as $r) {
            // Resolve placeholders per recipient
            $resolved = $this->resolvePlaceholders($data['message'], $r['id'], $sid, $school['name'] ?? '');
            $resolvedTitle = $this->resolvePlaceholders($data['title'], $r['id'], $sid, $school['name'] ?? '');

            // In-app notification
            if (in_array($channel, ['in-app', 'all'])) {
                $this->db->insert('notifications', [
                    'school_id'  => $sid,
                    'user_id'    => $r['id'],
                    'type'       => $data['type'],
                    'title'      => htmlspecialchars($resolvedTitle, ENT_QUOTES),
                    'message'    => htmlspecialchars($resolved, ENT_QUOTES),
                    'channel'    => $channel,
                    'is_read'    => 0,
                    'sent_at'    => $now,
                    'created_at' => $now,
                    'updated_at' => $now,
                ]);
            }

            // SMS
            if (in_array($channel, ['sms', 'all'])) {
                $user = $this->db->fetch("SELECT phone FROM users WHERE id=?", [$r['id']]);
                if (!empty($user['phone'])) {
                    $sms    = new \Services\SmsService($sid);
                    $result = $sms->send($user['phone'], $resolved, $sid);
                    $result ? $smsSent++ : $smsFailed++;
                }
            }
        }

        $msg = 'Notification sent to ' . count($recipients) . ' recipients.';
        if ($channel === 'sms' || $channel === 'all') {
            $msg .= " SMS: $smsSent sent, $smsFailed failed.";
        }

        $this->logActivity('sent_notification', 'Notification', 0);
        $this->withSuccess($msg);
        $this->redirect('admin/notifications');
    }

    // Resolve template placeholders for a specific user/recipient
    private function resolvePlaceholders(string $text, int $userId, int $schoolId, string $schoolName): string {
        // Get user info
        $user = $this->db->fetch("SELECT name, role FROM users WHERE id=?", [$userId]);
        if (!$user) return $text;

        $firstName = explode(' ', $user['name'])[0];

        // Defaults
        $student  = $user['name'];
        $term     = '';
        $balance  = '';
        $amount   = '';
        $date     = date('d M Y');

        // If parent — get linked student info
        if ($user['role'] === 'parent') {
            $studentRow = $this->db->fetch(
                "SELECT u.name AS student_name, s.id AS student_id FROM parent_student ps
                 JOIN students s ON s.id=ps.student_id
                 JOIN users u ON u.id=s.user_id
                 JOIN parents p ON p.id=ps.parent_id
                 WHERE p.user_id=? AND s.status='active'
                 ORDER BY s.id DESC LIMIT 1", [$userId]
            );
            if ($studentRow) {
                $student = $studentRow['student_name'];
                // Get current term
                $termRow = $this->db->fetch(
                    "SELECT t.name AS term_name, ay.name AS year_name, t.id
                     FROM terms t JOIN academic_years ay ON ay.id=t.academic_year_id
                     WHERE ay.school_id=? AND t.is_current=1 LIMIT 1", [$schoolId]
                );
                if ($termRow) {
                    $term = $termRow['year_name'].' '.$termRow['term_name'];
                    // Get fee balance
                    $inv = $this->db->fetch(
                        "SELECT (total_amount + IFNULL(opening_balance,0) - amount_paid) AS bal
                         FROM fee_invoices WHERE student_id=? AND term_id=? LIMIT 1",
                        [$studentRow['student_id'], $termRow['id']]
                    );
                    if ($inv) $balance = 'KES '.number_format((float)$inv['bal'], 2);
                }
            }
        }

        return str_replace(
            ['{student}', '{term}', '{balance}', '{amount}', '{date}', '{school}', '{parent}'],
            [$student,    $term,    $balance,    $amount,    $date,    $schoolName, $firstName],
            $text
        );
    }

    // API: get unread count for current user
    public function unreadCount(): void {
        $userId = $this->currentUser()['id'] ?? 0;
        $count  = $this->db->fetch(
            "SELECT COUNT(*) as c FROM notifications WHERE user_id=? AND is_read=0", [$userId]
        )['c'] ?? 0;
        $this->json(['count' => $count]);
    }

    // Mark all read
    public function markRead(): void {
        $userId = $this->currentUser()['id'] ?? 0;
        $this->db->query("UPDATE notifications SET is_read=1 WHERE user_id=?", [$userId]);
        $this->json(['ok' => true]);
    }
}
