<?php

namespace App\Http\Controllers;

use App\Models\BonusDisbursement;
use App\Models\Branch;
use App\Models\Product;
use App\Models\User;
use App\Services\BonusService;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;

class BonusController extends Controller
{
    public function index(Request $request, BonusService $bonusService)
    {
        $start = $request->input('start_date', now()->startOfMonth()->toDateString());
        $end = $request->input('end_date', now()->toDateString());
        $branchId = $request->user()->isOwner() ? $request->integer('branch_id') : $request->user()->branch_id;
        $staffId = $request->integer('staff_id') ?: null;

        if (! $request->user()->hasRole('owner', 'admin_cabang', 'manager')) {
            $staffId = $request->user()->id;
        }

        return view('bonuses.index', [
            'start' => $start,
            'end' => $end,
            'branchId' => $branchId,
            'staffId' => $staffId,
            'branches' => Branch::query()->where('is_active', true)->orderBy('name')->get(),
            'staff' => User::query()
                ->when($branchId, fn ($q) => $q->where('branch_id', $branchId))
                ->whereIn('role', ['owner', 'admin_cabang', 'manager', 'kasir'])
                ->orderBy('name')
                ->get(),
            'details' => $bonusService->payableDetails($branchId, $start, $end, $staffId),
            'summary' => $bonusService->summaryByStaff($branchId, $start, $end),
            'disbursements' => BonusDisbursement::query()
                ->with(['staff', 'branch', 'disburser'])
                ->when($branchId, fn ($q) => $q->where('branch_id', $branchId))
                ->latest()
                ->limit(20)
                ->get(),
        ]);
    }

    public function settings()
    {
        return view('bonuses.settings', [
            'products' => Product::query()->orderBy('type')->orderBy('name')->get(),
        ]);
    }

    public function updateSettings(Request $request)
    {
        $data = $request->validate([
            'products' => ['required', 'array'],
            'products.*.bonus_type' => ['required', Rule::in(['none', 'percent', 'nominal'])],
            'products.*.bonus_base' => ['required', Rule::in(['sales', 'margin'])],
            'products.*.bonus_value' => ['required', 'numeric', 'min:0'],
        ]);

        foreach ($data['products'] as $productId => $payload) {
            Product::query()->whereKey($productId)->update([
                'bonus_type' => $payload['bonus_type'],
                'bonus_base' => $payload['bonus_base'],
                'bonus_value' => $payload['bonus_value'],
            ]);
        }

        return back()->with('status', 'Pengaturan bonus berhasil disimpan.');
    }

    public function disburse(Request $request, BonusService $bonusService)
    {
        $data = $request->validate([
            'branch_id' => ['required', 'exists:branches,id'],
            'staff_id' => ['nullable', 'exists:users,id'],
            'start_date' => ['required', 'date'],
            'end_date' => ['required', 'date'],
            'note' => ['nullable', 'string', 'max:1000'],
        ]);

        abort_unless($request->user()->isOwner() || $request->user()->canAccessBranch((int) $data['branch_id']), 403);

        $disbursement = $bonusService->disburse(
            $request->user(),
            (int) $data['branch_id'],
            $data['start_date'],
            $data['end_date'],
            $data['staff_id'] ? (int) $data['staff_id'] : null,
            $data['note'] ?? null,
        );

        return redirect()->route('bonuses.disbursements.show', $disbursement)->with('status', 'Bonus berhasil dicairkan.');
    }

    public function showDisbursement(BonusDisbursement $bonusDisbursement)
    {
        abort_unless(auth()->user()->isOwner() || auth()->user()->canAccessBranch($bonusDisbursement->branch_id), 403);

        return view('bonuses.disbursement', [
            'disbursement' => $bonusDisbursement->load(['branch', 'staff', 'disburser', 'expense', 'items.orderDetail.order', 'items.orderDetail.staff']),
        ]);
    }
}
