<?php

namespace App\Http\Controllers\Admin\Finance\Payroll;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Attendance;
use App\Models\Bonus;
use App\Models\Employee;
use App\Models\SalarySlip;
use App\Models\TaxDeduction;

class PayrollController extends Controller
{
    public function __construct()
    {
        $this->middleware('can:finance.view')->only(['employeeMaster', 'attendance', 'run', 'payrollRun', 'taxDeductions', 'salarySlips', 'bonusIncentives', 'bonus']);
        $this->middleware('can:finance.add')->only(['storeBonus', 'processPayroll']);
    }
    public function employeeMaster(Request $request)
    {
        $employees = Employee::latest()->paginate(15);
        return view('admin.finance.payroll.employee-master', compact('employees'));
    }

    public function attendance(Request $request)
    {
        $attendances = Attendance::with('employee')->latest()->paginate(15);
        $employees = Employee::orderBy('name')->get();
        return view('admin.finance.payroll.attendance', compact('attendances', 'employees'));
    }
    public function run(Request $request)
    {
        $employees = Employee::orderBy('name')->get();
        return view('admin.finance.payroll.payroll-run', compact('employees'));
    }

    // Match the route method name used in web.php
    public function payrollRun(Request $request)
    {
        return $this->run($request);
    }

    public function taxDeductions()
    {
        $employees = Employee::orderBy('name')->get();
        $deductions = TaxDeduction::latest()->paginate(15);
        return view('admin.finance.payroll.tax-deductions', compact('employees', 'deductions'));
    }

    public function salarySlips()
    {
        $employees = Employee::orderBy('name')->get();
        $query = SalarySlip::with('employee')->latest();

        if (request('month')) {
            $query->where('month', request('month'));
        }

        if (request('employee_id')) {
            $query->where('employee_id', request('employee_id'));
        }

        $slips = $query->paginate(15)->withQueryString();
        return view('admin.finance.payroll.salary-slips', compact('employees', 'slips'));
    }

    public function bonusIncentives()
    {
        $employees = Employee::orderBy('name')->get();
        $bonuses = Bonus::latest()->paginate(15);
        return view('admin.finance.payroll.bonus-incentives', compact('employees', 'bonuses'));
    }

    // admin-extended.php expects these method names
    public function bonus(Request $request)
    {
        $employees = Employee::orderBy('name')->get();
        $bonuses = Bonus::with('employee')->latest()->paginate(15);
        return view('admin.finance.payroll.bonus-incentives', compact('employees', 'bonuses'));
    }

    public function storeBonus(Request $request)
    {
        $validated = $request->validate([
            'employee_id' => 'required|exists:employees,id',
            'month' => 'required|date_format:Y-m',
            'amount' => 'required|numeric|min:0',
            'type' => 'nullable|string',
            'description' => 'nullable|string',
        ]);

        Bonus::create([
            'employee_id' => $validated['employee_id'],
            'month' => $validated['month'],
            'amount' => $validated['amount'],
            'type' => $validated['type'] ?? 'bonus',
            'description' => $validated['description'] ?? null,
        ]);

        return back()->with('success', 'Bonus added successfully.');
    }

    public function processPayroll(Request $request)
    {
        $validated = $request->validate([
            'month' => 'required|date_format:Y-m',
            'employee_id' => 'nullable|exists:employees,id',
        ]);

        $month = $validated['month'];

        $employees = isset($validated['employee_id'])
            ? Employee::where('id', $validated['employee_id'])->get()
            : Employee::orderBy('name')->get();

        $processed = 0;

        foreach ($employees as $employee) {
            $basicSalary = (float) ($employee->salary ?? 0);
            $allowances = (float) Bonus::where('employee_id', $employee->id)
                ->where('month', $month)
                ->sum('amount');
            $deductions = (float) TaxDeduction::where('employee_id', $employee->id)
                ->where('month', $month)
                ->sum('amount');

            // Placeholder for overtime calculation if required in future
            $netSalary = $basicSalary + $allowances - $deductions;

            SalarySlip::updateOrCreate(
                [
                    'employee_id' => $employee->id,
                    'month' => $month,
                ],
                [
                    'basic_salary' => $basicSalary,
                    'allowances' => $allowances,
                    'deductions' => $deductions,
                    'net_salary' => $netSalary,
                    'file_path' => null,
                ]
            );

            $processed++;
        }

        return redirect()->route('finance.payroll.salary-slips', ['month' => $month])
            ->with('success', "Payroll processed for {$processed} employee(s) for {$month}.");
    }
}
