<?php

namespace App\Http\Controllers\Web;

use App\Http\Controllers\Controller;
use App\Models\Complaint;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\Rule;

class ComplaintController extends Controller
{
    public function index(Request $request)
    {
        $user = Auth::user();
        $canManage = $this->canManageAllComplaints($user);

        $query = Complaint::with(['fromUser', 'againstUser']);
        if (! $canManage) {
            $query->where('from_user_id', $user->id);
        }
        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }
        $complaints = $query->orderByDesc('complaint_date')->paginate(15)->withQueryString();

        return view('hr.complaints', compact('complaints', 'canManage'));
    }

    public function create()
    {
        $user = Auth::user();
        $canManage = $this->canManageAllComplaints($user);
        $users = $this->companyUsersQuery()->orderBy('name')->get();

        return view('hr.complaints-create', compact('users', 'canManage'));
    }

    public function store(Request $request)
    {
        $user = Auth::user();
        $canManage = $this->canManageAllComplaints($user);
        $companyId = $user->company_id;
        if (! $companyId) {
            abort(403, 'Company not found.');
        }

        $rules = [
            'against_user_id' => [
                'nullable',
                Rule::exists('users', 'id')->where(fn ($q) => $q->where('company_id', $companyId)),
            ],
            'subject' => 'required|string|max:191',
            'description' => 'nullable|string|max:2000',
            'complaint_date' => 'required|date',
            'status' => 'nullable|in:pending,under_review,resolved,rejected',
        ];

        if ($canManage) {
            $rules['from_user_id'] = [
                'required',
                Rule::exists('users', 'id')->where(fn ($q) => $q->where('company_id', $companyId)),
            ];
        }

        $validated = $request->validate($rules);

        if (! $canManage) {
            $validated['from_user_id'] = $user->id;
            $validated['status'] = 'pending';
        } else {
            $validated['status'] = $validated['status'] ?? 'pending';
        }

        $validated['company_id'] = $companyId;
        Complaint::create($validated);

        return redirect()->route('complaints.index')->with('success', 'Complaint recorded successfully.');
    }

    public function edit(Complaint $complaint)
    {
        $this->authorizeComplaint($complaint);
        $users = $this->companyUsersQuery()->orderBy('name')->get();

        return view('hr.complaints-edit', compact('complaint', 'users'));
    }

    public function update(Request $request, Complaint $complaint)
    {
        $this->authorizeComplaint($complaint);
        $companyId = Auth::user()?->company_id;
        $validated = $request->validate([
            'from_user_id' => [
                'required',
                Rule::exists('users', 'id')->where(fn ($q) => $q->where('company_id', $companyId)),
            ],
            'against_user_id' => [
                'nullable',
                Rule::exists('users', 'id')->where(fn ($q) => $q->where('company_id', $companyId)),
            ],
            'subject' => 'required|string|max:191',
            'description' => 'nullable|string|max:2000',
            'complaint_date' => 'required|date',
            'status' => 'required|in:pending,under_review,resolved,rejected',
            'resolution_notes' => 'nullable|string|max:2000',
        ]);

        if ($validated['status'] === 'resolved' && empty(trim((string) ($validated['resolution_notes'] ?? '')))) {
            return back()->withInput()->withErrors([
                'resolution_notes' => 'Resolution notes are required when marking as resolved.',
            ]);
        }

        $complaint->update($validated);

        return redirect()->route('complaints.index')->with('success', 'Complaint updated successfully.');
    }

    public function destroy(Complaint $complaint)
    {
        $this->authorizeComplaint($complaint);
        $complaint->delete();

        return redirect()->route('complaints.index')->with('success', 'Complaint deleted successfully.');
    }

    protected function canManageAllComplaints(?User $user): bool
    {
        if (! $user) {
            return false;
        }

        if ($user->isCompanyAccountAdmin()) {
            return true;
        }

        return $user->hasPermission('hr_operations_view');
    }

    protected function companyUsersQuery()
    {
        $query = User::forActiveDirectory();
        if (auth()->user()?->company_id) {
            $query->where('company_id', auth()->user()->company_id);
        }

        return $query;
    }

    protected function authorizeComplaint(Complaint $complaint): void
    {
        $user = Auth::user();
        $companyId = $user?->company_id;
        if ($companyId && $complaint->company_id !== $companyId) {
            abort(403);
        }

        if (! $this->canManageAllComplaints($user) && $complaint->from_user_id !== $user?->id) {
            abort(403, 'You can only access your own complaints.');
        }
    }
}
