<?php

namespace HelpGent\App\Support\Element\Fields;

defined( 'ABSPATH' ) || exit;

use HelpGent\App\Models\ElementAnswers;
use HelpGent\App\Models\Review;
use HelpGent\App\Support\Element\Element;
use HelpGent\App\Support\Element\Summary\Pagination;
use HelpGent\WpMVC\RequestValidator\Validator;

use HelpGent\App\DTO\ReviewDTO;
use HelpGent\App\Repositories\ChatMessageRepository;
use HelpGent\App\Repositories\ReviewRepository;

use stdClass;
use WP_REST_Request;

class LiveChat extends Element {

    use Pagination;

    public bool $has_nested_answer = true; 

    public bool $skip_full_submission = true;

    public static function get_key(): string {
        return 'live_chat';
    }

    public function validate( WP_REST_Request $wp_rest_request, Validator $validator, array $element ) {
        $key        = self::get_key();
        $attributes = $element['attributes'];
        
        $rules = [
            "{$key}" => 'accepted:0,1',
            'liked'  => 'accepted:0,1',
        ];

        if ( ! $wp_rest_request->has_param( 'liked' ) ) {
            $rules[ "{$key}" ] = 'required|' . $rules[ "{$key}" ];
        }

        if ( ! empty( $wp_rest_request->get_param( 'comment' ) ) || 
            ( '1' === $attributes['chat_rating_is_required'] && 
                $this->response_has_live_chat_message( $wp_rest_request ) ) 
        ) {
            $rules['liked'] = 'required|' . $rules['liked'];
        }

        $validator->validate( $rules, false );

        static::throw_validator_errors( $validator );
    }

    public function response_has_live_chat_message( WP_REST_Request $wp_rest_request ): bool {
        $response_id    = $wp_rest_request->get_param( 'response_id' );
        $response_token = $wp_rest_request->get_param( 'response_token' );

        if ( ! empty( $response_token ) ) {
            $response = helpgent_get_response_by_token( $response_token, $wp_rest_request->get_param( 'form_id' ) );

            if ( $response ) {
                $response_id = $response->id;
            }
        }

        if ( empty( $response_id ) ) {
            return false;
        }

        /**
         * @var ChatMessageRepository $chat_repo
         */
        $chat_repo = helpgent_pro_singleton( ChatMessageRepository::class );

        return $chat_repo->response_has_message( $response_id );
    }

    public function save_answer( WP_REST_Request $wp_rest_request, array $element, int $response_id, stdClass $form ): bool {
        if ( $wp_rest_request->has_param( 'liked' ) ) {
            $wp_rest_request->set_param( self::get_key(), '1' );
        }

        return parent::save_answer( $wp_rest_request, $element, $response_id, $form );
    }

    public function save_nested_answer( int $answer_id, array $values, stdClass $form ): bool {
        if ( ! isset( $values['liked'] ) ) {
            return true;
        }

        // Save the nested answer.
        $dto = ( new ReviewDTO() )
            ->set_answer_id( $answer_id )
            ->set_liked( '1' === ( string ) $values['liked'] );

        if ( isset( $values['comment'] ) ) {
            $dto->set_comment( $values['comment'] );
        }

        /**
         * @var ReviewRepository $review_repository
         */
        $review_repository = helpgent_singleton( ReviewRepository::class );

        return ( bool ) $review_repository->create_or_update( $dto );
    }

    public function get_chat_agent_id( int $response_id ): int {
        /**
         * @var ChatMessageRepository $chat_repo
         */
        $chat_repo = helpgent_pro_singleton( ChatMessageRepository::class );

        $id = $chat_repo->get_response_last_chat_agent_id( $response_id );

        return $id !== null ? $id : 0;
    }

    public function delete_feedback( stdClass $answer, ReviewRepository $review_repository ) {
        if ( $answer->review_id ) {
            return $review_repository->delete( $answer->review_id );
        }

        return false;
    }

    protected function get_element_summary( stdClass $form, array $element, int $page, int $per_page ): array {
        $total_query = ElementAnswers::query( 'answer' )
            ->select( 
                [
                    "SUM( CASE WHEN review.liked = 1 THEN 1 ELSE 0 END ) AS total_like",
                    "SUM( CASE WHEN review.liked = 0 THEN 1 ELSE 0 END ) AS total_dislike",
                ]
            )
            ->left_join( Review::get_table_name() . ' as review', 'review.answer_id', 'answer.id' )
            ->where( 'answer.form_id', $form->id )
            ->where( 'answer.element_id', $element['id'] )
            ->group_by( 'answer.element_id' )
            ->first();

        $query = ElementAnswers::query( 'answer' )
            ->select( 
                [
                    'answer.id',
                    'answer.element_type',
                    "review.comment",
                    "review.liked",
                    'answer.created_at',
                ]
            )
            ->left_join( Review::get_table_name() . ' as review', 'review.answer_id', 'answer.id' )
            ->where( 'answer.form_id', $form->id )
            ->where( 'answer.element_id', $element['id'] )
            ->pagination( $page, $per_page, 1 );

        return [
            'overview' => $total_query,
            'summary'  => $query,
        ];
    }
}