<?php

namespace App\Traits;

use Illuminate\Http\JsonResponse;
use Illuminate\Http\Response;


trait DeleteGuarded
{
    protected $delete_error = "";

    /**
     * Attempt to delete a model instance with possible relationships
     * @return Response | JsonResponse
     */
    public function attemptDelete(): Response|JsonResponse
    {
        if ($this->shouldPreventDelete()) {
            return response()->unprocessable($this->delete_error);
        }

        if ($this->hasAffectedRelationships()) {
            return response()->accepted($this->delete_error);
        }

        $this->deleteNonStandaloneChildren();
        static::delete();
        return response()->deleted();
    }

    /**
     * Check if deletion should be prevented for the model
     * @return bool
     */
    protected function shouldPreventDelete(): bool
    {
        $relationships = static::DELETE_PREVENTING_RELATIONSHIPS;

        foreach ($relationships as $relationship) {
            $relationship_name = $relationship['name'];
            $count = $this->{$relationship_name}()->count();

            if ($count > 0) {
                $message = str_replace(':count', $count, $relationship['message']);
                $this->delete_error = $message;
                return true;
            }
        }

        return false;
    }

    /**
     * Check if relationships will be affected by deletion unaware
     * @return bool
     */
    protected function hasAffectedRelationships(): bool
    {
        $affected_relationships = static::DELETE_AFFECTED_RELATIONSHIPS;

        $confirmed = request('confirmed');
        if (!$confirmed) {
            $error_messages = [];
            foreach ($affected_relationships as $affected_relationship) {
                $relationship_name = $affected_relationship['name'];
                $count = $this->{$relationship_name}()->count();
                if ($count > 0) {
                    $message = str_replace(':count', $count, $affected_relationship['message']);
                    $error_messages[] = $message;
                }
            }

            if (count($error_messages) > 0) {
                $this->delete_error = implode(',', $error_messages);
                return true;
            }
        }

        foreach ($affected_relationships as $affected_relationship) {
            $action = $affected_relationship['action'];
            $this->{$action}();
        }

        return false;
    }

    /**
     * Delete all the child relationships that can't stand alone
     * @return bool
     */
    protected function deleteNonStandaloneChildren(): void
    {
        $children = static::NON_STANDALONE_CHILDREN;

        foreach ($children as $child) {
             $this->{$child}()?->delete();
        }
    }


}
