<?php

namespace App\Http\Controllers;

use App\Models\Employee;
use App\Models\User;
use App\Notifications\EmployeeInvitation;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
use Inertia\Inertia;
use Inertia\Response;

class EssAccountController extends Controller
{
    public function index(Request $request): Response
    {
        $employees = Employee::query()
            ->with('user:id,email,invited_at,activated_at')
            ->when($request->string('q')->toString(), function ($query, $q) {
                $query->where(fn ($w) => $w->where('employee_code', 'like', "%{$q}%")
                    ->orWhere('last_name', 'like', "%{$q}%"));
            })
            ->orderBy('employee_code')
            ->paginate(20)
            ->withQueryString()
            ->through(fn (Employee $e) => [
                'id' => $e->id,
                'employee_code' => $e->employee_code,
                'full_name' => $e->full_name,
                'email' => $e->user?->email,
                'status' => $this->status($e),
                'invited_at' => $e->user?->invited_at?->toDateTimeString(),
            ]);

        return Inertia::render('admin/ess-accounts', [
            'employees' => $employees,
            'filters' => ['q' => $request->string('q')->toString()],
            'stats' => [
                'total' => Employee::count(),
                'active' => User::whereNotNull('activated_at')->whereHas('employee')->count(),
                'invited' => User::whereNull('activated_at')->whereNotNull('invited_at')->whereHas('employee')->count(),
                'none' => Employee::whereNull('user_id')->count(),
            ],
        ]);
    }

    /** Set or update the employee's login email (creating the account if needed). */
    public function setEmail(Request $request, Employee $employee): RedirectResponse
    {
        $data = $request->validate([
            'email' => [
                'required', 'email', 'max:255',
                Rule::unique('users', 'email')->ignore($employee->user_id),
            ],
        ]);

        if ($employee->user_id) {
            User::where('id', $employee->user_id)->update(['email' => $data['email']]);
        } else {
            $user = User::create([
                'name' => $employee->full_name ?: $employee->employee_code,
                'email' => $data['email'],
                'password' => Hash::make(Str::random(40)),
                'activated_at' => null,
            ]);
            $user->syncRoles(['EMPLOYEE']);
            $employee->update(['user_id' => $user->id]);
        }

        return back()->with('success', "Email set for {$employee->employee_code}.");
    }

    /** Generate and dispatch an activation invitation; also surface the link. */
    public function invite(Request $request, Employee $employee): RedirectResponse
    {
        $user = $employee->user;
        if (! $user || ! $user->email) {
            return back()->with('error', 'Set an email address first.');
        }
        if ($user->isActivated()) {
            return back()->with('error', 'This account is already active.');
        }

        $url = $user->activationUrl();
        $user->notify(new EmployeeInvitation($url));
        $user->update(['invited_at' => now()]);

        // Mail uses the log driver here, so return the link for manual delivery.
        return back()->with('success', "Invitation sent to {$user->email}. Activation link: {$url}");
    }

    private function status(Employee $e): string
    {
        if (! $e->user_id) {
            return 'No account';
        }
        if ($e->user?->activated_at) {
            return 'Active';
        }
        if ($e->user?->invited_at) {
            return 'Invited';
        }

        return 'Pending';
    }
}
