<?php

namespace Vendtics\App\Repositories;

defined( "ABSPATH" ) || exit;

use Vendtics\WpMVC\Database\Query\Builder;
use Vendtics\App\Models\Segment;
use Vendtics\App\DTO\Contact\SegmentReadDTO;
use Vendtics\App\Models\Contact;

class SegmentRepository extends Repository {

    use AdvancedFilter;

    public function get_query_builder(): Builder {
        return Segment::query( 'segment' );
    }

    public function get( SegmentReadDTO $dto ) {
        $query = $this->get_query_builder();

        $this->segment_search_query( $query, $dto );
        
        $count_query = clone $query;

        $this->segments_orders_query( $query, $dto );

        $contacts = $query->select( "segment.id", "segment.name", "segment.description", "segment.queries", "segment.created_at", "segment.updated_at" )->pagination( $dto->get_page(), $dto->get_per_page() );

        $contacts = array_map(
            function( $contact ) {
                $contact->total_contacts = $this->advanced_filter_query( Contact::query( 'contact' ), json_decode( $contact->queries, true ) )->distinct()->count( 'contact.id' );
                unset( $contact->queries );
                return $contact;
            }, $contacts
        );

        return [
            'segments' => $contacts,
            'total'    => $count_query->count(),
        ];
    }

    protected function segment_search_query( Builder $query, SegmentReadDTO $dto ) {
        if ( ! $dto->is_initialized( 'search' ) ) {
            return;
        }

        $search = $dto->get_search();

        if ( empty( $search ) ) {
            return;
        }

        $query->where(
            function( $like_query ) use( $search ) {
                $columns = [
                    'segment.name',
                    'segment.description'
                ];

                foreach ( $columns as $column ) {
                    $like_query->or_where_like( $column, "%{$search}%" );
                }
            }
        );
    }

    protected function segments_orders_query( Builder $query, SegmentReadDTO $dto ) {
        $order_columns =  [
            'id',
            'name',
            'description',
        ];

        if ( $dto->get_orders() ) {
            foreach ( $dto->get_orders() as $order ) {
                if ( empty( $order['order'] ) || empty( $order['order_by'] ) ) {
                    continue;
                }

                if ( ! in_array( $order['order_by'], $order_columns, true ) || ! in_array( $order['order'], ['asc', 'desc'], true ) ) {
                    continue;
                }

                $query->order_by( "segment.{$order['order_by']}", $order['order'] );
            }
        } else {
            $query->order_by( "segment.id", 'desc' );
        }
    }

    public function select() {
        return Segment::query()->select( 'id', 'name' )->get();
    }

    public function count() {
        return $this->get_query_builder()->count();
    }
}