<?php

namespace App\Http\Controllers\Admin;

use Carbon\Carbon;
use Inertia\Inertia;
use App\Utils\Helper;
use App\Enums\UserType;
use App\Models\Patient;
use App\Enums\ActionType;
use App\Enums\GenderType;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use App\Enums\PublishStatusType;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use App\Http\Services\SoftDeleteService;

class PatientController extends Controller
{
  public $adminRole = [UserType::Admin];
  public $isAdmin = false;
  public $page = null;

  public function __construct()
  {
    $this->middleware(function ($request, $next) {
      $user = auth()->user();
      $this->page = $this->getPage($request);
      $this->isAdmin = $user && in_array($user->role, $this->adminRole);
      return $next($request);
    });
  }

  public function index(Request $request)
  {
    $patients = Patient::when($request->filled("status"), function ($query) use ($request) {
      $query->where("status", $request->status);
    })
      ->filter($request)
      ->paginate(20);

    $data = [
      "title" => "{$this->page["label"]}",
      "status" => PublishStatusType::getValues(),
      "page" => $this->page,
      "patients" => collect($patients),
      "isAdmin" => $this->isAdmin,
    ];

    return Inertia::render("Admin/Patient/Index", $data);
  }

  protected function getFormData($request, $patient = null)
  {
    $page = $this->getPage($request);
    $data = [
      "isAdmin" => $this->isAdmin,
      "page" => $page,
      "gender" => GenderType::getValues(),
    ];

    return $data;
  }

  public function create(Request $request)
  {
    $formData = $this->getFormData($request);
    $data = [...$formData, "title" => "Tambah {$this->page["label"]}"];

    return Inertia::render("Admin/Patient/Create", $data);
  }

  public function edit($id, Request $request)
  {
    $patient = Patient::where("id", $id)->first();
    $authorize = $this->getAuthorize($request, $patient, ActionType::Update);
    if ($authorize instanceof \Illuminate\Http\RedirectResponse) {
      return $authorize;
    }

    $formData = $this->getFormData($request, $patient);

    $data = [...$formData, "title" => "Edit {$this->page["label"]}", $this->page["name"] => $patient];

    return Inertia::render("Admin/Patient/Edit", $data);
  }

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

    DB::beginTransaction();
    try {
      $validationResult = $this->processValidateData($validatedData, $request);
      if ($validationResult instanceof \Illuminate\Http\RedirectResponse) {
        return $validationResult;
      }

      [$validatedData] = $validationResult;
      Patient::create($validatedData);

      DB::commit();
      return redirect(\App\Utils\Helper::getRefurl(request()) ?? $this->page["url"])->with("success", "Tambah {$this->page["label"]} Baru Berhasil");
    } catch (\Throwable $th) {
      DB::rollBack();
      return redirect()
        ->back()
        ->with("error", "Tambah {$this->page["label"]} Baru Gagal. Kesalahan sistem internal");
    }
  }

  public function update($id, Request $request)
  {
    if ($request->restore_data == '1') return SoftDeleteService::restore("patients", $id, $this->page);
    $validatedData = $request->validate($this->validation($request, $id)["validation"]);

    DB::beginTransaction();
    try {
      $patient = Patient::where("id", $id)->first();

      $authorize = $this->getAuthorize($request, $patient, ActionType::Update);
      if ($authorize instanceof \Illuminate\Http\RedirectResponse) {
        return $authorize;
      }

      $validationResult = $this->processValidateData($validatedData, $request);
      if ($validationResult instanceof \Illuminate\Http\RedirectResponse) {
        return $validationResult;
      }

      [$validatedData] = $validationResult;
      $patient->update($validatedData);

      DB::commit();
      return redirect(\App\Utils\Helper::getRefurl(request()) ?? $this->page["url"])->with("success", "Update {$this->page["label"]} Berhasil");
    } catch (\Throwable $th) {
      DB::rollBack();
      return redirect()
        ->back()
        ->with("error", "Update {$this->page["label"]} Gagal. Kesalahan sistem internal");
    }
  }

  protected function processValidateData($validatedData, $request)
  {
    $validatedData['user_id'] = auth()->id();
    return [$validatedData];
  }

  public function destroy($id, Request $request)
  {
    DB::beginTransaction();
    try {
      $patient = Patient::where("id", $id)->first();

      $authorize = $this->getAuthorize($request, $patient, ActionType::Delete);
      if ($authorize instanceof \Illuminate\Http\RedirectResponse) {
        return $authorize;
      }

      $message = "Hapus {$this->page["label"]} Berhasil";
      $patient->delete();

      DB::commit();
      return redirect(\App\Utils\Helper::getRefurl(request()) ?? $this->page["url"])->with("success", $message);
    } catch (\Throwable $th) {
      DB::rollBack();
      return redirect()
        ->back()
        ->with("error", "Hapus {$this->page["label"]} Gagal. {$this->page["label"]} ini masih digunakan oleh fitur lain");
    }
  }

  protected function getAuthorize($request, $data = null, $action = ActionType::Read)
  {
    $user = auth()->user();
    if ($user->role == UserType::Admin) {
      return true;
    }

    $actionLabels = Helper::getEnumTranslation(ActionType::class, "id");
    $forbiddenMessage = "Anda tidak diperbolehkan {$actionLabels[$action]} {$this->page["label"]} ini";

    return Helper::redirectBack("error", $forbiddenMessage);
  }

  protected function getPage($request, $id = null)
  {
    $fields = \App\Utils\Helper::getFormFields($this->validation($request));

    $page = [
      "name" => "patients",
      "label" => "Data Pasien",
      "url" => "/admin/patients",
      "data" => null,
      "fields" => $fields,
    ];

    return $page;
  }

  protected function validation($request, $id = null)
  {
    return [
      "validation" => [
        'name' => 'required|string',
        'address' => 'required|string',
        'phone' => 'required|string',
        'birth_date' => 'required|date',
        'gender' => 'required|string',
        'medical_history' => 'nullable',
        'medication_allergy' => 'nullable',
      ],
      "default" => [],
    ];
  }
}
