<?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\WpMVC\RequestValidator\Validator;
use Vendtics\App\Repositories\ListRepository;
use Vendtics\App\DTO\Contact\ListReadDTO;
use Vendtics\App\DTO\Contact\ListDTO;
use WP_REST_Request;

class ListController extends Controller {
    public ListRepository $repository;

    public function __construct( ListRepository $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(
            [
                'orders'   => 'json',
                'page'     => 'required|numeric',
                'per_page' => 'required|numeric',
                'search'   => 'string|max:255'
            ]
        );

        $dto = new ListReadDTO;
        $dto->set_search( $request->get_param( 'search' ) );
        $dto->set_page( intval( $request->get_param( 'page' ) ) );
        $dto->set_per_page( intval( $request->get_param( 'per_page' ) ) );

        if ( $request->has_param( 'orders' ) ) {
            $dto->set_orders( json_decode( $request->get_param( 'orders' ), true ) );
        }

        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 {
        // Define validation rules
        $validator->validate(
            [
                'name'        => 'required|string|max:50',
                'description' => 'string|max:255'
            ]
        );
    
        // Create DTO and set values
        $dto = new ListDTO();
        $dto->set_name( $request->get_param( 'name' ) );
        $dto->set_description( $request->get_param( 'description' ) );
    
        // Create DTO in the repository
        $id = $this->repository->create( $dto );
    
        return Response::send(
            [
                'message' => esc_html__( "The list 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"
            ]
        );

        $list = $this->repository->get_by_id( $request->get_param( "id" ) );

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

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

    /**
     * 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 {
        // Define validation rules
        $validator->validate(
            [
                'id'          => 'required|numeric',
                'name'        => 'string|max:50',
                'description' => 'string|max:255'
            ]
        );
    
        // Create DTO and set values
        $dto = new ListDTO();
        $dto->set_id( $request->get_param( 'id' ) );
        $dto->set_name( $request->get_param( 'name' ) );
        $dto->set_description( $request->get_param( 'description' ) );
    
        // Update DTO in the repository
        $this->repository->update( $dto );
    
        return Response::send(
            [
                'message' => esc_html__( "The list was updated successfully", 'vendtics' )
            ]
        );
    }     

    /**
     * @param Validator $validator Instance of the Validator.
     * @param WP_REST_Request $request The REST request instance.
     * @return array
     */
    public function bulk_delete( Validator $validator, WP_REST_Request $request ): array {
        $validator->validate(
            [
                "ids" => "required|array"
            ]
        );

        if ( ! vendtics_is_one_level_array( $request->get_param( 'ids' ) ) ) {
            throw new Exception( esc_html__( "Something was wrong", 'vendtics' ), 505 );
        }

        $ids = map_deep( $request->get_param( 'ids' ), "intval" );

        $this->repository->bulk_delete( $ids );

        return Response::send(
            [
                'message' => esc_html__( "Lists was removed 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__( "The list was deleted successfully", 'vendtics' )
            ]
        );
    }

    public function select() {
        return Response::send(
            [
                "items" => $this->repository->select()
            ]
        );
    }
}