<?php

namespace App\Http\Controllers\Web;

use App\Http\Controllers\Controller;
use App\Http\Requests\Leave\UpdateLeaveTypeAssignmentsRequest;
use App\Http\Requests\Leave\UpdateLeaveTypeRequest;
use App\Http\Requests\Leave\UpdateLeaveTypeRuleRequest;
use App\Models\Department;
use App\Models\LeaveType;
use App\Models\LeaveTypeRule;
use App\Models\Role;
use App\Models\User;
use App\Services\Leave\LeaveEligibilityService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class LeaveTypeManagementController extends Controller
{
    public function index(Request $request, LeaveEligibilityService $eligibility)
    {
        $companyId = Auth::user()?->company_id;

        $leaveTypes = LeaveType::query()->orderBy('name')->get();

        $selectedId = $request->integer('leave_type_id');
        $selected = $selectedId
            ? $leaveTypes->firstWhere('id', $selectedId)
            : $leaveTypes->first();

        $selected = $selected ? LeaveType::with(['rule', 'departments', 'roles', 'users'])->find($selected->id) : null;

        $leaveTypeEmployeeCounts = $leaveTypes->mapWithKeys(function (LeaveType $type) use ($eligibility) {
            return [$type->id => $eligibility->countEligibleUsers($type)];
        });

        $departments = Department::query()->orderBy('name');
        $roles = Role::query()->orderBy('name');
        $users = User::query()->forActiveDirectory()->orderBy('name');

        if ($companyId) {
            $departments->where('company_id', $companyId);
            $roles->where('company_id', $companyId);
            $users->where('company_id', $companyId);
        }

        return view('leave-types.manage', [
            'leaveTypes' => $leaveTypes,
            'selectedLeaveType' => $selected,
            'leaveTypeEmployeeCounts' => $leaveTypeEmployeeCounts,
            'tab' => $request->get('tab', 'general'),
            'departments' => $departments->get(),
            'roles' => $roles->get(),
            'users' => $users->get(),
        ]);
    }

    public function update(LeaveType $leaveType, UpdateLeaveTypeRequest $request)
    {
        $companyId = Auth::user()?->company_id;
        $validated = $request->validated();

        $leaveType->update([
            'company_id' => $leaveType->company_id ?? $companyId,
            'name' => $validated['name'],
            'short_code' => $validated['short_code'] ?: null,
            'description' => $validated['description'] ?: null,
            'leave_count' => $validated['leave_count'] ?? null,
            'is_unlimited' => (bool) ($validated['is_unlimited'] ?? false),
            'weekend_policy' => $validated['weekend_policy'],
            'holiday_policy' => $validated['holiday_policy'],
            'probation_allowed' => (bool) ($validated['probation_allowed'] ?? false),
            'notice_period_allowed' => (bool) ($validated['notice_period_allowed'] ?? false),
            'is_paid' => (bool) ($validated['is_paid'] ?? false),
        ]);

        return redirect()
            ->route('leave-types.manage', ['leave_type_id' => $leaveType->id, 'tab' => 'general'])
            ->with('success', 'Leave type updated successfully.');
    }

    public function updateRules(LeaveType $leaveType, UpdateLeaveTypeRuleRequest $request)
    {
        $companyId = Auth::user()?->company_id;
        $validated = $request->validated();

        LeaveTypeRule::updateOrCreate(
            ['leave_type_id' => $leaveType->id],
            array_merge($validated, [
                'company_id' => $leaveType->company_id ?? $companyId,
                'leave_type_id' => $leaveType->id,
                'carry_forward_enabled' => (bool) ($validated['carry_forward_enabled'] ?? false),
                'pro_rata_on_joining' => (bool) ($validated['pro_rata_on_joining'] ?? true),
                'encashment_enabled' => (bool) ($validated['encashment_enabled'] ?? false),
                'sandwich_rule' => (bool) ($validated['sandwich_rule'] ?? false),
                'requires_attachment' => (bool) ($validated['requires_attachment'] ?? false),
            ])
        );

        return redirect()
            ->route('leave-types.manage', ['leave_type_id' => $leaveType->id, 'tab' => 'advanced'])
            ->with('success', 'Advanced rules updated successfully.');
    }

    public function updateAssignments(LeaveType $leaveType, UpdateLeaveTypeAssignmentsRequest $request)
    {
        $companyId = Auth::user()?->company_id;
        $validated = $request->validated();

        $applyToAll = (bool) ($validated['apply_to_all'] ?? false);

        $leaveType->update([
            'company_id' => $leaveType->company_id ?? $companyId,
            'apply_to_all' => $applyToAll,
        ]);

        $pivotMeta = ['company_id' => $leaveType->company_id ?? $companyId];

        $deptSync = collect($validated['department_ids'] ?? [])->mapWithKeys(fn ($id) => [(int) $id => $pivotMeta])->all();
        $roleSync = collect($validated['role_ids'] ?? [])->mapWithKeys(fn ($id) => [(int) $id => $pivotMeta])->all();
        $userSync = collect($validated['user_ids'] ?? [])->mapWithKeys(fn ($id) => [(int) $id => $pivotMeta])->all();

        $leaveType->departments()->sync($applyToAll ? [] : $deptSync);
        $leaveType->roles()->sync($applyToAll ? [] : $roleSync);
        $leaveType->users()->sync($applyToAll ? [] : $userSync);

        return redirect()
            ->route('leave-types.manage', ['leave_type_id' => $leaveType->id, 'tab' => 'assign'])
            ->with('success', 'Assignments updated successfully.');
    }
}

