<?php

namespace App\Http\Controllers\Employee;

use App\Enums\UserType;
use App\Http\Controllers\Controller;
use App\Models\Loan;
use App\Models\User;
use App\Services\NotificationService;
use Illuminate\Http\Request;
use Inertia\Inertia;

class EmployeeLoanController extends Controller
{
    public function __construct(private readonly NotificationService $notificationService) {}

    public function index(Request $request)
    {
        $loans = Loan::where('employee_id', $request->user()->id)
            ->with(['approver', 'transactions.payroll'])
            ->latest()
            ->get();

        return Inertia::render('Employee/Loan/Index', [
            'loans' => $loans,
        ]);
    }

    public function store(Request $request)
    {
        $validated = $this->validateLoanPayload($request);

        Loan::create([
            'employee_id' => $request->user()->id,
            'total_amount' => $validated['total_amount'],
            'installment_amount' => $validated['installment_amount'],
            'start_month' => $validated['start_month'],
            'loan_date' => now()->format('Y-m'),
            'remaining_balance' => $validated['total_amount'], // initially same as total
            'status' => 'draft',
            'remarks' => $validated['remarks'],
        ]);

        return back()->with('success', 'Loan draft saved successfully.');
    }

    public function update(Request $request, Loan $loan)
    {
        $this->ensureOwnedByUser($loan, $request->user()->id);

        if ($loan->status !== 'draft') {
            return back()->with('error', 'Only draft loans can be edited.');
        }

        $validated = $this->validateLoanPayload($request);

        $loan->update([
            'total_amount' => $validated['total_amount'],
            'installment_amount' => $validated['installment_amount'],
            'start_month' => $validated['start_month'],
            'remaining_balance' => $validated['total_amount'],
            'remarks' => $validated['remarks'],
        ]);

        return back()->with('success', 'Loan draft updated successfully.');
    }

    public function destroy(Request $request, Loan $loan)
    {
        $this->ensureOwnedByUser($loan, $request->user()->id);

        if ($loan->status !== 'draft') {
            return back()->with('error', 'Only draft loans can be deleted.');
        }

        $loan->delete();

        return back()->with('success', 'Loan draft deleted successfully.');
    }

    public function sendForApproval(Request $request, Loan $loan)
    {
        $user = $request->user();
        $this->ensureOwnedByUser($loan, $user->id);

        if ($loan->status !== 'draft') {
            return back()->with('error', 'Only draft loans can be submitted.');
        }

        $hasActiveLoan = Loan::query()
            ->where('employee_id', $user->id)
            ->where('id', '!=', $loan->id)
            ->where(function ($query) {
                $query->whereIn('status', ['pending', 'approved'])
                    ->orWhere('remaining_balance', '>', 0);
            })
            ->exists();

        if ($hasActiveLoan) {
            return back()->with('error', 'You already have an active or outstanding loan request.');
        }

        $loan->update([
            'status' => 'pending',
            'approved_by' => null,
            'approved_at' => null,
        ]);

        $managerId = $user->employeeProfile?->manager_id;

        if ($managerId) {
            $this->notificationService->info(
                $managerId,
                'New Loan Request Pending Approval',
                "{$user->name} submitted a salary loan request for approval.",
                ['loan_id' => $loan->id],
                '/admin/loans'
            );
        } else {
            User::query()
                ->whereIn('type', [UserType::ADMIN->value, UserType::SUPER_ADMIN->value])
                ->pluck('id')
                ->each(function (int $adminId) use ($loan, $user) {
                    $this->notificationService->info(
                        $adminId,
                        'New Loan Request Pending Approval',
                        "{$user->name} submitted a salary loan request for approval.",
                        ['loan_id' => $loan->id],
                        '/admin/loans'
                    );
                });
        }

        return back()->with('success', 'Loan request sent for approval.');
    }

    private function validateLoanPayload(Request $request): array
    {
        return $request->validate([
            'total_amount' => 'required|numeric|min:1',
            'installment_amount' => 'required|numeric|min:1|lte:total_amount',
            'start_month' => 'required|date_format:Y-m',
            'remarks' => 'nullable|string|max:1000',
        ]);
    }

    private function ensureOwnedByUser(Loan $loan, int $userId): void
    {
        if ((int) $loan->employee_id !== $userId) {
            abort(403, 'Unauthorized action.');
        }
    }
}
