<?php

namespace App\Http\Controllers\Web;

use App\Http\Controllers\Controller;
use App\Models\CompanyPolicy;
use App\Models\CompanyPolicyAcknowledgment;
use App\Services\AuditService;
use App\Support\FormTextRules;
use Illuminate\Http\Request;

class CompanyPolicyController extends Controller
{
    public function __construct(
        protected AuditService $audit
    ) {}

    public function index()
    {
        $policies = CompanyPolicy::orderBy('name')->paginate(15);

        return view('company-policies.index', compact('policies'));
    }

    public function portal()
    {
        $policies = CompanyPolicy::query()
            ->where('status', 'active')
            ->orderBy('name')
            ->get();

        $acknowledgedIds = CompanyPolicyAcknowledgment::query()
            ->where('user_id', auth()->id())
            ->pluck('company_policy_id')
            ->all();

        return view('company-policies.portal', compact('policies', 'acknowledgedIds'));
    }

    public function show(CompanyPolicy $companyPolicy)
    {
        $this->assertTenantRecord($companyPolicy);
        abort_unless($companyPolicy->status === 'active' || auth()->user()?->hasPermission('hr_operations_view'), 403);

        $acknowledged = CompanyPolicyAcknowledgment::query()
            ->where('company_policy_id', $companyPolicy->id)
            ->where('user_id', auth()->id())
            ->exists();

        return view('company-policies.show', compact('companyPolicy', 'acknowledged'));
    }

    public function acknowledge(CompanyPolicy $companyPolicy)
    {
        $this->assertTenantRecord($companyPolicy);
        abort_unless($companyPolicy->status === 'active', 404);

        CompanyPolicyAcknowledgment::firstOrCreate(
            [
                'company_policy_id' => $companyPolicy->id,
                'user_id' => auth()->id(),
            ],
            [
                'company_id' => auth()->user()->company_id,
                'acknowledged_at' => now(),
                'ip_address' => request()->ip(),
            ]
        );

        $this->audit->log('company_policy.acknowledged', $companyPolicy);

        return redirect()->route('company-policies.show', $companyPolicy)->with('success', 'Policy acknowledged.');
    }

    public function acknowledgments(CompanyPolicy $companyPolicy)
    {
        $this->assertTenantRecord($companyPolicy);
        abort_unless(auth()->user()?->hasPermission('hr_operations_view'), 403);

        $acknowledgments = CompanyPolicyAcknowledgment::with('user')
            ->where('company_policy_id', $companyPolicy->id)
            ->orderByDesc('acknowledged_at')
            ->paginate(30);

        return view('company-policies.acknowledgments', compact('companyPolicy', 'acknowledgments'));
    }

    public function create()
    {
        return view('company-policies.create');
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'name' => FormTextRules::notNumericOnly(true, 191),
            'description' => FormTextRules::notNumericOnly(false, 1000),
            'content' => FormTextRules::notNumericOnly(false, 65535),
            'status' => 'nullable|in:active,inactive',
        ], FormTextRules::messages());
        $validated['status'] = $validated['status'] ?? 'active';
        $validated['company_id'] = auth()->user()->company_id;

        $policy = CompanyPolicy::create($validated);
        $this->audit->log('company_policy.created', $policy);

        return redirect()->route('company-policies.index')->with('success', 'Policy created successfully.');
    }

    public function edit(CompanyPolicy $companyPolicy)
    {
        $this->assertTenantRecord($companyPolicy);

        return view('company-policies.edit', compact('companyPolicy'));
    }

    public function update(Request $request, CompanyPolicy $companyPolicy)
    {
        $this->assertTenantRecord($companyPolicy);

        $validated = $request->validate([
            'name' => FormTextRules::notNumericOnly(true, 191),
            'description' => FormTextRules::notNumericOnly(false, 1000),
            'content' => FormTextRules::notNumericOnly(false, 65535),
            'status' => 'nullable|in:active,inactive',
        ], FormTextRules::messages());
        $companyPolicy->update($validated);
        $this->audit->log('company_policy.updated', $companyPolicy);

        return redirect()->route('company-policies.index')->with('success', 'Policy updated successfully.');
    }

    public function destroy(CompanyPolicy $companyPolicy)
    {
        $this->assertTenantRecord($companyPolicy);
        $companyPolicy->delete();
        $this->audit->log('company_policy.deleted', null, ['policy_id' => $companyPolicy->id]);

        return redirect()->route('company-policies.index')->with('success', 'Policy deleted.');
    }

    protected function assertTenantRecord(CompanyPolicy $companyPolicy): void
    {
        $companyId = auth()->user()?->company_id;
        if ($companyId && (int) $companyPolicy->company_id !== (int) $companyId) {
            abort(403);
        }
    }
}
