<?php

namespace App\Http\Controllers\Admin\Module;

use Inertia\Inertia;
use App\Utils\Helper;
use App\Models\Budget;
use App\Enums\BudgetType;
use App\Enums\UserType;
use App\Models\Payment;
use App\Models\UserBank;
use App\Enums\ActionType;
use App\Enums\ModuleType;
use App\Enums\UserBankType;
use App\Models\ApprovalLog;
use Illuminate\Http\Request;
use App\Enums\ActionStatusType;
use App\Http\Services\ApprovalLogService;
use App\Enums\PaymentStatusType;
use App\Enums\UserDepartmentType;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Core\BaseResourceController;

class PaymentRequestController extends BaseResourceController
{
  protected $model = Payment::class;

  protected function getPage(Request $request, $id = null): array
  {
    return [
      "name" => "payment_requests",
      "inertia" => "Admin/Module/PaymentRequest",
      "label" => "Permintaan Pembayaran",
      "url" => "/admin/budgets/{$request->route('budget_id')}/payment_requests",
      "fields" => Helper::getFormFields($this->validation($request)),
    ];
  }

  protected function validation(Request $request, $id = null): array
  {
    return [
      "validation" => [
        "amount" => "required|integer|min:1",
      ],
      "default" => [
        "payment_date" => now()->format('Y-m-d'),
      ],
    ];
  }

  public function index(Request $request)
  {
    $budget = Budget::withPaidAmount()->withPendingPayment()->find($request->route('budget_id'));

    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;

    $page = $this->getPage($request);

    return Inertia::render($page['inertia'] . "/Index", [
      'title' => $page['label'],
      'budget' => $budget,
      'page' => $page
    ]);
  }

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

    DB::beginTransaction();
    try {
      $budget = Budget::withPaidAmount()->find($request->route('budget_id'));

      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;

      $remainingAmount = $budget->paid_remaining_amount;
      $amount = intval($request->amount);

      if ($amount > $remainingAmount) {
        return redirect()->back()->with("error", "Nominal permintaan Rp. " . number_format($amount, 0, ',', '.') . " melebihi sisa dana anggaran Rp. " . number_format($remainingAmount, 0, ',', '.'));
      }

      $maxAmount = $remainingAmount;
      $paymentPercentage = $remainingAmount > 0 ? round(($amount / $remainingAmount) * 100) : 0;

      $userBank = UserBank::where('user_id', $budget->user_id)->where('type', UserBankType::Personal)->first();
      $lastPayment = DB::table("payments")->select("code")->where('budget_id', $budget->id)->latest("id")->whereNotNull('code')->first();
      $code = "INV01";

      if ($lastPayment) {
        $lastCode = explode("/", $lastPayment->code);
        $lastCode = $lastCode[0];

        if ($lastCode) {
          $lastCode = str_replace("INV", "", $lastCode);
          $lastCode = str_pad(intval($lastCode) + 1, 2, "0", STR_PAD_LEFT);
          $code = "INV{$lastCode}";
        }
      }

      $code .= "/{$budget->code}";

      $paymentData = [
        "budget_id" => $budget->id,
        "department_id" => $budget->department_id,
        "company_id" => $budget->company_id,
        "user_bank_id" => $userBank?->id ?? null,
        "code" => $code,
        "amount" => $amount,
        'max_amount' => $maxAmount,
        'payment_percentage' => $paymentPercentage,
        "description" => $budget->name,
        "method" => null,
        "type" => null,
        'payment_date' => now()->toDateTimeString(),
        'due_date' => now()->toDateTimeString(),
        'status' => PaymentStatusType::Pending,
      ];

      $payment = Payment::create($paymentData);
      $payment->save();

      (new ApprovalLogService())->create($request, $payment, ModuleType::Payment, ActionStatusType::Submit, [
        'is_finance' => true,
        'target_finance_department' => true,
        'note' => $request->note
      ]);

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



  protected function getAuthorize(Request $request, $budget = null, $action = null)
  {
    if ($budget?->status?->value !== \App\Enums\BudgetStatusType::Approved) {
      return Helper::redirectBack("error", "Anggaran belum disetujui");
    }

    if ($budget?->type?->value !== BudgetType::CashAdvance) {
      return Helper::redirectBack("error", "Fitur ini hanya tersedia untuk anggaran jenis Pencairan Dana");
    }

    if (intval($budget?->paid_percentage ?? 0) >= 100) {
      return Helper::redirectBack("error", "Anggaran sudah terbayar penuh");
    }

    if ($budget->user_id != auth()->id()) {
      return Helper::redirectBack("error", "Anda tidak diperbolehkan mengajukan permintaan pembayaran pada anggaran ini");
    }
  }

}
