<?php

namespace App\Services\Attendance;

use App\Services\EmailService;
use App\Services\Notifications\UserNotificationDispatchService;
use Illuminate\Support\Facades\DB;

class AttendanceDailySummaryService
{
    public function __construct(
        private UserNotificationDispatchService $notifier,
        private EmailService $emailService
    ) {
    }

    public function sendAbsenteesSummary(): int
    {
        $rows = $this->fetchTodaySummary('absent');
        return $this->notifyParents($rows, 'absent');
    }

    public function sendLatesSummary(): int
    {
        $rows = $this->fetchTodaySummary('late');
        return $this->notifyParents($rows, 'late');
    }

    private function fetchTodaySummary(string $type): array
    {
        $start = now()->startOfDay();
        $endEx = now()->addDay()->startOfDay();

        $query = DB::table('attendance_data as ad')
            ->join('students as s', 's.id', '=', 'ad.student_id')
            ->leftJoin('users as u', 'u.id', '=', 's.parent_id')
            ->select(
                'ad.date',
                's.id as student_id',
                's.firstname as student_firstname',
                's.lastname as student_lastname',
                'u.id as parent_id',
                'u.email as parent_email',
                'u.firstname as parent_firstname',
                'u.lastname as parent_lastname'
            )
            ->where('ad.date', '>=', $start)
            ->where('ad.date', '<', $endEx);

        if ($type === 'absent') {
            $query->where(function ($w) {
                $w->whereIn(DB::raw("UPPER(TRIM(ad.status))"), ['ABSENT', 'ABS', 'A'])
                    ->orWhereRaw("UPPER(TRIM(ad.status)) LIKE 'ABS%'");
            });
        } else {
            $query->where(function ($w) {
                $w->whereIn(DB::raw("UPPER(TRIM(ad.status))"), ['LATE', 'L'])
                    ->orWhereRaw("UPPER(TRIM(ad.status)) LIKE 'LATE%'");
            });
        }

        return $query->get()->map(fn ($row) => (array) $row)->all();
    }

    private function notifyParents(array $rows, string $type): int
    {
        $sent = 0;
        foreach ($rows as $row) {
            $parentId = (int) ($row['parent_id'] ?? 0);
            if ($parentId <= 0) {
                continue;
            }

            $studentName = trim((string) ($row['student_firstname'] ?? '') . ' ' . (string) ($row['student_lastname'] ?? ''));
            $date = substr((string) ($row['date'] ?? ''), 0, 10);

            $message = sprintf(
                'Daily Attendance Update: %s was marked %s on %s.',
                $studentName !== '' ? $studentName : 'Your student',
                $type,
                $date
            );

            $this->notifier->notifyUser($parentId, 'Daily Attendance Update', $message, ['in_app'], 'attendance', 'parent');

            $email = (string) ($row['parent_email'] ?? '');
            if ($email !== '') {
                $body = '<p>' . e($message) . '</p>';
                $this->emailService->send($email, 'Daily Attendance Update', $body, 'attendance');
            }

            $sent++;
        }

        return $sent;
    }
}
