<?php

namespace Modules\MedWorkforce\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Modules\MedWorkforce\Entities\RosterAssignment;
use Modules\MedWorkforce\Entities\SwapRequest;
use Modules\MedWorkforce\Services\RosterService;
use Yajra\DataTables\Facades\DataTables;

/**
 * Swap-request list + approve/reject (SIFA P7-T1). Raising a request needs
 * medwf.roster.manage; approving/rejecting is gated by medwf.swap.approve.
 */
class SwapController extends MedWorkforceBaseController
{
    public function __construct(private RosterService $roster)
    {
    }

    public function index(Request $request)
    {
        $this->guard('medwf.swap.approve');

        if ($request->ajax()) {
            $staff = $this->staff();

            $query = SwapRequest::forBusiness($this->businessId())
                ->with('assignment.template');

            return DataTables::of($query)
                ->addColumn('shift', function ($r) {
                    $a = $r->assignment;
                    if (! $a) {
                        return '-';
                    }
                    $date = $a->date instanceof Carbon ? $a->date->toDateString() : (string) $a->date;
                    $tmpl = $a->template ? $a->template->name : __('medworkforce::lang.custom');

                    return e($date . ' · ' . $tmpl);
                })
                ->addColumn('requested_by_name', fn ($r) => e($staff[$r->requested_by] ?? ('#' . $r->requested_by)))
                ->addColumn('requested_with_name', fn ($r) => e($staff[$r->requested_with_user_id] ?? ('#' . $r->requested_with_user_id)))
                ->editColumn('status', fn ($r) => $this->statusLabel($r->status))
                ->addColumn('action', function ($r) {
                    if ($r->status !== 'pending') {
                        return '<span class="text-muted">' . __('medworkforce::lang.decided') . '</span>';
                    }

                    return '<button class="btn btn-xs btn-success medwf-swap-approve" data-href="'
                        . route('medwf.swaps.approve', $r->id) . '"><i class="fa fa-check"></i> ' . __('medworkforce::lang.approve') . '</button> '
                        . '<button class="btn btn-xs btn-danger medwf-swap-reject" data-href="'
                        . route('medwf.swaps.reject', $r->id) . '"><i class="fa fa-times"></i> ' . __('medworkforce::lang.reject') . '</button>';
                })
                ->rawColumns(['status', 'action'])
                ->make(true);
        }

        return view('medworkforce::swaps.index');
    }

    /** Raise a swap request from the roster (medwf.roster.manage). */
    public function store(Request $request)
    {
        $this->guard('medwf.roster.manage');

        $data = $this->validate($request, [
            'roster_assignment_id'   => 'required|integer',
            'requested_with_user_id' => 'required|integer',
            'reason'                 => 'nullable|string|max:500',
        ]);

        try {
            // The requester is the current holder of the assignment.
            $assignment = RosterAssignment::forBusiness($this->businessId())->findOrFail($data['roster_assignment_id']);

            $this->roster->requestSwap(
                $this->businessId(),
                (int) $assignment->id,
                (int) $assignment->user_id,
                (int) $data['requested_with_user_id'],
                $data['reason'] ?? null
            );

            return $this->ok(__('medworkforce::lang.swap_requested'));
        } catch (\Exception $e) {
            \Log::emergency($e->getMessage());

            return $this->fail();
        }
    }

    public function approve($id)
    {
        $this->guard('medwf.swap.approve');

        try {
            $this->roster->approveSwap($this->businessId(), (int) $id, (int) $this->userId());

            return $this->ok(__('medworkforce::lang.swap_approved'));
        } catch (\Exception $e) {
            \Log::emergency($e->getMessage());

            return $this->fail();
        }
    }

    public function reject($id)
    {
        $this->guard('medwf.swap.approve');

        try {
            $this->roster->rejectSwap($this->businessId(), (int) $id, (int) $this->userId());

            return $this->ok(__('medworkforce::lang.swap_rejected'));
        } catch (\Exception $e) {
            \Log::emergency($e->getMessage());

            return $this->fail();
        }
    }

    private function statusLabel(string $status): string
    {
        $class = [
            'pending'  => 'warning',
            'approved' => 'success',
            'rejected' => 'danger',
            'cancelled' => 'default',
        ][$status] ?? 'default';

        return '<span class="label label-' . $class . '">' . __('medworkforce::lang.swap_status_' . $status) . '</span>';
    }
}
