<?php

use Gigneo\Modules;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

$settings = $this->get_settings_for_display();

$include_by = (array) ( $settings['include_by'] ?? array() );
$exclude_by = (array) ( $settings['exclude_by'] ?? array() );

$query_args = array(
	'post_type'      => 'gigneo_service',
	'post_status'    => 'publish',
	'posts_per_page' => absint( $settings['posts_per_page'] ?? 9 ),
	'no_found_rows'  => true,
);

$post_not_in = array();
$tax_query   = array( 'relation' => 'AND' );

$add_term_filters = static function ( $term_keys, $exclude = false ) use ( &$tax_query ) {
	foreach ( (array) $term_keys as $term_key ) {
		if ( ! is_string( $term_key ) || ! str_contains( $term_key, ':' ) ) {
			continue;
		}

		list( $term_taxonomy, $filter_term_id ) = explode( ':', $term_key, 2 );
		$filter_term_id                         = absint( $filter_term_id );
		$filter_term                            = get_term( $filter_term_id, $term_taxonomy );

		if ( ! $filter_term || is_wp_error( $filter_term ) || ! in_array( $term_taxonomy, array( 'gigneo_facet', 'gigneo_skill' ), true ) ) {
			continue;
		}

		$term_query = array(
			'taxonomy' => $term_taxonomy,
			'field'    => 'term_id',
			'terms'    => array( $filter_term_id ),
		);

		if ( $exclude ) {
			$term_query['operator'] = 'NOT IN';
		}

		$tax_query[] = $term_query;
	}
};

if ( in_array( 'term', $include_by, true ) && ! empty( $settings['include_term_ids'] ) ) {
	$add_term_filters( $settings['include_term_ids'] );
}

if ( in_array( 'term', $exclude_by, true ) && ! empty( $settings['exclude_term_ids'] ) ) {
	$add_term_filters( $settings['exclude_term_ids'], true );
}

if ( count( $tax_query ) > 1 ) {
	// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
	$query_args['tax_query'] = $tax_query;
}

// Include authors.
if ( in_array( 'author', $include_by, true ) && ! empty( $settings['include_authors'] ) ) {
	$include_authors = $this->resolve_query_author_ids( $settings['include_authors'] );

	if ( ! empty( $include_authors ) ) {
		$query_args['author__in'] = $include_authors;
	} else {
		$query_args['author__in'] = array( 0 );
	}
}

// Include services.
if ( in_array( 'service', $include_by, true ) && ! empty( $settings['include_services'] ) ) {
	$query_args['post__in'] = array_map( 'absint', (array) $settings['include_services'] );
}

// Exclude authors.
if ( in_array( 'author', $exclude_by, true ) && ! empty( $settings['exclude_authors'] ) ) {
	$exclude_authors = $this->resolve_query_author_ids( $settings['exclude_authors'] );

	if ( ! empty( $exclude_authors ) ) {
		$query_args['author__not_in'] = $exclude_authors;
	}
}

// Exclude services.
if ( in_array( 'service', $exclude_by, true ) && ! empty( $settings['exclude_services'] ) ) {
	$post_not_in = array_map( 'absint', (array) $settings['exclude_services'] );
}

// WP_Query ignores post__not_in when post__in is set, so apply excludes here.
if ( ! empty( $post_not_in ) ) {
	if ( ! empty( $query_args['post__in'] ) ) {
		$query_args['post__in'] = array_values( array_diff( $query_args['post__in'], $post_not_in ) );

		if ( empty( $query_args['post__in'] ) ) {
			$query_args['post__in'] = array( 0 );
		}
	} else {
		// phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_post__not_in -- Exclude user-selected services from Elementor widget query.
		$query_args['post__not_in'] = $post_not_in;
	}
}

// Order.
$sort_by    = $settings['orderby'] ?? 'date';
$sort_order = $settings['order'] ?? 'DESC';

switch ( $sort_by ) {
	case 'title':
	case 'menu_order':
		$query_args['orderby'] = $sort_by;
		$query_args['order']   = $sort_order;
		break;
	case 'rand':
		$query_args['orderby'] = 'rand';
		break;
	case 'recommended':
		// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
		$query_args['meta_key'] = '_gigneo_pm_total_completed_order';
		$query_args['orderby']  = 'meta_value_num';
		$query_args['order']    = $sort_order;
		break;
	case 'top_rated':
		// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
		$query_args['meta_key'] = '_gigneo_pm_average_rating';
		$query_args['orderby']  = 'meta_value_num';
		$query_args['order']    = $sort_order;
		break;
	case 'price':
		// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
		$query_args['meta_key'] = '_gigneo_pm_price_plan_one_price';
		$query_args['orderby']  = 'meta_value_num';
		$query_args['order']    = $sort_order;
		break;
	default:
		$query_args['orderby'] = 'date';
		$query_args['order']   = $sort_order;
		break;
}

$query_args = apply_filters( 'gigneo_elementor_service_grid_query_args', $query_args, $settings, $this );

$service_query      = new WP_Query( $query_args );
$active_profile_id  = gigneo_active_profile_id();
$saved_items        = gigneo_post_meta( $active_profile_id, '_gigneo_pm_saved_service' );
$saved_items        = ! empty( $saved_items ) && is_array( $saved_items ) ? array_map( 'absint', $saved_items ) : array();
$country_state_list = gigneo_countries_with_states( 'active' );

$enable_filters   = $settings['enable_filters'] ?? 'no';
$filter_all_text  = ucfirst( mb_strtolower( $settings['filter_all_text'] ?? esc_html__( 'All', 'gigneo' ) ) );
$category_filters = array();

if ( 'yes' === $enable_filters && ! empty( $service_query->posts ) ) {
	foreach ( $service_query->posts as $post_obj ) {
		$gn_terms = get_the_terms( $post_obj->ID, 'gigneo_facet' );

		if ( $gn_terms && ! is_wp_error( $gn_terms ) ) {
			foreach ( $gn_terms as $gn_term ) {
				if ( 0 !== (int) $gn_term->parent ) {
					continue;
				}

				$category_filters[ $gn_term->slug ] = ucfirst( mb_strtolower( $gn_term->name ) );
			}
		}
	}
}
?>
<div class="gn-services-grid-main-wrapper">
	<?php if ( 'yes' === $enable_filters && ! empty( $category_filters ) ) { ?>
		<div class="gn-grid-filters gn-services-grid-filters">
			<ul class="gn-services-grid-filter-list">
				<li class="gn-services-grid-filter-item active"
					data-filter="*"><?php echo esc_html( $filter_all_text ); ?></li>
				<?php foreach ( $category_filters as $f_slug => $f_name ) { ?>
					<li class="gn-services-grid-filter-item"
						data-filter=".cat-<?php echo esc_attr( $f_slug ); ?>"><?php echo esc_html( $f_name ); ?></li>
				<?php } ?>
			</ul>
		</div>
	<?php } ?>

	<div class="gn-ele-service-grid-wrapper">
		<?php
		if ( $service_query->have_posts() ) {
			while ( $service_query->have_posts() ) {
				$service_query->the_post();
				$service_id           = get_the_ID();
				$service_title        = get_the_title( $service_id );
				$service_link         = get_permalink( $service_id );
				$service_thumbnail_id = get_post_thumbnail_id( $service_id );

				$service_price      = gigneo_post_meta( $service_id, '_gigneo_pm_price_plan_one_price' );
				$service_type       = gigneo_post_meta( $service_id, '_gigneo_pm_type' );
				$service_gallery    = gigneo_post_meta( $service_id, '_gigneo_pm_gallery' );
				$service_video_type = gigneo_post_meta( $service_id, '_gigneo_pm_video_type' );

				//Video
				$service_video_link = '';
				if ( 'link' === $service_video_type ) {
					$service_video_link = gigneo_post_meta( $service_id, '_gigneo_pm_video_link' );
				} else {
					$service_video      = gigneo_post_meta( $service_id, '_gigneo_pm_video' );
					$service_video_link = wp_get_attachment_url( $service_video ) ?? '';
				}

				$author_id        = get_post_field( 'post_author', $service_id );
				$profile_id       = gigneo_profile_id( $author_id, 'freelancer' );
				$author_avatar_id = get_post_thumbnail_id( $profile_id ) ?? 0;
				$online_status    = gigneo_online_status( $profile_id );
				$is_featured      = gigneo_post_meta( $service_id, '_gigneo_pm_featured' );

				$author_profile_average_rating = gigneo_profile_rating( $profile_id, 'average' );
				$author_profile_reviews        = gigneo_profile_rating( $profile_id );
				$delivery_time                 = gigneo_post_meta( $service_id, '_gigneo_pm_price_plan_one_delivery_time' );
				$delivery_time_type            = gigneo_post_meta( $service_id, '_gigneo_pm_price_plan_one_delivery_time_type' );
				$delivery_time_label           = gigneo_delivery_time( $delivery_time, $delivery_time_type );

				$locations = gigneo_post_meta( $service_id, '_gigneo_pm_locations' );
				$locations = is_array( $locations ) ? $locations : array();
				$card_lat  = '';
				$card_lng  = '';
				if ( ! empty( $locations ) && is_array( $locations ) ) {
					$first_loc = $locations[0]['location'][0] ?? $locations[0]['location'] ?? array();
					$card_lat  = $first_loc['lat'] ?? '';
					$card_lng  = $first_loc['lng'] ?? '';
				}

				// Terms for filter class
				$gn_terms       = get_the_terms( $service_id, 'gigneo_facet' );
				$cat_class_list = array();

				if ( $gn_terms && ! is_wp_error( $gn_terms ) ) {
					foreach ( $gn_terms as $gn_term ) {
						$cat_class_list[] = 'cat-' . $gn_term->slug;
					}
				}
				$cat_class_str = ! empty( $cat_class_list ) ? ' ' . implode( ' ', $cat_class_list ) : '';

				// Save state
				$active_class = in_array( $service_id, $saved_items, true ) ? 'gn-saved' : '';
				?>
				<div class="gn-service-card-item<?php echo esc_attr( $cat_class_str ); ?>">
					<div class="gn-service-card gn-service-card-layout-1"
						data-item-id="<?php echo esc_attr( $service_id ); ?>"
						data-lat="<?php echo esc_attr( $card_lat ); ?>" data-lng="<?php echo esc_attr( $card_lng ); ?>">
						<div class="gn-head">
							<div class="gn-slick-slider gn-slick-theme gn-service-media-slider">
								<div class="gn-slick-slide">
									<figure class="gn-service-media">
										<?php gigneo_attachment_image_src( $service_thumbnail_id, 'large' ); ?>
										<?php if ( ! empty( $service_video_link ) ) { ?>
											<a href="<?php echo esc_url( $service_video_link ); ?>" data-gn-fancybox
												class="gn-play-video-toggle">
												<i class="hi hi-play" aria-hidden="true"></i>
											</a>
										<?php } ?>
									</figure>
								</div>
								<?php
								if ( ! empty( $service_gallery ) && is_array( $service_gallery ) ) {
									foreach ( $service_gallery as $gallery_item ) {
										if ( intval( $gallery_item ) === intval( $service_thumbnail_id ) ) {
											continue;
										}
										?>
										<div class="gn-slick-slide">
											<figure class="gn-service-media"><?php gigneo_attachment_image_src( $gallery_item, 'large' ); ?>
											</figure>
										</div>
										<?php
									}
								}
								?>
							</div>
							<?php if ( $is_featured ) { ?>
								<div class="gn-tags">
									<span class="gn-status-tag-fill gn-warning"><?php echo esc_html__( 'Featured', 'gigneo' ); ?></span>
								</div>
							<?php } ?>
							<?php if ( 'yes' === $settings['show_save_button'] ) { ?>
								<button class="gn-save-btn gn-btn <?php echo esc_attr( $active_class ); ?>"
										data-gn-id="<?php echo intval( $service_id ); ?>"
										data-gn-type="<?php echo esc_attr( 'service' ); ?>"
										aria-label="<?php esc_attr_e( 'Save', 'gigneo' ); ?>">
									<?php gigneo_saved_icon( true ); ?>
								</button>
							<?php } ?>
						</div>
						<div class="gn-body">
							<h2 class="gn-title gn-two-line-ellipsis">
								<a href="<?php echo esc_url( $service_link ); ?>"><?php echo esc_html( $service_title ); ?></a>
							</h2>
							<div class="gn-price">
								<span class="gn-label"><?php echo esc_html__( 'Starting from', 'gigneo' ); ?></span>
								<strong class="gn-value"><?php echo esc_html( gigneo_price_format( $service_price, true ) ); ?></strong>
							</div>
							<?php if ( 'yes' === $settings['show_meta'] ) { ?>
								<div class="gn-meta">
									<div class="gn-delivery">
										<i class="hi hi-clock" aria-hidden="true"></i>
										<?php echo esc_html( $delivery_time_label ); ?>
									</div>
									<div class="gn-type">
										<i class="hi hi-map-pin" aria-hidden="true"></i>
										<?php echo 'onsite' === $service_type ? esc_html__( 'Onsite', 'gigneo' ) : esc_html__( 'Remote', 'gigneo' ); ?>
									</div>
									<?php if ( count( $locations ) === 1 ) { ?>
                                        <div class="gn-location">
                                            <i class="hi hi-map" aria-hidden="true"></i>
                                            <?php
                                            $loc       = $locations[0] ?? array();
                                            $city      = get_term_by( 'slug', $loc['city'] ?? '', 'gigneo_city' );
                                            $city_name = ( $city && ! is_wp_error( $city ) ) ? $city->name : '';

                                            $country_state_key = $loc['country_state'] ?? '';
                                            $country_state     = $country_state_list[ $country_state_key ] ?? '';

                                            $label = implode( ', ', array_filter( array(
                                                    $city_name,
                                                    $country_state,
                                            ) ) );

                                            if ( $label ) {
                                                echo '<span>' . esc_html( $label ) . '</span>';
                                            }
                                            ?>
                                        </div>
										<?php
									} elseif ( count( $locations ) > 1 ) {
										?>
										<div class="gn-location">
											<i class="hi hi-map" aria-hidden="true"></i>
											<?php
											printf(
											// translators: %d is the number of locations.
												esc_html( _n( '%d Location', '%d Locations', count( $locations ), 'gigneo' ) ),
												count( $locations )
											);

											?>
										</div>
									<?php } ?>
								</div>
							<?php } ?>
						</div>
						<div class="gn-footer">
							<div class="gn-profile">
								<figure class="gn-avatar gn-<?php echo esc_attr( $online_status ? 'online' : 'offline' ); ?>">
									<?php gigneo_attachment_image_src( $author_avatar_id, 'thumbnail', 'profile', '', '', $profile_id ); ?>
								</figure>
								<div class="gn-info">
									<div class="gn-name-wrapper">
										<a href="<?php echo esc_url( get_the_permalink( $profile_id ) ); ?>" target="_blank"
											class="gn-name"><?php echo esc_html( gigneo_profile_name( $profile_id ) ); ?>
										</a>
										<?php gigneo_verification_badge( $profile_id, true ); ?>
									</div>
									<?php if ( 'yes' === $settings['show_rating'] ) { ?>
										<p class="gn-ratings">
											<i class="hi hi-star-alt" aria-hidden="true"></i>
											<?php echo esc_html( $author_profile_average_rating ?? 0 ); ?>
											<span class="gn-count">(<?php echo esc_html( $author_profile_reviews ?? 0 ); ?>)</span>
										</p>
									<?php } ?>
								</div>
							</div>
							<div class="gn-actions">
								<?php
								do_action(
									'gigneo_action_buttons',
									array(
										'member_id'  => $profile_id,
										'profile_id' => $active_profile_id,
										'context'    => 'grid',
									)
								);
								?>
								<a href="<?php echo esc_url( get_the_permalink( $service_id ) ); ?>"
									class="gn-btn gn-btn-outline-grey">
									<i class="hi hi-eye" aria-hidden="true"></i>
								</a>
							</div>
						</div>
					</div>
				</div>
				<?php
			}
			wp_reset_postdata();
		}
		?>
	</div>
</div>
