<?php

namespace Vendtics\App\Http\Controllers\Admin;

defined( "ABSPATH" ) || exit;

use Vendtics\App\Http\Controllers\Controller;
use Vendtics\WpMVC\Exceptions\Exception;
use Vendtics\WpMVC\Routing\Response;
use Vendtics\App\Repositories\NoteRepository;
use Vendtics\WpMVC\RequestValidator\Validator;
use Vendtics\App\DTO\Note\DTO;
use Vendtics\App\DTO\Note\Read;
use WP_REST_Request;

class NoteController extends Controller {
    public NoteRepository $repository;

    public function __construct( NoteRepository $repository ) {
        $this->repository = $repository;
    }

    /**
     * Display a listing of the resource.
     *
     * @param Validator $validator Instance of the Validator.
     * @param WP_REST_Request $request The REST request instance.
     * @return array
     */
    public function index( Validator $validator, WP_REST_Request $request ): array {
        $validator->validate(
            [
                'page'        => 'required|numeric',
                'per_page'    => 'required|numeric',
                'contact_id'  => 'required|numeric',
                'is_favorite' => 'required|numeric|accepted:0,1',
                'search'      => 'string'
            ]
        );

        $dto = ( new Read )->set_page( intval( $request->get_param( 'page' ) ) )
        ->set_per_page( intval( $request->get_param( 'per_page' ) ) )
        ->set_contact_id( intval( $request->get_param( 'contact_id' ) ) )
        ->set_is_favorite( intval( $request->get_param( 'is_favorite' ) ) )
        ->set_search( (string) $request->get_param( 'search' ) );

        return Response::send( $this->repository->get( $dto ) );
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param Validator $validator Instance of the Validator.
     * @param WP_REST_Request $request The REST request instance.
     * @return array
     */
    public function store( Validator $validator, WP_REST_Request $request ): array {
        $validator->validate(
            [
                'title'      => 'required|string|max:255',
                'note'       => 'required|string|max:1000',
                'contact_id' => 'required|numeric',
            ]
        );

        $dto = ( new DTO )->set_title( $request->get_param( 'title' ) )
        ->set_note( $request->get_param( 'note' ) )
        ->set_contact_id( $request->get_param( 'contact_id' ) )
        ->set_created_by( get_current_user_id() );

        $id = $this->repository->create( $dto );

        return Response::send(
            [
                "message" => esc_html__( "Note was created successfully", 'vendtics' ),
                "data"    => [
                    "id" => $id
                ]
            ], 201
        );
    }

    /**
     * Display the specified resource.
     *
     * @param Validator $validator Instance of the Validator.
     * @param WP_REST_Request $request The REST request instance.
     * @return array
     * @throws Exception
     */
    public function show( Validator $validator, WP_REST_Request $request ): array {
        $validator->validate(
            [
                "id" => "required|numeric"
            ]
        );

        $note = $this->repository->get_single( $request->get_param( "id" ) );

        if ( ! $note ) {
            throw new Exception( esc_html__( "Note not found", 'vendtics' ) );
        }

        return Response::send(
            [
                "data" => $note
            ]
        );
    }

    /**
     * Update the specified resource in storage.
     *
     * @param Validator $validator Instance of the Validator.
     * @param WP_REST_Request $request The REST request instance.
     * @return array
     */
    public function update( Validator $validator, WP_REST_Request $request ): array {
        $validator->validate(
            [
                "id"    => "required|numeric",
                'title' => 'required|string|max:255',
                'note'  => 'required|string|max:1000'
            ]
        );

        $dto = ( new DTO )->set_id( $request->get_param( "id" ) )
        ->set_title( $request->get_param( 'title' ) )
        ->set_note( $request->get_param( 'note' ) );

        $this->repository->update( $dto );

        return Response::send(
            [
                "message" => esc_html__( "Note was updated successfully", 'vendtics' )
            ]
        );
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param Validator $validator Instance of the Validator.
     * @param WP_REST_Request $request The REST request instance.
     * @return array
     */
    public function delete( Validator $validator, WP_REST_Request $request ): array {
        $validator->validate(
            [
                "id" => "required|numeric"
            ]
        );

        $this->repository->delete_by_id( $request->get_param( "id" ) );

        return Response::send(
            [
                "message" => esc_html__( "Note was deleted successfully", 'vendtics' )
            ]
        );
    }

    public function update_favorite_status( Validator $validator, WP_REST_Request $request ) {
        $validator->validate(
            [
                "id"          => "required|numeric",
                'is_favorite' => 'required|numeric|accepted:0,1',
            ]
        );

        $id = intval( $request->get_param( 'id' ) );

        $this->repository->update_favorite( $id, $request->get_param( 'is_favorite' ) );

        return Response::send(
            [
                "message" => esc_html__( "Note favorite status updated successfully", 'vendtics' ),
            ]
        );
    }

    public function update_priority( Validator $validator, WP_REST_Request $request ) {
        $validator->validate(
            [
                "id"       => "required|numeric",
                "priority" => "required|string|accepted:high,medium,normal,low",
            ]
        );

        $id = intval( $request->get_param( 'id' ) );

        $this->repository->update_priority( $id, $request->get_param( 'priority' ) );

        return Response::send(
            [
                "message" => esc_html__( "Note priority updated successfully", 'vendtics' ),
            ]
        );
    }
    
    public function duplicate( Validator $validator, WP_REST_Request $request ) {
        $validator->validate(
            [
                "id" => "required|numeric"
            ]
        );

        $note = $this->repository->get_by_id( intval( $request->get_param( 'id' ) ) );

        if ( ! $note ) {
            throw new Exception( "Note not found" );
        }

        $dto = ( new DTO )->set_title( $note->title . ' - Copy' )
        ->set_note( $note->note )
        ->set_contact_id( $note->contact_id )
        ->set_created_by( get_current_user_id() );

        $id = $this->repository->create( $dto );

        return Response::send(
            [
                "message" => esc_html__( "Note was duplicated successfully", 'vendtics' ),
                "data"    => [
                    "id" => $id
                ]
            ], 201
        );
    }
}