<?php

namespace OtomaticAi\RestControllers;

use Exception;
use OtomaticAi\Models\Persona;
use OtomaticAi\Models\WP\User;
use OtomaticAi\Utils\Image;
use Simple_Local_Avatars;
use WP_Error;

class PersonaRestController extends RestController
{
    public function index()
    {
        $personas = Persona::whereHas('user')->with("user")->get();

        return $personas;
    }

    public function show()
    {
        $id = $this->input('id');

        $persona = Persona::find($id);

        if (empty($persona)) {
            return new WP_Error('not_found', 'Persona not found', ['status' => 404]);
        }

        return $persona;
    }

    public function setAvatar()
    {
        $this->validate([
            'avatar' => ['required', 'string'],
        ]);

        $id = $this->input('id');
        $persona = Persona::find($id);

        if (empty($persona)) {
            return new WP_Error('not_found', 'Persona not found', ['status' => 404]);
        }

        if (!class_exists("Simple_Local_Avatars")) {
            return new WP_Error('error', 'This feature require the Simple Local Avatars plugin. It is available on the WordPress store.', ['status' => 503]);
        }

        $persona->load(["user"]);

        // attach the avatar
        try {
            $image = Image::fromBase64($this->input("avatar"));

            if (!empty($image)) {
                $attachmentId = $image->save('user avatar');

                if ($attachmentId !== null) {
                    $sla = new Simple_Local_Avatars();
                    $sla->assign_new_user_avatar($attachmentId, $persona->user->ID);
                }
            }
        } catch (Exception $e) {
            return new WP_Error('error', $e->getMessage(), ['status' => 503]);
        }

        return $persona->fresh();
    }

    public function removeAvatar()
    {
        $id = $this->input('id');

        $persona = Persona::find($id);

        if (empty($persona)) {
            return new WP_Error('not_found', 'Persona not found', ['status' => 404]);
        }

        if (!class_exists("Simple_Local_Avatars")) {
            return new WP_Error('error', 'This feature require the Simple Local Avatars plugin. It is available on the WordPress store.', ['status' => 503]);
        }

        $persona->load(["user"]);

        // attach the avatar
        try {
            $sla = new Simple_Local_Avatars();
            $sla->avatar_delete($persona->user->ID);
        } catch (Exception $e) {
            return new WP_Error('error', $e->getMessage(), ['status' => 503]);
        }

        return $persona->fresh();
    }

    public function store()
    {
        $this->validate([
            "username" => ["required", "string"],
            "password" => ["required", "string"],
            "email" => ["nullable", "email"],
            "role" => ["nullable", "string"],
            "language" => ["required", "string"],
            "first_name" => ["required", "string"],
            "last_name" => ["nullable", "string"],
            "age" => ["nullable", "numeric", "min:18", "max:99"],
            "job" => ["nullable", "string"],
            "writing_style" => ["nullable", "string"],
            "description" => ["nullable", "string"],
            "custom_instructions" => ["nullable", "string"],
        ]);

        // verif if the username already exists
        $user = User::where("user_login", $this->input("username"))->first();
        if (!empty($user)) {
            $this->response(["message" => "The username already exists.", "errors" => ["username" => "The username already exists."]], 422);
        }

        // verify if the email already exists
        if (!empty($this->input("email"))) {
            $user = User::where("user_email", $this->input("email"))->first();
            if (!empty($user)) {
                $this->response(["message" => "The email already exists.", "errors" => ["email" => "The email already exists."]], 422);
            }
        }

        // create the user
        $userId = wp_insert_user([
            'user_login' => $this->input("username"),
            'user_pass' => $this->input("password"),
            'user_email' => $this->input("email"),
            'first_name' => $this->input("first_name"),
            'last_name' => $this->input("last_name"),
            'display_name' => $this->input("first_name") . (!empty($this->input("last_name")) ? " " . $this->input("last_name") : ""),
            'role' => $this->input("role"),
            'description' => $this->input("description"),
        ]);

        if (is_wp_error($userId)) {
            return new WP_Error('error', 'Unable to create the user.<br>' . $userId->get_error_message(), ['status' => 500]);
        }

        // get model
        $user = User::find($userId);

        // create the persona
        $persona = new Persona;
        $persona->user()->associate($user);

        $persona->language = $this->input("language");
        $persona->age = $this->input("age");
        $persona->job = $this->input("job");
        $persona->writing_style = $this->input("writing_style");
        $persona->custom_instructions = $this->input("custom_instructions");

        if ($persona->save()) {
            return $persona;
        }

        return new WP_Error('error', 'Unable to create the persona.', ['status' => 503]);
    }

    public function update()
    {
        $this->validate([
            "language" => ["required", "string"],
            "first_name" => ["required", "string"],
            "last_name" => ["nullable", "string"],
            "age" => ["required", "numeric", "min:18", "max:99"],
            "job" => ["required", "string"],
            "writing_style" => ["nullable", "string"],
            "description" => ["nullable", "string"],
            "custom_instructions" => ["nullable", "string"],
        ]);

        $id = $this->input('id');
        $persona = Persona::find($id);

        if (empty($persona)) {
            return new WP_Error('not_found', 'Persona not found', ['status' => 404]);
        }

        $persona->load(["user"]);

        // update user_meta
        update_user_meta($persona->user->ID, "first_name", $this->input("first_name"));
        update_user_meta($persona->user->ID, "last_name", $this->input("last_name"));
        update_user_meta($persona->user->ID, "description", $this->input("description"));

        // update persona
        $persona->language = $this->input("language");
        $persona->age = $this->input("age");
        $persona->job = $this->input("job");
        $persona->writing_style = $this->input("writing_style");
        $persona->custom_instructions = $this->input("custom_instructions");

        if ($persona->save()) {
            return $persona;
        }

        return new WP_Error('error', 'Unable to update the persona.', ['status' => 503]);
    }

    public function destroy()
    {
        $id = $this->input('id');

        $persona = Persona::find($id);

        if (empty($persona)) {
            return new WP_Error('not_found', 'Persona not found', ['status' => 404]);
        }

        $persona->delete();
    }
}
