<?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\SegmentRepository;
use Vendtics\App\DTO\Contact\SegmentDTO;
use Vendtics\App\DTO\Contact\SegmentReadDTO;
use WP_REST_Request;

class SegmentController extends Controller {
    public SegmentRepository $repository;

    public function __construct( SegmentRepository $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 SegmentReadDTO;
        $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 {
        $validator->validate(
            [
                'name'        => 'required|max:255',
                'description' => 'string|max:255',
                'queries'     => 'required|array'
            ]
        );

        $dto = new SegmentDTO;
        $dto->set_name( $request->get_param( 'name' ) );
        $dto->set_description( $request->get_param( 'description' ) );
        $dto->set_queries( $request->get_param( 'queries' ) );

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

        return Response::send(
            [
                "message" => esc_html__( "Segment 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"
            ]
        );

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

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

        $segment->queries = json_decode( $segment->queries );

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

    /**
     * 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",
                'name'        => 'required|max:255',
                'description' => 'string|max:255',
                'queries'     => 'required|array'
            ]
        );

        $dto = new SegmentDTO;
        $dto->set_id( $request->get_param( "id" ) );
        $dto->set_name( $request->get_param( 'name' ) );
        $dto->set_description( $request->get_param( 'description' ) );
        $dto->set_queries( $request->get_param( 'queries' ) );

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

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

    public function duplicate( Validator $validator, WP_REST_Request $request ) {
        $validator->validate(
            [
                "id" => "required|numeric"
            ]
        );

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

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

        $dto = new SegmentDTO;
        $dto->set_name( $segment->name . ' - Copy' );
        $dto->set_queries( json_decode( $segment->queries, true ) );

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

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

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