<?php

namespace HelpGent\App\Http\Controllers\Guest;


defined( 'ABSPATH' ) || exit;

use HelpGent\App\Models\Form;
use HelpGent\App\DTO\ChatMessageDTO;
use HelpGent\App\Repositories\ResponseRepository;
use HelpGent\App\Repositories\ChatMessageRepository;
use HelpGent\App\Http\Controllers\Controller;
use HelpGent\WpMVC\Exceptions\Exception;
use HelpGent\WpMVC\RequestValidator\Validator;
use HelpGent\WpMVC\Routing\Response;
use HelpGent\WpMVC\Database\Query\Builder;
use WP_REST_Request;

class ChatMessageController extends Controller {
    public ResponseRepository $response_repository;

    public ChatMessageRepository $repository;

    public function __construct( ChatMessageRepository $repository, ResponseRepository $response_repository ) {
        $this->repository          = $repository;
        $this->response_repository = $response_repository;
    }

    public function index( Validator $validator, WP_REST_Request $wp_rest_request ) {
        $validator->validate(
            [
                'response_token' => 'required|string',
                'form_id'        => 'required|numeric',
                'per_page'       => 'numeric',
                'page'           => 'numeric',
                'search'         => 'string'
            ]
        );

        $response_token = $wp_rest_request->get_param( 'response_token' );
        $form_id        = intval( $wp_rest_request->get_param( 'form_id' ) );
        $response       = $this->get_authorized_user_response( $response_token, $form_id );

        return Response::send(
            [ 
                'messages' => $this->repository->get(
                    $response->id, 
                    intval( $wp_rest_request->get_param( 'per_page' ) ), 
                    intval( $wp_rest_request->get_param( 'page' ) ), 
                    (string) $wp_rest_request->get_param( 'search' ) 
                ) 
            ]
        );
    }

    public function store( Validator $validator, WP_REST_Request $wp_rest_request ) {
        $validator->validate(
            [
                'response_token' => 'required|string',
                'form_id'        => 'required|numeric',
                'replied_by'     => 'required|string|max:50|accepted:video,voice,text,reply,screen_record',
                'message'        => 'string',
                'attachment_id'  => 'numeric',
                'attachment_ids' => 'array',
                'parent_id'      => 'numeric|min:1',
            ]
        );

        $response_token = $wp_rest_request->get_param( 'response_token' );
        $form_id        = intval( $wp_rest_request->get_param( 'form_id' ) );
        $response       = $this->get_authorized_user_response( $response_token, $form_id );

        /**
         * Requested message and attachment validation
         */
        $attachment_ids = (array) $wp_rest_request->get_param( 'attachment_ids' );
        $attachment_id  = intval( $wp_rest_request->get_param( 'attachment_id' ) );
        $message        = (string) $wp_rest_request->get_param( 'message' );
        
        if ( empty( $message ) && 0 >= $attachment_id && empty( $attachment_ids ) ) {
            $error = new Exception( '', 422 );
            
            $error->set_messages(
                [
                    'message' => [
                        esc_html__( "The message field is required", "helpgent" )
                    ]
                ]
            );

            throw $error;
        }

        $columns = [ 'form.id', 'form.title', 'form.status', 'form.content', 'form.created_by' ];

        $form_query = Form::query( 'form' )->select( $columns )->where( 'form.id', $response->form_id )->group_by( $columns );

        /**
         * @var Builder $form_query
         */
        $form_query     = apply_filters( 'helpgent_chat_message_store_from_query', $form_query );
        $join_form_meta = apply_filters( 'helpgent_chat_message_store_from_query_join_meta', false );

        if ( $join_form_meta ) {
            $form_query->left_join( "helpgent_form_meta as form_meta", "form_meta.form_id", "=", "form.id" );
        }

        $form = helpgent_migrate_old_form( $form_query->first(), false );

        $message_dto = ( new ChatMessageDTO() )
            ->set_form_id( $form->id )
            ->set_response_id( $response->id )
            ->set_message( $message )
            ->set_created_by( $response->created_by )
            ->set_attachment_id( $attachment_id )
            ->set_attachment_ids( $attachment_ids )
            ->set_parent_id( intval( $wp_rest_request->get_param( 'parent_id' ) ) )
            ->set_replied_by( $wp_rest_request->get_param( 'replied_by' ) );

        do_action( 'helpgent_before_store_chat_message', $message_dto, $wp_rest_request, $form, $response );
        
        $message_id = $this->repository->create( $message_dto );

        $this->response_repository->update_read( $response->id, 0 );
        $this->response_repository->update_user_activity( intval( $response->id ) );

        $message_dto->set_id( $message_id );

        $message_data = $this->repository->get_by_id( $message_id );
        $message_data = $this->repository->prepare_message( $message_data );

        do_action( 'helpgent_after_store_chat_message', $message_dto, $wp_rest_request, $form, $response );
        
        return Response::send(
            [
                'message_data' => $message_data,
                'message'      => esc_html__( 'The message was created successfully', 'helpgent' )
            ], 
            201 
        );
    }

    public function user_chat_unread_count( Validator $validator, WP_REST_Request $wp_rest_request ) {
        $validator->validate(
            [
                'response_token' => 'required|string',
                'form_id'        => 'required|numeric',
            ]
        );

        $response_token = $wp_rest_request->get_param( 'response_token' );
        $form_id        = intval( $wp_rest_request->get_param( 'form_id' ) );
        $response       = $this->get_authorized_user_response( $response_token, $form_id );

        return Response::send(
            [
                'count' => $this->repository->get_response_unread_message_count( $response->created_by, $response->id ),
            ] 
        );
    }

    public function get_authorized_user_response( string $response_token, int $form_id ) {
        $response = helpgent_get_response_by_token( $response_token, $form_id );

        if ( empty( $response ) ) {
            throw new Exception( esc_html__( "Response not found", 'helpgent' ), 404 );
        }

        return $response;
    }
}
