<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Employee;
use App\Models\PayrollPeriod;
use App\Models\PayrollRecord;
use Illuminate\Support\Facades\DB;

class PayrollController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
    }

    public function index(Request $request)
    {
        abort_if(! auth()->user()->canAccess('payroll'), 403);

        $periods = PayrollPeriod::withCount('records')
                                ->orderByDesc('start_date')
                                ->paginate(12)
                                ->withQueryString();

        return view('payroll.index', compact('periods'));
    }

    public function create()
    {
        abort_if(! auth()->user()->isHrOrAdmin(), 403);
        return view('payroll.create');
    }

    public function generate(Request $request)
    {
        abort_if(! auth()->user()->isHrOrAdmin(), 403);

        $request->validate([
            'name'         => 'required|string|max:100',
            'start_date'   => 'required|date',
            'end_date'     => 'required|date|after_or_equal:start_date',
            'payment_date' => 'required|date',
        ]);

        $period = PayrollPeriod::create($request->only([
            'name', 'start_date', 'end_date', 'payment_date',
        ]) + ['status' => 'draft']);

        DB::transaction(function () use ($period) {
            Employee::where('status', 'active')->each(function ($emp) use ($period) {
                $gross   = $emp->salary_usd ?? 0;
                $tax     = round($gross * 0.15, 2);
                $pension = round($gross * 0.05, 2);

                PayrollRecord::create([
                    'period_id'         => $period->id,
                    'employee_id'       => $emp->id,
                    'basic_salary'      => $gross,
                    'gross_pay'         => $gross,
                    'tax_deduction'     => $tax,
                    'pension_deduction' => $pension,
                    'total_deductions'  => $tax + $pension,
                    'net_pay'           => $gross - $tax - $pension,
                    'net_pay_lrd'       => ($gross - $tax - $pension) * 182,
                    'currency'          => 'USD',
                    'status'            => 'draft',
                ]);
            });
        });

        return redirect()->route('payroll.show', $period)
                         ->with('success', 'Payroll generated for all active employees.');
    }

    public function show(PayrollPeriod $payroll)
    {
        abort_if(! auth()->user()->canAccess('payroll'), 403);

        $records = $payroll->records()
                           ->with(['employee.user', 'employee.department'])
                           ->paginate(25);

        $totals = $payroll->records()
                          ->selectRaw('SUM(gross_pay) as total_gross, SUM(net_pay) as total_net, SUM(total_deductions) as total_deductions')
                          ->first();

        return view('payroll.show', compact('payroll', 'records', 'totals'));
    }

    public function approve(PayrollPeriod $payroll)
    {
        abort_if(! auth()->user()->hasRole('super_admin', 'president'), 403);

        $payroll->update(['status' => 'approved', 'approved_by' => auth()->id()]);

        return back()->with('success', 'Payroll approved.');
    }

    public function payslip(PayrollRecord $record)
    {
        $user = auth()->user();

        abort_if(
            ! $user->isManagement() && $user->employee?->id !== $record->employee_id,
            403
        );

        $record->load(['employee.user', 'employee.department', 'period']);

        return view('payroll.payslip', compact('record'));
    }
}
