<?php

namespace HelpGent\App\Http\Controllers\Admin;

defined( 'ABSPATH' ) || exit;

use HelpGent\App\DTO\AdminResponseReadDTO;
use HelpGent\App\Http\Controllers\Controller;
use HelpGent\App\Models\HelpGentUser;
use HelpGent\App\Repositories\FormRepository;
use HelpGent\App\Repositories\ResponseRepository;
use HelpGent\App\Repositories\ResponseTagRepository;
use HelpGent\WpMVC\RequestValidator\Validator;
use HelpGent\WpMVC\Routing\Response;
use HelpGent\WpMVC\Exceptions\Exception;
use WP_REST_Request;

class ResponseController extends Controller {
    public ResponseRepository $repository;

    public FormRepository $form_repository;

    public ResponseTagRepository $response_tag_repository;

    public function __construct( ResponseRepository $repository, FormRepository $form_repository, ResponseTagRepository $response_tag_repository ) {
        $this->repository              = $repository;
        $this->form_repository         = $form_repository;
        $this->response_tag_repository = $response_tag_repository;
    }

    public function index( Validator $validator, WP_REST_Request $wp_rest_request ) {
        $validator->validate(
            [
                'form_id'      => 'required|numeric',
                'response_id'  => 'numeric',
                'per_page'     => 'numeric',
                'page'         => 'numeric',
                'is_archive'   => 'required|numeric|accepted:0,1',
                'order_by'     => 'required|string|accepted:read,unread,latest,oldest',
                'is_completed' => 'numeric|accepted:0,1',
                'tag_ids'      => 'array',
                'search'       => 'string',
                'from_date'    => 'date:Y-m-d',
                'to_date'      => 'date:Y-m-d'
            ] 
        );

        $form_id = intval( $wp_rest_request->get_param( 'form_id' ) );

        do_action( 'helpgent_before_retrieve_responses', $form_id, $wp_rest_request, $validator );

        $from_date = $wp_rest_request->get_param( 'from_date' );

        if ( ! empty( $from_date ) ) {
            $from_date = helpgent_now()->create_from_format( helpgent_date_time_format(), $from_date . ' 00:00:00' );
        }

        $to_date = $wp_rest_request->get_param( 'to_date' );

        if ( ! empty( $to_date ) ) {
            $to_date = helpgent_now()->create_from_format( helpgent_date_time_format(), $to_date . ' 24:00:00' );
        }

        $dto = ( new AdminResponseReadDTO() )
            ->set_per_page( intval( $wp_rest_request->get_param( 'per_page' ) ) )
            ->set_page( intval( $wp_rest_request->get_param( 'page' ) ) )
            ->set_order_by( $wp_rest_request->get_param( 'order_by' ) )
            ->set_is_archive( intval( $wp_rest_request->get_param( 'is_archive' ) ) )
            ->set_tag_ids( $wp_rest_request->has_param( 'tag_ids' ) ? $wp_rest_request->get_param( 'tag_ids' ) : [] )
            ->set_search( $wp_rest_request->get_param( 'search' ) )
            ->set_from_date( $from_date )
            ->set_to_date( $to_date )
            ->set_form_id( $form_id );

        if ( $wp_rest_request->has_param( 'response_id' ) ) {
            $dto->set_response_id( intval( $wp_rest_request->get_param( 'response_id' ) ) );
        }

        if ( $wp_rest_request->has_param( 'is_completed' ) ) {
            $dto->set_is_completed( intval( $wp_rest_request->get_param( 'is_completed' ) ) );
        }

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

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

        $form_id = intval( $wp_rest_request->get_param( 'form_id' ) );

        do_action( 'helpgent_before_retrieve_response_form', $form_id, $wp_rest_request, $validator );

        return Response::send(
            [
                'form' => $this->repository->form( $form_id )
            ]
        );
    }

    public function delete( Validator $validator, WP_REST_Request $wp_rest_request ) {
        $validator->validate(
            [
                'id' => 'required|numeric'
            ]
        );

        $response_id = $wp_rest_request->get_param( 'id' );

        do_action( 'helpgent_before_delete_response', $response_id, $wp_rest_request, $validator );

        $delete = $this->repository->delete( $response_id );

        if ( 0 === $delete ) {
            throw new Exception( esc_html__( 'Oops, something went wrong. Please try again.', 'helpgent' ), 500 );
        }

        return Response::send(
            [
                'message' => esc_html__( 'The response has been deleted successfully.', 'helpgent' )
            ]
        );
    }

    public function setup_tag( Validator $validator, WP_REST_Request $wp_rest_request ) {
        $validator->validate(
            [
                'tag_id'      => 'required|integer',
                'response_id' => 'required|integer'
            ]
        );

        $response_id = $wp_rest_request->get_param( 'response_id' );

        do_action( 'helpgent_before_add_or_remove_response_tag', $response_id, $wp_rest_request, $validator );

        $this->response_tag_repository->add_or_remove( 
            $response_id, 
            $wp_rest_request->get_param( 'tag_id' ),
            get_current_user_id()
        );

        return Response::send(
            [
                'message' => esc_html__( "The response tag has been updated successfully.", 'helpgent' )
            ]
        );
    }

    public function update_read( Validator $validator, WP_REST_Request $wp_rest_request ) {
        $validator->validate(
            [
                'id'      => 'required|numeric',
                'is_read' => 'required|integer|accepted:0,1'
            ]
        );

        $response_id = $wp_rest_request->get_param( 'id' );

        do_action( 'helpgent_before_update_response_read', $response_id, $wp_rest_request, $validator );

        $this->repository->update_read( 
            $response_id,
            $wp_rest_request->get_param( 'is_read' )
        );

        return Response::send(
            [
                'message' => esc_html__( "Response read status updated successfully!", 'helpgent' )
            ]
        );
    }

    public function update_archive_status( Validator $validator, WP_REST_Request $wp_rest_request ) {
        $validator->validate(
            [
                'id'         => 'required|numeric',
                'is_archive' => 'required|integer|accepted:0,1'
            ]
        );

        $response_id = $wp_rest_request->get_param( 'id' );

        do_action( 'helpgent_before_update_response_archive_status', $response_id, $wp_rest_request, $validator );

        $this->repository->update_archive_status( 
            $response_id,
            $wp_rest_request->get_param( 'is_archive' )
        );

        return Response::send(
            [
                'message' => esc_html__( "Response archive status updated successfully!", 'helpgent' )
            ]
        );
    }

    public function user( Validator $validator, WP_REST_Request $wp_rest_request ) {
        $validator->validate(
            [
                'id' => 'numeric'
            ] 
        );

        $response_id = intval( $wp_rest_request->get_param( 'id' ) );

        $response = $this->repository->get_by_id( $response_id );

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

        $user_id = $response->created_by;

        if ( '0' === $user_id ) {
            throw new Exception( esc_html__( "User not found", "helpgent" ) );
        }

        $user = HelpGentUser::query()->where( 'id', $user_id )->first();

        if ( ! $user ) {
            throw new Exception( esc_html__( "User not found", "helpgent" ) );
        }

        $user->avatar_url =  get_avatar_url( $user->email );

        return Response::send(
            [
                'user' => $user
            ]
        );
    }
}
