<?php

namespace HelpGent\App\Repositories;

defined( 'ABSPATH' ) || exit;

use HelpGent\WpMVC\Database\Query\Builder;
use HelpGent\WpMVC\Database\Eloquent\Model;
use HelpGent\WpMVC\Repositories\Repository;
use HelpGent\WpMVC\Exceptions\Exception;
use HelpGent\App\Models\HelpGentUser;
use HelpGent\App\Models\User;
use HelpGent\App\Models\ChatMessage;
use HelpGent\App\Models\ChatMember;
use HelpGent\App\Models\Message;
use HelpGent\WpMVC\DTO\DTO;
use HelpGent\App\DTO\UserDTO;

class UserRepository extends Repository {
    public function get_query_builder():Builder {
        return HelpGentUser::query( 'user' );
    }

    protected array $select_columns = [
        'user.id',
        'user.name',
        'user.email',
        'user.number',
        'user.company',
        'user.created_at'
    ];

    public function get( int $per_page, int $page ) {
        $select_query = $this->get_query_builder()
            ->where_null( 'registered_id' )
            ->where(
                function( Builder $builder ) {
                    return $builder
                    ->where_not_null( 'user.email' )
                    ->where( 'user.email', '!=', '' );
                } 
            )
            ->select( $this->select_columns )
            ->order_by_desc( 'user.id' );
            
        $count_query = clone $select_query;

        return [
            'users' => $select_query->pagination( $page, $per_page ),
            'total' => $count_query->count()
        ];
    }

    public function create( DTO $dto ) {
        /**
         * @var UserDTO $dto
         */

        if ( $dto->is_initialized( 'email' ) && ! empty( $dto->get_email() ) ) {
            if ( $this->get_by_email( $dto->get_email() ) ) {
                throw new Exception( esc_html__( "This email address already exists.", 'helpgent' ), 500 );
            }
    
            $user = User::query()->where( 'user_email', $dto->get_email() )->first();
    
            if ( $user ) {
                $dto->set_registered_id( $user->ID );
            }
        }

        $values               = $dto->to_array();
        $values['created_at'] = helpgent_now();

        return $this->get_query_builder()->insert_get_id( $this->process_values( $values ) );
    }

    public function get_by_email( string $email, $columns = ['*'] ) {
        return $this->get_by( "email", $email, $columns );
    }

    public function get_by_token( string $token, $columns = ['*'] ) {
        return $this->get_by( "token", $token, $columns );
    }

    public function update_email( int $id, string $email ) {
        return $this->get_query_builder()->where( "id", $id )->update(
            [
                'email'      => $email,
                'updated_at' => helpgent_now(),
            ]
        );
    }

    /**
     * @param int $id
     * @return string
     */
    public function update_token( int $id ) {
        $token = helpgent_generate_token();
        $this->get_query_builder()->where( 'id', $id )->update(
            [
                'token'            => $token,
                'token_expires_at' => helpgent_now()->add_days( 30 ),
                'updated_at'       => helpgent_now(),
            ]
        );
        return $token;
    }

    public function export() {
        $query = $this->get_query_builder()->select( $this->select_columns )->where_null( 'registered_id' );
         
        do_action( 'helpgent_user_export_query', $query );
    
        return helpgent_export_contact( $query, 'user' )['url'];
    }

    public function switch_user( int $from_user_id, int $to_user_id, bool $remove_user_after_switch = false ) {
        if ( $from_user_id === $to_user_id ) {
            return null;
        }
        
        $tables = [
            [
                'model'  => ChatMessage::class,
                'column' => 'created_by',
            ],
            [
                'model'  => ChatMember::class,
                'column' => 'user_id',
            ],
            [
                'model'  => Message::class,
                'column' => 'created_by',
            ],
        ];

        foreach ( $tables as $table ) {
            /**
             * @var Model $model
             */
            $model  = helpgent_singleton( $table['model'] );
            $column = $table['column'];

            $model->query()->where( $column, $from_user_id )->update( [ $column => $to_user_id ] );
        }

        if ( $remove_user_after_switch ) {
            $this->delete_by_id( $from_user_id );
        }

        return $to_user_id;
    }
}