<?php

namespace Modules\Payroll\Http\Controllers\API;

use App\Http\Controllers\Controller;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Modules\Authentication\Models\User;
use Modules\Payroll\Models\UserPayroll;

class PayrollReportController extends Controller
{
    public function salaryStatementReport(Request $request): JsonResponse
    {
        $year = intval($request->year);
        $month = intval($request->month);
        if (! $year || ! $month) {
            return $this->responseError([], 'Invalid year or month.');
        }

        try {
            $data = UserPayroll::select('payslip_salaries.*', 'user_payrolls.*', 'payments.*')
                ->join('payslip_salaries', 'payslip_salaries.user_id', 'user_payrolls.user_id')
                ->join('payments', 'payments.user_id', 'user_payrolls.user_id')
                ->whereYear('payslip_salaries.payment_date', $year)
                ->whereMonth('payslip_salaries.payment_date', $month)
                ->with('user')
                ->get();

            if ($data && count($data) > 0) {
                return $this->responseSuccess($data, _lang('Payroll report successfully.'));
            }

            return $this->responseError([], 'No Data Found', 404);
        } catch (\Exception $e) {
            return $this->responseError([], 'Something went wrong.');
        }
    }

    public function getPaymentInfo(Request $request): JsonResponse
    {
        $fromDate = $request->from_date ?? date('Y-m-01');
        $toDate = $request->to_date ?? date('Y-m-t');

        try {
            // Validate dates
            $fromDate = Carbon::createFromFormat('Y-m-d', $fromDate)->startOfDay();
            $toDate = Carbon::createFromFormat('Y-m-d', $toDate)->endOfDay();
        } catch (\Exception $e) {
            return $this->responseError([], 'Invalid date format.');
        }

        // Base query
        $hrPaymentsQuery = User::query()
            ->whereIn('user_type', ['Staff', 'Teacher', 'Accountant', 'Librarian', 'Hostel', 'Transport'])
            ->with([
                'payroll' => fn ($q) => $q->select('user_id', 'net_salary', 'current_due', 'current_advance'),
                'payroll.payslipSalaries' => fn ($q) => $q
                    ->whereBetween('payment_date', [$fromDate, $toDate]),
                'payroll.payslipSalaries.payments' => fn ($q) => $q
                    ->whereBetween('created_at', [$fromDate, $toDate]),
                'payroll.payslipSalaries.invoice',
            ]);

        // Select minimal fields for efficiency
        $users = $hrPaymentsQuery->select('id', 'name')->get();

        $report = $users->map(function ($user) {
            $payslipSalary = $user->payroll->payslipSalaries->first();

            return [
                'hr_id' => $user->id,
                'hr_name' => $user->name,
                'invoice_id' => $payslipSalary?->invoice?->invoice_id ?? null,
                'is_paid' => $payslipSalary->is_paid ?? null,
                'payment_type' => $payslipSalary?->payments->first()?->type ?? null,
                'net_salary' => $user->payroll->net_salary ?? 0,
                'payable_salary' => $user->payroll->net_salary - ($payslipSalary->paid_amount ?? 0),
                'paid' => $payslipSalary->paid_amount ?? 0,
                'due' => $user->payroll->current_due ?? 0,
                'advance' => $user->payroll->current_advance ?? 0,
                'payment_date' => $payslipSalary->payment_date ?? null,
            ];
        });

        if ($report->isNotEmpty()) {
            return $this->responseSuccess($report, _lang('HR Payments fetched successfully.'));
        }

        return $this->responseError([], 'No Data Found', 404);
    }
}
