<?php

namespace App\Http\Controllers;

use App\Models\Site;
use App\Models\Staff;
use Illuminate\Http\Request;

/**
 * First-setup screen: after importing the masterlist, admins must complete each
 * worker's passport details, permit details and photo. This lists what's missing.
 */
class SetupController extends Controller
{
    /** Filters → human labels shown as tabs. */
    public const CHECKS = [
        'photo'           => 'Missing photo',
        'passport_no'     => 'Missing passport no.',
        'passport_expiry' => 'Missing passport expiry',
        'permit_expiry'   => 'Missing permit expiry',
        'passport_doc'    => 'No passport scan',
        'permit_doc'      => 'No permit scan',
    ];

    public function index(Request $request)
    {
        $this->authorizeManage();

        $check  = $request->get('check', 'photo');
        $siteId = $request->get('site_id');

        $base = fn () => Staff::where('status', '!=', 'resign');

        // Counts for every check (drives the tab badges).
        $counts = [
            'photo'           => (clone $base())->whereNull('photo_path')->count(),
            'passport_no'     => (clone $base())->whereNull('passport_no')->count(),
            'passport_expiry' => (clone $base())->whereNull('passport_expiry')->count(),
            'permit_expiry'   => (clone $base())->whereNull('permit_expiry')->count(),
            'passport_doc'    => (clone $base())->whereDoesntHave('documents', fn ($q) => $q->where('type', 'passport'))->count(),
            'permit_doc'      => (clone $base())->whereDoesntHave('documents', fn ($q) => $q->where('type', 'permit'))->count(),
        ];

        $query = $base()->with(['site', 'nationality']);
        $this->applyCheck($query, $check);

        if ($siteId) {
            $query->where('site_id', $siteId);
        }

        $staff = $query->orderBy('name')->paginate(25)->withQueryString();

        $total    = Staff::where('status', '!=', 'resign')->count();
        $complete = Staff::where('status', '!=', 'resign')
            ->whereNotNull('photo_path')->whereNotNull('passport_no')
            ->whereNotNull('passport_expiry')->whereNotNull('permit_expiry')
            ->count();

        return view('setup.index', [
            'staff'    => $staff,
            'counts'   => $counts,
            'check'    => $check,
            'sites'    => Site::orderBy('name')->get(),
            'siteId'   => $siteId,
            'total'    => $total,
            'complete' => $complete,
            'percent'  => $total > 0 ? (int) round($complete / $total * 100) : 0,
        ]);
    }

    /** One-shot completion of a worker's passport, permit and photo. */
    public function complete(Request $request, Staff $staff)
    {
        $this->authorizeManage();

        $data = $request->validate([
            'passport_no'     => ['nullable', 'string', 'max:100', "unique:staff,passport_no,{$staff->id}"],
            'passport_expiry' => ['nullable', 'date'],
            'permit_expiry'   => ['nullable', 'date'],
            'fomema_expiry'   => ['nullable', 'date'],
            'photo'           => ['nullable', 'image', 'max:5120'],
            'passport_file'   => ['nullable', 'file', 'max:10240'],
            'permit_file'     => ['nullable', 'file', 'max:10240'],
        ]);

        $attrs = collect($data)->only([
            'passport_no', 'passport_expiry', 'permit_expiry', 'fomema_expiry',
        ])->filter(fn ($v) => $v !== null && $v !== '')->all();

        if ($request->hasFile('photo')) {
            if ($staff->photo_path) {
                \Illuminate\Support\Facades\Storage::disk('private')->delete($staff->photo_path);
            }
            $attrs['photo_path'] = $request->file('photo')->store("staff/{$staff->id}/photo", 'private');
        }

        if ($request->filled('passport_no') || $request->hasFile('passport_file')) {
            $attrs['has_passport'] = true;
        }

        $staff->update($attrs);

        $this->storeScan($request, $staff, 'passport_file', 'passport', 'Passport', $staff->passport_expiry);
        $this->storeScan($request, $staff, 'permit_file', 'permit', 'Work Permit', $staff->permit_expiry);

        return back()->with('success', "{$staff->name} updated.");
    }

    private function storeScan(Request $request, Staff $staff, string $field, string $type, string $title, $expiry): void
    {
        if (! $request->hasFile($field)) {
            return;
        }

        $file = $request->file($field);
        $staff->documents()->create([
            'type'          => $type,
            'title'         => $title,
            'expiry_date'   => $expiry,
            'path'          => $file->store("documents/{$staff->id}", 'private'),
            'original_name' => $file->getClientOriginalName(),
            'mime'          => $file->getClientMimeType(),
            'uploaded_by'   => auth()->id(),
        ]);
    }

    private function applyCheck($query, string $check): void
    {
        match ($check) {
            'passport_no'     => $query->whereNull('passport_no'),
            'passport_expiry' => $query->whereNull('passport_expiry'),
            'permit_expiry'   => $query->whereNull('permit_expiry'),
            'passport_doc'    => $query->whereDoesntHave('documents', fn ($q) => $q->where('type', 'passport')),
            'permit_doc'      => $query->whereDoesntHave('documents', fn ($q) => $q->where('type', 'permit')),
            default           => $query->whereNull('photo_path'),
        };
    }

    private function authorizeManage(): void
    {
        abort_unless(auth()->user()->isAdmin() || auth()->user()->isSupervisor(), 403);
    }
}
