<?php

namespace App\Services;

use App\Models\Loan;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

class NotificationService
{
    /**
     * Create a database notification immediately.
     * No queue worker is required.
     */
    public function sendToUser(
        User $user,
        string $title,
        string $message,
        ?Loan $loan = null,
        string $level = 'info'
    ): void {
        DB::table('notifications')->insert([
            'id' => (string) Str::uuid(),
            'type' => 'App\\Notifications\\LoanNotification',
            'notifiable_type' => User::class,
            'notifiable_id' => $user->id,
            'data' => json_encode([
                'title' => $title,
                'message' => $message,
                'loan_id' => $loan?->id,
                'loan_number' => $loan?->loan_number,
                'level' => $level,
            ]),
            'read_at' => null,
            'created_at' => now(),
            'updated_at' => now(),
        ]);
    }

    public function sendToAdmins(
        string $title,
        string $message,
        ?Loan $loan = null,
        string $level = 'info'
    ): void {
        User::where('role', 'admin')
            ->get()
            ->each(function (User $admin) use (
                $title,
                $message,
                $loan,
                $level
            ) {
                $this->sendToUser(
                    $admin,
                    $title,
                    $message,
                    $loan,
                    $level
                );
            });
    }

    public function loanApplied(Loan $loan): void
    {
        $this->sendToAdmins(
            'New Loan Application',
            'A new loan application has been submitted.',
            $loan,
            'info'
        );
    }

    public function loanApproved(Loan $loan): void
    {
        $this->sendToUser(
            $loan->user,
            'Loan Approved',
            'Your loan has been approved.',
            $loan,
            'success'
        );

        $this->processingFeePending($loan);
    }

    public function loanRejected(Loan $loan): void
    {
        $this->sendToUser(
            $loan->user,
            'Loan Rejected',
            'Your loan application has been rejected.',
            $loan,
            'error'
        );
    }

    public function processingFeePending(Loan $loan): void
    {
        $this->sendToUser(
            $loan->user,
            'Processing Fee Required',
            'Your processing fee is ready for payment.',
            $loan,
            'warning'
        );
    }

    public function processingFeePaid(Loan $loan): void
    {
        $this->sendToUser(
            $loan->user,
            'Processing Fee Paid',
            'Your processing fee payment has been recorded successfully.',
            $loan,
            'success'
        );

        $this->sendToAdmins(
            'Processing Fee Paid',
            'Processing fee payment has been recorded for this loan.',
            $loan,
            'success'
        );
    }

    public function loanDisbursed(Loan $loan): void
    {
        $this->sendToUser(
            $loan->user,
            'Loan Disbursed',
            'Your loan has been disbursed and the EMI schedule is now available.',
            $loan,
            'success'
        );
    }

    public function emiPaid(
        Loan $loan,
        string $message = 'Your EMI payment has been recorded successfully.'
    ): void {
        $this->sendToUser(
            $loan->user,
            'EMI Payment Received',
            $message,
            $loan,
            'success'
        );

        $this->sendToAdmins(
            'EMI Payment Received',
            'An EMI payment has been recorded for this loan.',
            $loan,
            'success'
        );
    }

    public function loanCompleted(Loan $loan): void
    {
        $this->sendToUser(
            $loan->user,
            'Loan Completed',
            'Congratulations. Your loan has been fully completed.',
            $loan,
            'success'
        );

        $this->sendToAdmins(
            'Loan Completed',
            'A loan has been fully completed.',
            $loan,
            'success'
        );
    }

    public function loanClosed(Loan $loan): void
    {
        $this->sendToUser(
            $loan->user,
            'Loan Closed',
            'Your loan has been closed by administration.',
            $loan,
            'info'
        );
    }

    public function loanOverdue(Loan $loan): void
    {
        $this->sendToUser(
            $loan->user,
            'EMI Overdue',
            'Your loan has an overdue EMI. Please make the pending payment.',
            $loan,
            'warning'
        );

        $this->sendToAdmins(
            'Loan Overdue',
            'A loan has been marked as overdue.',
            $loan,
            'warning'
        );
    }
}