<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\ApiBaseController;
use App\Models\StaffMember;
use App\Models\WeekoffRule;
use Examyou\RestAPI\ApiResponse;
use Examyou\RestAPI\Exceptions\ApiException;

class EmployeeWeekoffRuleController extends ApiBaseController
{
    /**
     * Return paginated list of employees alongside their assigned weekoff rule.
     */
    public function index()
    {
        $request = request();

        $perPage = (int)$request->get('per_page', 15);
        $query = StaffMember::with([
            'designation:id,name',
            'department:id,name',
        ])->orderBy('name');

        if ($search = $request->get('search')) {
            $query->where(function ($builder) use ($search) {
                $builder->where('name', 'like', '%' . $search . '%')
                    ->orWhere('employee_number', 'like', '%' . $search . '%')
                    ->orWhere('email', 'like', '%' . $search . '%');
            });
        }

        if ($request->filled('designation_id')) {
            $designationId = $this->getIdFromHash($request->designation_id);
            $query->where('designation_id', $designationId);
        }

        if ($request->filled('department_id')) {
            $departmentId = $this->getIdFromHash($request->department_id);
            $query->where('department_id', $departmentId);
        }

        $paginator = $query->paginate($perPage);

        // Attach current effective weekoff rule per employee (resolved from history)
        $items = collect($paginator->items())->map(function ($employee) {
            $rule = \App\Services\WeekoffService::getEffectiveRule($employee);
            $employee->weekoffRule = $rule ? ['id' => $rule->id, 'name' => $rule->name, 'xid' => $rule->xid] : null;
            return $employee;
        })->all();

        return ApiResponse::make('Employee weekoff rules', $items, [
            'total' => $paginator->total(),
            'per_page' => $paginator->perPage(),
            'current_page' => $paginator->currentPage(),
            'last_page' => $paginator->lastPage(),
        ]);
    }

    /**
     * Assign a weekoff rule to an employee via payload.
     */
    public function store()
    {
        $request = request();
        $this->validate($request, [
            'user_id' => 'required|string',
            'weekoff_rule_id' => 'nullable|string',
        ]);

        $employee = $this->resolveEmployee($request->user_id);
        $rule = $this->resolveWeekoffRule($request->weekoff_rule_id, $employee->company_id);

        // Append to history instead of mutating user directly
        \App\Models\EmployeeWeekoffHistory::create([
            'employee_id' => $employee->id,
            'weekoff_rule_id' => $rule?->id,
            'effective_date' => now()->format('Y-m-d'),
            'assigned_by' => user()?->id,
            'company_id' => $employee->company_id,
        ]);

        return ApiResponse::make('Weekoff rule assigned', [
            'x_user_id' => $employee->xid,
            'weekoff_rule' => $rule ? ['id' => $rule->id, 'name' => $rule->name, 'xid' => $rule->xid] : null,
        ]);
    }

    /**
     * Assign a weekoff rule to an employee via route param.
     */
    public function update(...$args)
    {
        $xid = last($args);
        $request = request();
        $this->validate($request, [
            'weekoff_rule_id' => 'nullable|string',
        ]);

        $employee = $this->resolveEmployee($xid);
        $rule = $this->resolveWeekoffRule($request->weekoff_rule_id, $employee->company_id);

        \App\Models\EmployeeWeekoffHistory::create([
            'employee_id' => $employee->id,
            'weekoff_rule_id' => $rule?->id,
            'effective_date' => now()->format('Y-m-d'),
            'assigned_by' => user()?->id,
            'company_id' => $employee->company_id,
        ]);

        return ApiResponse::make('Weekoff rule assigned', [
            'x_user_id' => $employee->xid,
            'weekoff_rule' => $rule ? ['id' => $rule->id, 'name' => $rule->name, 'xid' => $rule->xid] : null,
        ]);
    }

    /**
     * Remove the weekoff rule from an employee.
     */
    public function destroy(...$args)
    {
        $xid = last($args);
        $employee = $this->resolveEmployee($xid);

        // Appending a null assignment to indicate removal from this date
        \App\Models\EmployeeWeekoffHistory::create([
            'employee_id' => $employee->id,
            'weekoff_rule_id' => null,
            'effective_date' => now()->format('Y-m-d'),
            'assigned_by' => user()?->id,
            'company_id' => $employee->company_id,
        ]);

        return ApiResponse::make('Weekoff rule removed', [
            'x_user_id' => $employee->xid,
        ]);
    }

    protected function resolveEmployee(string $hashId): StaffMember
    {
        $employeeId = $this->getIdFromHash($hashId);

        return StaffMember::findOrFail($employeeId);
    }

    protected function resolveWeekoffRule(?string $hashId, ?int $companyId): ?WeekoffRule
    {
        if (!$hashId) {
            return null;
        }

        $ruleId = $this->getIdFromHash($hashId);

        $rule = WeekoffRule::where('is_active', true)->find($ruleId);

        if (!$rule) {
            throw new ApiException("Weekoff rule not found or inactive.");
        }

        if ($companyId && $rule->company_id !== $companyId) {
            throw new ApiException("Weekoff rule does not belong to the employee's company.");
        }

        return $rule;
    }

    protected function persistAssignment(StaffMember $employee, ?WeekoffRule $rule)
    {
        // Legacy helper removed. Assignment now appends to history via EmployeeWeekoffHistory.
        return ApiResponse::make('Not used', []);
    }
}

