<?php

namespace App\Http\Controllers;

use App\Models\Banking;
use App\Models\Child;
use App\Models\PendingChange;
use App\Models\Spouse;
use App\Models\Staff;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Inertia\Inertia;
use Inertia\Response;

class PendingChangeController extends Controller
{
    public function index(Request $request): Response
    {
        $user      = Auth::user();
        $companyId = $user->company_id;

        $query = PendingChange::with(['staff', 'staff.company', 'reviewer'])
            ->orderByDesc('created_at');

        if ($user->isCompanyHr() && $companyId) {
            $query->where('company_id', $companyId);
        }

        if ($request->filled('status')) {
            $query->where('status', $request->status);
        } else {
            $query->where('status', 'pending');
        }

        $changes = $query->paginate(20)->withQueryString();

        return Inertia::render('PendingChanges/Index', [
            'changes' => $changes,
            'filters' => $request->only(['status']),
        ]);
    }

    public function approve(Request $request, PendingChange $pendingChange)
    {
        $user = Auth::user();

        if ($user->isCompanyHr() && $user->company_id && $pendingChange->company_id !== $user->company_id) {
            abort(403);
        }

        if ($pendingChange->status !== 'pending') {
            return redirect()->back()->with('error', 'This change has already been reviewed.');
        }

        $data = $request->validate([
            'hr_notes' => 'nullable|string|max:1000',
        ]);

        $this->applyChange($pendingChange);

        $pendingChange->update([
            'status'      => 'approved',
            'hr_notes'    => $data['hr_notes'] ?? null,
            'reviewed_by' => $user->id,
            'reviewed_at' => now(),
        ]);

        return redirect()->back()->with('success', 'Change approved and applied.');
    }

    public function reject(Request $request, PendingChange $pendingChange)
    {
        $user = Auth::user();

        if ($user->isCompanyHr() && $user->company_id && $pendingChange->company_id !== $user->company_id) {
            abort(403);
        }

        if ($pendingChange->status !== 'pending') {
            return redirect()->back()->with('error', 'This change has already been reviewed.');
        }

        $data = $request->validate([
            'hr_notes' => 'nullable|string|max:1000',
        ]);

        $pendingChange->update([
            'status'      => 'rejected',
            'hr_notes'    => $data['hr_notes'] ?? null,
            'reviewed_by' => $user->id,
            'reviewed_at' => now(),
        ]);

        return redirect()->back()->with('success', 'Change rejected.');
    }

    private function applyChange(PendingChange $change): void
    {
        $fields = $change->field_changes;

        switch ($change->table_name) {
            case 'staff':
                Staff::where('id', $change->staff_id)->update($fields);
                break;
            case 'spouses':
                if ($change->record_id) {
                    Spouse::where('id', $change->record_id)->update($fields);
                } else {
                    Spouse::create(array_merge($fields, ['staff_id' => $change->staff_id]));
                }
                break;
            case 'children':
                if ($change->record_id) {
                    Child::where('id', $change->record_id)->update($fields);
                } else {
                    Child::create(array_merge($fields, ['staff_id' => $change->staff_id]));
                }
                break;
            case 'banking':
                if ($change->record_id) {
                    Banking::where('id', $change->record_id)->update($fields);
                } else {
                    Banking::create(array_merge($fields, ['staff_id' => $change->staff_id]));
                }
                break;
        }
    }
}
