<?php

namespace App\Services\Administrator;

use App\Models\AdminNotificationSubject;
use Illuminate\Support\Facades\DB;

class AdminPrintRecipientService
{
    public function __construct(
        protected AdminNotificationUserService $userService
    ) {
    }

    public function data(): array
    {
        $admins = $this->userService->fetchAdminNotificationUsers();
        $tableReady = DB::getSchemaBuilder()->hasTable('admin_notification_subjects');
        $assigned = [];

        if ($tableReady && !empty($admins)) {
            $adminIds = array_map('intval', array_column($admins, 'id'));

            $rows = AdminNotificationSubject::query()
                ->select('admin_id')
                ->where('subject', 'print_requests')
                ->whereIn('admin_id', $adminIds)
                ->get();

            foreach ($rows as $row) {
                $adminId = (int) ($row->admin_id ?? 0);
                if ($adminId > 0) {
                    $assigned[$adminId] = true;
                }
            }
        }

        return [
            'admins' => $admins,
            'assigned' => $assigned,
            'tableReady' => $tableReady,
        ];
    }

    public function save(array $posted): array
    {
        if (!DB::getSchemaBuilder()->hasTable('admin_notification_subjects')) {
            return [
                'success' => false,
                'message' => 'Notification subject storage is missing. Run migrations first.',
                'status' => 422,
            ];
        }

        $admins = $this->userService->fetchAdminNotificationUsers();
        $adminIds = array_map('intval', array_column($admins, 'id'));

        if (empty($adminIds)) {
            return [
                'success' => false,
                'message' => 'No admins found to update.',
                'status' => 404,
            ];
        }

        $selected = [];
        foreach ($posted as $key => $value) {
            $adminId = (int) $key;
            if ($adminId > 0 && in_array($adminId, $adminIds, true)) {
                $selected[] = $adminId;
            }
        }

        $selected = array_values(array_unique($selected));

        $current = AdminNotificationSubject::query()
            ->where('subject', 'print_requests')
            ->whereIn('admin_id', $adminIds)
            ->pluck('admin_id')
            ->map(fn($id) => (int) $id)
            ->unique()
            ->values()
            ->all();

        $toDelete = array_values(array_diff($current, $selected));
        $toInsert = array_values(array_diff($selected, $current));

        if (!empty($toDelete)) {
            AdminNotificationSubject::query()
                ->where('subject', 'print_requests')
                ->whereIn('admin_id', $toDelete)
                ->delete();
        }

        if (!empty($toInsert)) {
            $batch = [];
            foreach ($toInsert as $adminId) {
                $batch[] = [
                    'admin_id' => $adminId,
                    'subject' => 'print_requests',
                    'created_at' => now(),
                    'updated_at' => now(),
                ];
            }
            AdminNotificationSubject::insert($batch);
        }

        $changes = count($toDelete) + count($toInsert);

        return [
            'success' => true,
            'message' => $changes > 0 ? 'Print notification recipients updated.' : 'No changes were made.',
            'status' => 200,
        ];
    }
}