<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Deposit;
use App\Models\GeneratedLetter;
use App\Models\Offboarding;
use App\Models\PerformanceCycle;
use App\Models\PerformanceReview;
use App\Models\PrePayment;
use App\Models\Resignation;
use App\Services\Finance\FinanceNavService;
use App\Services\Finance\PrePaymentInstallmentService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\Rule;

class HrMobileController extends Controller
{
    public function resignations(Request $request): JsonResponse
    {
        $user = Auth::user();
        $query = Resignation::with('user')->orderByDesc('resignation_date');

        if (! $user->hasPermission('hr_operations_view')) {
            $query->where('user_id', $user->id);
        }

        return response()->json($query->paginate($request->integer('per_page', 15)));
    }

    public function showResignation(Resignation $resignation): JsonResponse
    {
        $this->authorize('view', $resignation);

        return response()->json($resignation->load(['user', 'offboarding']));
    }

    public function offboardings(Request $request): JsonResponse
    {
        $user = Auth::user();
        abort_unless($user->hasPermission('hr_operations_view') || $user->hasPermission('dashboard_view'), 403);

        $query = Offboarding::with('user')->orderByDesc('created_at');
        if (! $user->hasPermission('hr_operations_view')) {
            $query->where('user_id', $user->id);
        }

        return response()->json($query->paginate($request->integer('per_page', 15)));
    }

    public function showOffboarding(Offboarding $offboarding): JsonResponse
    {
        $user = Auth::user();
        if ((int) $offboarding->company_id !== (int) $user->company_id) {
            abort(403);
        }
        if (! $user->hasPermission('hr_operations_view') && (int) $offboarding->user_id !== (int) $user->id) {
            abort(403);
        }

        return response()->json($offboarding->load(['user', 'checklistItems.assignee', 'fnfSettlement']));
    }

    public function performanceReviews(Request $request): JsonResponse
    {
        abort_unless(Auth::user()?->hasPermission('performance_view'), 403);

        $query = PerformanceReview::with(['user', 'reviewer', 'performanceCycle'])
            ->orderByDesc('review_date');

        return response()->json($query->paginate($request->integer('per_page', 15)));
    }

    public function performanceCycles(Request $request): JsonResponse
    {
        abort_unless(Auth::user()?->hasPermission('performance_view'), 403);

        return response()->json(
            PerformanceCycle::orderByDesc('created_at')->paginate($request->integer('per_page', 15))
        );
    }

    public function deposits(Request $request, FinanceNavService $nav): JsonResponse
    {
        abort_unless($nav->hasTreasuryAccess(Auth::user()), 403);

        return response()->json(
            Deposit::with(['account', 'depositCategory'])->orderByDesc('date')->paginate($request->integer('per_page', 15))
        );
    }

    public function generatedLetters(Request $request): JsonResponse
    {
        abort_unless(Auth::user()?->hasPermission('documents_view'), 403);

        return response()->json(
            GeneratedLetter::with(['employee', 'template'])->orderByDesc('created_at')->paginate($request->integer('per_page', 15))
        );
    }

    public function showGeneratedLetter(GeneratedLetter $generatedLetter): JsonResponse
    {
        abort_unless(Auth::user()?->hasPermission('documents_view'), 403);
        if ((int) $generatedLetter->company_id !== (int) Auth::user()?->company_id) {
            abort(403);
        }

        return response()->json($generatedLetter->load(['employee', 'template', 'generatedBy']));
    }

    public function prePayments(Request $request, FinanceNavService $nav): JsonResponse
    {
        abort_unless($nav->hasOperationalOrTreasuryAccess(Auth::user()), 403);

        $query = PrePayment::with('user')->orderByDesc('year')->orderByDesc('month');
        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }

        return response()->json($query->paginate($request->integer('per_page', 15)));
    }

    public function storePrePayment(Request $request, FinanceNavService $nav): JsonResponse
    {
        abort_unless($nav->hasOperationalOrTreasuryAccess(Auth::user()), 403);
        abort_unless(Auth::user()?->hasPermission('finance_create'), 403);

        $user = Auth::user();
        $validated = $request->validate([
            'user_id' => 'required|exists:users,id',
            'advance_date' => 'required|date',
            'amount' => 'required|numeric|min:0.01',
            'installments' => ['required', 'integer', Rule::in(PrePaymentInstallmentService::INSTALLMENT_OPTIONS)],
            'deduction_start_month' => 'required|integer|min:1|max:12',
            'deduction_start_year' => 'required|integer|min:2000|max:2100',
            'notes' => 'nullable|string|max:1000',
        ]);

        $records = app(PrePaymentInstallmentService::class)->createPlan(
            (int) $user->company_id,
            (int) $validated['user_id'],
            (float) $validated['amount'],
            $validated['advance_date'],
            (int) $validated['installments'],
            (int) $validated['deduction_start_month'],
            (int) $validated['deduction_start_year'],
            $validated['notes'] ?? null
        );

        return response()->json([
            'installments' => collect($records)->load('user'),
            'count' => count($records),
        ], 201);
    }
}
