<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Role;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rule;

class StaffController extends Controller
{
    public function index()
    {
        $staff = User::where('shop_id', $this->shopId())
            ->where('type_id', 3)
            ->with('role')
            ->latest()
            ->get();

        return view('admin.staff.index', compact('staff'));
    }

    public function create()
    {
        $roles = Role::where('shop_id', $this->shopId())->get();

        return view('admin.staff.form', ['staffMember' => new User(), 'roles' => $roles]);
    }

    public function store(Request $request)
    {
        $data = $this->validated($request);

        User::create([
            'name' => $data['name'],
            'staff_code' => $this->generateStaffCode(),
            'phone' => $data['phone'],
            'password' => Hash::make($data['password']),
            'type_id' => 3,
            'shop_id' => $this->shopId(),
            'role_id' => $data['role_id'] ?? null,
            'is_active' => $request->boolean('is_active', true),
        ]);

        return redirect()->route('shop.staff.index')->with('status', 'Staff added.');
    }

    public function edit(User $staffMember)
    {
        $this->authorizeShop($staffMember);

        $roles = Role::where('shop_id', $this->shopId())->get();

        return view('admin.staff.form', compact('staffMember', 'roles'));
    }

    public function update(Request $request, User $staffMember)
    {
        $this->authorizeShop($staffMember);

        $data = $this->validated($request, $staffMember->id);

        $staffMember->update([
            'name' => $data['name'],
            'phone' => $data['phone'],
            'role_id' => $data['role_id'] ?? null,
            'is_active' => $request->boolean('is_active', true),
            ...(filled($data['password'] ?? null) ? ['password' => Hash::make($data['password'])] : []),
        ]);

        return redirect()->route('shop.staff.index')->with('status', 'Staff updated.');
    }

    public function destroy(User $staffMember)
    {
        $this->authorizeShop($staffMember);

        $staffMember->delete();

        return back()->with('status', 'Staff removed.');
    }

    protected function shopId(): int
    {
        return Auth::guard('admin')->user()->shop_id;
    }

    protected function authorizeShop(User $staffMember): void
    {
        abort_unless(
            $staffMember->shop_id === $this->shopId() && $staffMember->type_id === 3,
            403
        );
    }

    protected function generateStaffCode(): string
    {
        $shop = Auth::guard('admin')->user()->shop;
        $prefix = strtoupper(substr(preg_replace('/[^A-Za-z]/', '', $shop->name), 0, 2));
        $prefix = $prefix ?: 'ST';

        $lastCode = User::where('shop_id', $this->shopId())
            ->where('staff_code', 'like', "{$prefix}-%")
            ->orderByRaw('CAST(SUBSTRING(staff_code, 4) AS UNSIGNED) DESC')
            ->value('staff_code');

        $nextNumber = 1;
        if ($lastCode) {
            $lastNumber = (int) substr($lastCode, strlen($prefix) + 1);
            $nextNumber = $lastNumber + 1;
        }

        return $prefix . '-' . str_pad($nextNumber, 4, '0', STR_PAD_LEFT);
    }

    protected function validated(Request $request, $ignoreId = null): array
    {
        return $request->validate([
            'name' => 'required|string|max:255',
            'phone' => 'required|string|max:20|unique:users,phone' . ($ignoreId ? ",{$ignoreId}" : ''),
            'password' => $ignoreId ? 'nullable|min:6' : 'required|min:6',
            'role_id' => ['nullable', Rule::exists('roles', 'id')->where('shop_id', $this->shopId())],
            'is_active' => 'boolean',
        ]);
    }
}
