<?php

namespace App\Http\Controllers\Admin\Module;

use App\Utils\Helper;
use App\Models\Budget;
use App\Models\Category;
use App\Enums\ActionType;
use Illuminate\Http\Request;
use App\Models\BudgetCategory;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Core\BaseResourceController;
use App\Http\Services\BudgetApprovalService;

class BudgetApprovalController extends BaseResourceController
{
  protected $model = BudgetCategory::class;

  protected function indexQuery($query, Request $request)
  {
    $query->with(['budgetDetails.quantityUnits.unitType', 'category']);
    $query->when($request->filled("category_id"), fn($q) => $q->whereRelation("category", "id", $request->category_id));

    return $query;
  }

  protected function indexData(Request $request, $isFormData = true): array
  {
    $budgetId = $request->route('budget_id');
    $categories = Category::selectOptions()
      ->where('status', \App\Enums\OriginStatusType::Active)
      ->whereRelation('budgetCategories', 'budget_id', $budgetId)
      ->get();

    $budgetCategorySumQuery = clone $this->mainQuery;
    $budgetCategorySum = $budgetCategorySumQuery->select([
      DB::raw("
            COALESCE(SUM(price_amount_total), 0)  AS price_amount_total
        "),
    ])
      ->first();

    $budgetCategorySum = [
      "price_amount_total" => intval($budgetCategorySum->price_amount_total ?? 0),
    ];

    $budget = Budget::with([
      "latestApprovalLog.children.budgetDetail"
    ])->find($budgetId);

    $approvalLog = $budget->latestApprovalLog;
    $budgetDetailRevisions = $approvalLog->children->map(fn($item) => $item->budgetDetail)->flatten(1)->filter();

    return [
      'budget' => $budget,
      'categories' => $categories,
      'budgetCategorySum' => $budgetCategorySum,
      'approvalLog' => $approvalLog,
      'budgetDetailRevisions' => $budgetDetailRevisions,
    ];
  }

  protected function getPage(Request $request, $id = null): array
  {
    $page = [
      "name" => "budget_approvals",
      "inertia" => "Admin/Module/BudgetApproval",
      "label" => "Approval Anggaran",
      "url" => "/admin/budgets/{$request->route('budget_id')}/budget_approvals",
      "fields" => Helper::getFormFields($this->validation($request)),
    ];

    return $page;
  }

  public function store(Request $request)
  {
    $request->validate($this->validation($request)['validation']);

    DB::beginTransaction();
    try {
      $budget = Budget::withUserAction()
        ->where('id', $request->route('budget_id'))
        ->first();

      if (!$budget)
        return redirect()->back()->with("error", "Data anggaran tidak ditemukan");

      $authorize = $this->getAuthorize($request, $budget, ActionType::Create);
      if ($authorize instanceof \Illuminate\Http\RedirectResponse)
        return $authorize;

      (new BudgetApprovalService())->approve($request, $budget);

      DB::commit();
      return redirect("/admin/budgets")->with('success', "Anggaran {$budget->name} berhasil disetujui");
    } catch (\Exception $e) {
      DB::rollBack();
      return redirect()->back()->with('error', 'Terjadi kesalahan: ' . $e->getMessage());
    }
  }

  protected function validation(Request $request, $id = null): array
  {
    return [
      "validation" => [
        "custom_note" => "nullable|string",
        "budget_categories" => "required|array",
        "budget_categories.*.category_id" => "required",
        "budget_categories.*.budget_details" => "required|array",
        "budget_categories.*.budget_details.*.id" => "required|exists:budget_details,id",
        "budget_categories.*.budget_details.*.is_approved" => "nullable|boolean",
        "budget_categories.*.budget_details.*.is_revision" => "nullable|boolean",
        "budget_categories.*.budget_details.*.is_rejected" => "nullable|boolean",
        "budget_categories.*.budget_details.*.status_message" => "required_if:budget_categories.*.budget_details.*.is_rejected,1|required_if:budget_categories.*.budget_details.*.is_revision,1",
      ],
      "default" => [],
    ];
  }

  protected function getAuthorize(Request $request, $budget = null, $action = ActionType::Read)
  {
    $user = auth()->user();
    if ($budget->approval_level != $user->role)
      return Helper::redirectBack("error", "Anda belum memiliki hak akses untuk menyetujui anggaran ini");

    return true;
  }

  protected function indexValidation(Request $request)
  {
    $budget = Budget::withUserAction()
      ->where('id', $request->route('budget_id'))
      ->first();

    if (!$budget)
      return redirect()->back()->with("error", "Data anggaran tidak ditemukan");

    return $this->getAuthorize($request, $budget, ActionType::Read);
  }
}
