<?php

namespace App\Http\Controllers\Admin;

use App\Models\User;
use App\Utils\Helper;
use App\Enums\UserType;
use App\Models\Company;
use App\Models\Department;
use Illuminate\Http\Request;
use App\Enums\OriginStatusType;
use App\Http\Controllers\Core\BaseResourceController;

class DepartmentController extends BaseResourceController
{
  protected $model = Department::class;

  protected function indexQuery($query, Request $request)
  {
    $query->when($request->filled("status"), fn($q) => $q->where("status", $request->status));
    $query->with("user:id,name", "company");
    $query->withCount("userDepartments");

    return $query;
  }

  protected function getPage(Request $request, $id = null): array
  {
    $page = [
      "name" => "departments",
      "inertia" => "Admin/Department",
      "label" => "Departemen",
      "url" => "/admin/departments",
      "fields" => Helper::getFormFields($this->validation($request)),
    ];

    return $page;
  }

  protected function validation(Request $request, $id = null): array
  {
    return [
      "validation" => [
        "user_id" => "nullable|integer|exists:users,id",
        "name" => "required|string",
        "code" => "nullable|string|unique:departments,code," . $id,
        "status" => "required|string",
        "details" => "required|array",
        "is_finance" => "required|boolean",
      ],
      "detail_validation" => [
        "details.*.manager_id" => "required|exists:users,id",
        "details.*.user_id" => "nullable|array",
        "details.*.user_id.*.value" => "nullable|exists:users,id",
      ],
      "default" => [
        "is_finance" => false,
        "status" => \App\Enums\OriginStatusType::Active,
      ],
    ];
  }

  protected function getFormData(Request $request, $model = null): array
  {
    $defaultValues = ["user_id", "is_finance"];

    if (!empty($model)) {
      $array = collect($model->toArray())->only($defaultValues)->toArray();
      $request->merge([...$array, ...$request->all()]);
    }

    $userId = $request->user_id;
    if (in_array(auth()->user()->role, [UserType::Director])) {
      $userId = auth()->id();
    }

    $directors = [];
    if ($this->isAdmin) {
      $directors = User::selectOptions()
        ->where("status", OriginStatusType::Active)
        ->where("role", UserType::Director)
        ->get();
    }

    $managers = [];
    if ($userId) {
      $managers = User::selectOptions()
        ->where("status", OriginStatusType::Active)
        ->whereIn("role", [UserType::Manager])
        ->get();
    }

    $members = [];
    if ($userId) {
      $members = User::selectOptions()
        ->where("status", OriginStatusType::Active)
        ->whereIn("role", [UserType::User])
        ->get();
    }

    if (!empty($this->modelInstance) && $this->isFormPage) {
      $this->modelInstance = $this->modelInstance->load(["managers" => ["user:id,name", "members.user:id,name"]]);
      $this->modelInstance->details = $this->modelInstance->managers->map(function ($model) {
        return [
          "manager_id" => $model->user->id,
          "user_id" => $model->members->map(function ($model) {
            return [
              "value" => $model->user->id,
              "label" => $model->user->name,
            ];
          }),
        ];
      });
    }

    $data = [
      "status" => OriginStatusType::getValues(),
      "page" => $this->page,
      "directors" => $directors,
      "managers" => $managers,
      "members" => $members,
      "isAdmin" => $this->isAdmin,
    ];
    return $data;
  }

  protected function beforeSave(array $validatedData, Request $request): array
  {
    $company = Company::active($request)->first();
    $validatedData['company_id'] = $company->id;
    $user = auth()->user();
    if (!in_array($user->role, [UserType::PresidentDirector])) {
      $validatedData['user_id'] = $user->id;
    }

    if (!$this->isEdit) {
      $validatedData["code"] = substr($validatedData["name"], 0, 3);
      $validatedData["code"] = strtoupper($validatedData["code"]);
    }

    $existCode = Department::where('code', $validatedData['code'])->first();
    if ($existCode) {
      $validatedData['code'] = $validatedData['code'] . "-" . rand(1, 100);
    }

    unset($validatedData['details']);
    return $validatedData;
  }

  protected function afterSave($model, Request $request)
  {
    if (!$request->has('details') || !is_array($request->details))
      return;

    $userDepartments = [
      [
        "user_id" => $model->user_id,
        "manager_id" => null,
        "type" => UserType::Director,
      ]
    ];

    foreach ($request->details as $detailGroup) {
      $managerId = $detailGroup['manager_id'];
      $userIds = $detailGroup['user_id'];

      $userDepartments[] = [
        "user_id" => $managerId,
        "manager_id" => null,
        "type" => UserType::Manager,
      ];

      foreach ($userIds as $userId) {
        $userDepartments[] = [
          "user_id" => $userId['value'],
          "manager_id" => $managerId,
          "type" => UserType::User,
        ];
      }
    }

    $model->userDepartments()->delete();
    $model->userDepartments()->createMany($userDepartments);
  }
}
