<?php
/**
 * Child theme functions - State + City Hubs + Service Pages
 * Version: Yoast-Compatible (replaces Rank Math version)
 * URL Structure: /{state}/{city}/home-service/{post-name}/
 * Integrated with Yoast SEO
 *
 * Version: 1.4.0 — Child theme complete (no plugin required)
 */

// ============================================================
// HELPERS — path checks & CPT lookups
// ============================================================

function lh_get_request_path() {
	if ( is_admin() || empty( $_SERVER['REQUEST_URI'] ) ) {
		return '';
	}
	$request_uri = strtok( wp_unslash( $_SERVER['REQUEST_URI'] ), '?' );
	$home_path   = parse_url( home_url(), PHP_URL_PATH );
	if ( $home_path && '/' !== $home_path ) {
		$home_path   = untrailingslashit( $home_path );
		$request_uri = preg_replace( '#^' . preg_quote( $home_path, '#' ) . '/?#', '', $request_uri );
	}
	return trim( $request_uri, '/' );
}

function lh_clean_page_query_vars( $query_vars ) {
	unset(
		$query_vars['pagename'],
		$query_vars['page_id'],
		$query_vars['page'],
		$query_vars['attachment'],
		$query_vars['attachment_id']
	);
	return $query_vars;
}

function lh_query_is_location_hub( $query_vars ) {
	if ( empty( $query_vars['post_type'] ) ) {
		return false;
	}
	return in_array( $query_vars['post_type'], array( 'state', 'city', 'home-services' ), true );
}

function lh_is_city_services_listing( $query = null ) {
	if ( null === $query ) {
		global $wp_query;
		$query = $wp_query;
	}
	$city_slug = $query->get( 'city_slug' ) ?: get_query_var( 'city_slug' );
	$post_type = $query->get( 'post_type' );
	if ( is_array( $post_type ) ) {
		$post_type = reset( $post_type );
	}
	if ( ! $post_type ) {
		$post_type = get_query_var( 'post_type' );
	}
	$name = $query->get( 'name' ) ?: get_query_var( 'name' );
	return $city_slug && 'home-services' === $post_type && empty( $name );
}

function lh_get_city_services_listing_url( $city_post ) {
	if ( is_numeric( $city_post ) ) {
		$city_post = get_post( $city_post );
	}
	if ( ! $city_post || 'city' !== $city_post->post_type ) {
		return '';
	}
	$state_slug = get_post_meta( $city_post->ID, '_city_state', true );
	if ( $state_slug ) {
		return home_url( $state_slug . '/' . $city_post->post_name . '/home-service/' );
	}
	return home_url( $city_post->post_name . '/home-service/' );
}

function lh_path_matches_wp_page( $path ) {
	if ( '' === $path ) {
		return false;
	}
	$page = get_page_by_path( $path, OBJECT, 'page' );
	return $page && 'publish' === $page->post_status;
}

function lh_is_home_service_path( $parts ) {
	if ( isset( $parts[2] ) && 'home-service' === $parts[2] ) {
		return true;
	}
	if ( isset( $parts[1] ) && 'home-service' === $parts[1] ) {
		return true;
	}
	return false;
}

function lh_get_state_by_slug( $slug ) {
	if ( '' === $slug ) {
		return null;
	}
	$posts = get_posts( array(
		'post_type'      => 'state',
		'name'           => $slug,
		'posts_per_page' => 1,
		'post_status'    => 'publish',
		'no_found_rows'  => true,
	) );
	return ! empty( $posts ) ? $posts[0] : null;
}

function lh_get_city_by_slug( $slug, $state_slug = '' ) {
	if ( '' === $slug ) {
		return null;
	}
	$posts = get_posts( array(
		'post_type'      => 'city',
		'name'           => $slug,
		'posts_per_page' => 1,
		'post_status'    => 'publish',
		'no_found_rows'  => true,
	) );
	if ( empty( $posts ) ) {
		return null;
	}
	$city = $posts[0];
	if ( '' === $state_slug ) {
		return $city;
	}
	$city_state = get_post_meta( $city->ID, '_city_state', true );
	return ( $city_state === $state_slug ) ? $city : null;
}

function lh_schedule_rewrite_flush() {
	set_transient( 'lh_flush_rewrites', 1, MINUTE_IN_SECONDS );
}

add_action( 'shutdown', function () {
	if ( ! get_transient( 'lh_flush_rewrites' ) ) {
		return;
	}
	delete_transient( 'lh_flush_rewrites' );
	flush_rewrite_rules( false );
} );

// ============================================================
// 1. STATE POST TYPE
// ============================================================
add_action( 'init', 'my_register_state_post_type' );
function my_register_state_post_type() {
	register_post_type( 'state', array(
		'labels' => array(
			'name'          => 'States',
			'singular_name' => 'State',
			'menu_name'     => 'States',
			'add_new'       => 'Add New State',
			'edit_item'     => 'Edit State',
			'view_item'     => 'View State',
			'search_items'  => 'Search States',
			'not_found'     => 'No states found',
		),
		'public'             => true,
		'has_archive'        => false,
		'hierarchical'       => false,
		'rewrite'            => array( 'slug' => '', 'with_front' => false ),
		'show_in_rest'       => true,
		'supports'           => array( 'title', 'editor', 'thumbnail', 'excerpt', 'page-attributes' ),
		'menu_icon'          => 'dashicons-flag',
		'menu_position'      => 4,
		'capability_type'    => 'page',
		'map_meta_cap'       => true,
		'show_in_nav_menus'  => true,
		'publicly_queryable' => true,
	) );
}

// ============================================================
// 2. CITY HUB POST TYPE
// ============================================================
add_action( 'init', 'my_register_city_post_type' );
function my_register_city_post_type() {
	register_post_type( 'city', array(
		'labels' => array(
			'name'          => 'Cities',
			'singular_name' => 'City',
			'menu_name'     => 'Cities',
			'add_new'       => 'Add New City',
			'edit_item'     => 'Edit City',
			'view_item'     => 'View City',
			'search_items'  => 'Search Cities',
			'not_found'     => 'No cities found',
		),
		'public'             => true,
		'has_archive'        => false,
		'hierarchical'       => false,
		'rewrite'            => array( 'slug' => '', 'with_front' => false ),
		'show_in_rest'       => true,
		'supports'           => array( 'title', 'editor', 'thumbnail', 'excerpt', 'page-attributes' ),
		'menu_icon'          => 'dashicons-location',
		'menu_position'      => 5,
		'capability_type'    => 'page',
		'map_meta_cap'       => true,
		'show_in_nav_menus'  => true,
		'publicly_queryable' => true,
	) );
}

// ============================================================
// 3. HOME SERVICE POST TYPE
// ============================================================
add_action( 'init', 'my_register_homeservices_post_type' );
function my_register_homeservices_post_type() {
	register_post_type( 'home-services', array(
		'labels' => array(
			'name'              => 'Home Services',
			'singular_name'     => 'Home Service',
			'menu_name'         => 'Home Services',
			'add_new'           => 'Add New Service',
			'edit_item'         => 'Edit Service',
			'view_item'         => 'View Service',
			'search_items'      => 'Search Services',
			'not_found'         => 'No services found',
			'parent_item_colon' => 'Parent Service:',
		),
		'public'            => true,
		'has_archive'       => false,
		'hierarchical'      => true,
		'rewrite'           => array( 'slug' => 'home-service', 'with_front' => false, 'hierarchical' => true ),
		'show_in_rest'      => true,
		'supports'          => array( 'title', 'editor', 'thumbnail', 'excerpt', 'custom-fields', 'page-attributes', 'author' ),
		'menu_icon'         => 'dashicons-building',
		'menu_position'     => 6,
		'capability_type'   => 'page',
		'map_meta_cap'      => true,
		'show_in_nav_menus' => true,
	) );
}

// ============================================================
// 4. TAXONOMIES
// ============================================================
add_action( 'init', 'my_register_taxonomies' );
function my_register_taxonomies() {
	register_taxonomy( 'home-services-tag', 'home-services', array(
		'hierarchical'      => false,
		'labels'            => array( 'name' => 'Tags', 'singular_name' => 'Tag', 'menu_name' => 'Tags' ),
		'show_ui'           => true,
		'show_admin_column' => true,
		'query_var'         => true,
		'rewrite'           => array( 'slug' => 'home-service-tag', 'with_front' => false ),
		'show_in_rest'      => true,
	) );
}

// ============================================================
// 5. CUSTOM REWRITE RULES (dynamic — per state/city slug only)
// ============================================================
add_action( 'init', 'add_city_service_rewrite_rules' );
function add_city_service_rewrite_rules() {
	add_rewrite_rule(
		'^home-service/([^/]+)/([^/]+)/?$',
		'index.php?post_type=home-services&name=$matches[2]',
		'top'
	);
	add_rewrite_rule(
		'^home-service/([^/]+)/?$',
		'index.php?post_type=home-services&name=$matches[1]',
		'top'
	);
	add_rewrite_rule(
		'^home-service/?$',
		'index.php?post_type=home-services',
		'top'
	);

	lh_register_location_rewrite_rules();
}

function lh_register_location_rewrite_rules() {
	$states = get_posts( array(
		'post_type'      => 'state',
		'posts_per_page' => -1,
		'post_status'    => 'publish',
		'orderby'        => 'name',
		'order'          => 'ASC',
		'no_found_rows'  => true,
	) );

	foreach ( $states as $state ) {
		$s    = preg_quote( $state->post_name, '/' );
		$name = $state->post_name;

		add_rewrite_rule(
			'^' . $s . '/?$',
			'index.php?post_type=state&state=' . $name . '&name=' . $name,
			'top'
		);

		$cities = get_posts( array(
			'post_type'      => 'city',
			'posts_per_page' => -1,
			'post_status'    => 'publish',
			'orderby'        => 'name',
			'order'          => 'ASC',
			'no_found_rows'  => true,
			'meta_query'     => array(
				array( 'key' => '_city_state', 'value' => $name ),
			),
		) );

		foreach ( $cities as $city ) {
			$c        = preg_quote( $city->post_name, '/' );
			$cityname = $city->post_name;

			add_rewrite_rule(
				'^' . $s . '/' . $c . '/?$',
				'index.php?post_type=city&state_slug=' . $name . '&city=' . $cityname . '&name=' . $cityname,
				'top'
			);
			add_rewrite_rule(
				'^' . $s . '/' . $c . '/home-service/?$',
				'index.php?state_slug=' . $name . '&city_slug=' . $cityname . '&post_type=home-services',
				'top'
			);
			add_rewrite_rule(
				'^' . $s . '/' . $c . '/home-service/([^/]+)/?$',
				'index.php?post_type=home-services&state_slug=' . $name . '&city_slug=' . $cityname . '&name=$matches[1]',
				'top'
			);
			add_rewrite_rule(
				'^' . $s . '/' . $c . '/home-service/([^/]+)/([^/]+)/?$',
				'index.php?post_type=home-services&state_slug=' . $name . '&city_slug=' . $cityname . '&name=$matches[2]',
				'top'
			);
		}
	}

	$orphan_cities = get_posts( array(
		'post_type'      => 'city',
		'posts_per_page' => -1,
		'post_status'    => 'publish',
		'orderby'        => 'name',
		'order'          => 'ASC',
		'no_found_rows'  => true,
		'meta_query'     => array(
			'relation' => 'OR',
			array( 'key' => '_city_state', 'compare' => 'NOT EXISTS' ),
			array( 'key' => '_city_state', 'value' => '', 'compare' => '=' ),
		),
	) );

	foreach ( $orphan_cities as $city ) {
		$c        = preg_quote( $city->post_name, '/' );
		$cityname = $city->post_name;

		add_rewrite_rule( '^' . $c . '/?$', 'index.php?post_type=city&city=' . $cityname . '&name=' . $cityname, 'top' );
		add_rewrite_rule( '^' . $c . '/home-service/?$', 'index.php?city_slug=' . $cityname . '&post_type=home-services', 'top' );
		add_rewrite_rule( '^' . $c . '/home-service/([^/]+)/?$', 'index.php?post_type=home-services&city_slug=' . $cityname . '&name=$matches[1]', 'top' );
		add_rewrite_rule( '^' . $c . '/home-service/([^/]+)/([^/]+)/?$', 'index.php?post_type=home-services&city_slug=' . $cityname . '&name=$matches[2]', 'top' );
	}
}

add_action( 'save_post_state', 'lh_schedule_rewrite_flush' );
add_action( 'save_post_city', 'lh_schedule_rewrite_flush' );

// ============================================================
// 6. QUERY VARIABLES
// ============================================================
add_filter( 'query_vars', 'add_custom_query_vars' );
function add_custom_query_vars( $vars ) {
	$vars[] = 'city_slug';
	$vars[] = 'state_slug';
	return $vars;
}

// ============================================================
// 7. PARSE REQUEST — State / City detection (CPT only, pages win)
// ============================================================
add_filter( 'request', 'check_state_city_slug_first' );
function check_state_city_slug_first( $query_vars ) {
	if ( is_admin() ) {
		return $query_vars;
	}

	$request_uri = lh_get_request_path();
	if ( '' === $request_uri ) {
		return $query_vars;
	}

	$reserved = array( 'wp-admin', 'wp-login', 'wp-content', 'wp-includes', 'feed', 'xmlrpc', 'sitemap_index.xml', 'sitemap.xml', 'home-service' );
	$parts    = explode( '/', $request_uri );

	if ( in_array( $parts[0], $reserved, true ) ) {
		return $query_vars;
	}

	if ( lh_query_is_location_hub( $query_vars ) ) {
		return lh_clean_page_query_vars( $query_vars );
	}

	if ( lh_is_home_service_path( $parts ) ) {
		$parsed = lh_parse_home_service_request( $parts, $query_vars );
		if ( lh_query_is_location_hub( $parsed ) || ! empty( $parsed['page_id'] ) || ! empty( $parsed['p'] ) ) {
			return lh_clean_page_query_vars( $parsed );
		}
	}

	if ( ! empty( $query_vars['pagename'] ) || ! empty( $query_vars['page_id'] ) ) {
		if ( lh_path_matches_wp_page( $request_uri ) ) {
			return $query_vars;
		}
		$query_vars = lh_clean_page_query_vars( $query_vars );
	}

	if ( ! empty( $query_vars['name'] ) && ! empty( $query_vars['post_type'] )
		&& ! in_array( $query_vars['post_type'], array( 'state', 'city', 'home-services' ), true ) ) {
		return $query_vars;
	}

	if ( lh_path_matches_wp_page( $request_uri ) ) {
		return $query_vars;
	}

	if ( 1 === count( $parts ) ) {
		if ( lh_get_state_by_slug( $parts[0] ) ) {
			return array( 'post_type' => 'state', 'state' => $parts[0], 'name' => $parts[0] );
		}
		$city = lh_get_city_by_slug( $parts[0] );
		if ( $city && ! get_post_meta( $city->ID, '_city_state', true ) ) {
			return array( 'post_type' => 'city', 'city' => $parts[0], 'name' => $parts[0] );
		}
	}

	if ( 2 === count( $parts ) && lh_get_city_by_slug( $parts[1], $parts[0] ) ) {
		return array(
			'post_type'  => 'city',
			'state_slug' => $parts[0],
			'city'       => $parts[1],
			'name'       => $parts[1],
		);
	}

	return $query_vars;
}

// ============================================================
// 7b. CITY SERVICES LISTING PAGE — /{state}/{city}/home-service/
// ============================================================
add_action( 'parse_request', 'lh_parse_request_for_location_hubs', 1 );
function lh_parse_request_for_location_hubs( $wp ) {
	if ( is_admin() ) {
		return;
	}
	$path = lh_get_request_path();
	if ( '' === $path ) {
		return;
	}
	$parts    = explode( '/', $path );
	$reserved = array( 'wp-admin', 'wp-login', 'wp-content', 'wp-includes', 'feed', 'xmlrpc', 'sitemap_index.xml', 'sitemap.xml', 'home-service' );
	if ( in_array( $parts[0], $reserved, true ) ) {
		return;
	}
	if ( lh_is_home_service_path( $parts ) ) {
		$parsed = lh_parse_home_service_request( $parts, $wp->query_vars );
		if ( lh_query_is_location_hub( $parsed ) || ! empty( $parsed['page_id'] ) || ! empty( $parsed['p'] ) ) {
			$wp->query_vars = array_merge( $wp->query_vars, lh_clean_page_query_vars( $parsed ) );
		}
	}
}

add_action( 'pre_get_posts', 'lh_city_services_listing_query', 1 );
function lh_city_services_listing_query( $query ) {
	if ( is_admin() || ! $query->is_main_query() || ! lh_is_city_services_listing( $query ) ) {
		return;
	}
	$city_slug  = $query->get( 'city_slug' ) ?: get_query_var( 'city_slug' );
	$state_slug = $query->get( 'state_slug' ) ?: get_query_var( 'state_slug' );
	$query->set( 'post_type', 'home-services' );
	$query->set( 'posts_per_page', -1 );
	$query->set( 'post_status', 'publish' );
	$query->set( 'orderby', 'menu_order' );
	$query->set( 'order', 'ASC' );
	$query->set( 'post_parent', 0 );
	$meta_query = array( 'relation' => 'AND', array( 'key' => '_service_city', 'value' => $city_slug ) );
	if ( $state_slug ) {
		$meta_query[] = array( 'key' => '_service_state', 'value' => $state_slug );
	}
	$query->set( 'meta_query', $meta_query );
	$query->is_404               = false;
	$query->is_archive           = true;
	$query->is_post_type_archive = true;
	$query->is_singular          = false;
	$query->is_single            = false;
}

add_action( 'template_redirect', 'lh_fix_city_services_listing_404', 0 );
function lh_fix_city_services_listing_404() {
	if ( ! lh_is_city_services_listing() ) {
		return;
	}
	global $wp_query;
	$wp_query->is_404               = false;
	$wp_query->is_archive           = true;
	$wp_query->is_post_type_archive = true;
	$wp_query->is_singular          = false;
	$wp_query->is_single            = false;
	status_header( 200 );
}

add_action( 'save_post_city', 'lh_auto_setup_city_services_listing', 99, 3 );
function lh_auto_setup_city_services_listing( $post_id, $post, $update ) {
	if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE || wp_is_post_revision( $post_id ) ) {
		return;
	}
	if ( 'publish' !== $post->post_status ) {
		return;
	}
	$state_slug = get_post_meta( $post_id, '_city_state', true );
	if ( ! $state_slug ) {
		delete_post_meta( $post_id, '_city_services_enabled' );
		delete_post_meta( $post_id, '_city_services_url' );
		return;
	}
	update_post_meta( $post_id, '_city_services_enabled', '1' );
	update_post_meta( $post_id, '_city_services_url', lh_get_city_services_listing_url( $post ) );
	if ( ! get_post_meta( $post_id, '_city_services_intro', true ) ) {
		$state_post = lh_get_state_by_slug( $state_slug );
		$state_name = $state_post ? $state_post->post_title : ucwords( str_replace( '-', ' ', $state_slug ) );
		update_post_meta( $post_id, '_city_services_intro', sprintf( 'Browse professional home services in %1$s, %2$s. Select a service below to learn more.', $post->post_title, $state_name ) );
	}
	lh_schedule_rewrite_flush();
}

add_action( 'save_post', 'lh_maybe_setup_city_services_after_meta_save', 99, 1 );
function lh_maybe_setup_city_services_after_meta_save( $post_id ) {
	if ( 'city' !== get_post_type( $post_id ) ) {
		return;
	}
	$post = get_post( $post_id );
	if ( $post && 'publish' === $post->post_status && get_post_meta( $post_id, '_city_state', true ) ) {
		lh_auto_setup_city_services_listing( $post_id, $post, true );
	}
}

function lh_regenerate_all_city_services_listings() {
	$cities = get_posts( array( 'post_type' => 'city', 'post_status' => 'publish', 'posts_per_page' => -1, 'no_found_rows' => true ) );
	foreach ( $cities as $city ) {
		lh_auto_setup_city_services_listing( $city->ID, $city, true );
	}
}

add_action( 'init', function () {
	if ( get_option( 'lh_db_version' ) === '1.4.0' ) {
		return;
	}
	lh_regenerate_all_city_services_listings();
	update_option( 'lh_db_version', '1.4.0' );
}, 99 );

// ============================================================
// ============================================================
// 7c. MANUAL PAGE LOCATION + SINGULAR SERVICE FIX
// ============================================================

/**
 * Find manually assigned city listing page.
 *
 * @return WP_Post|null
 */
function lh_find_city_listing_page( $state_slug, $city_slug ) {
	$pages = get_posts(
		array(
			'post_type'      => 'page',
			'post_status'    => 'publish',
			'posts_per_page' => 1,
			'name'           => '', // unused
			'no_found_rows'  => true,
			'meta_query'     => array(
				'relation' => 'AND',
				array(
					'key'   => '_lh_page_role',
					'value' => 'listing',
				),
				array(
					'key'   => '_service_state',
					'value' => $state_slug,
				),
				array(
					'key'   => '_service_city',
					'value' => $city_slug,
				),
			),
		)
	);

	return ! empty( $pages ) ? $pages[0] : null;
}

/**
 * Find a location-assigned page by slug + city/state.
 *
 * @return WP_Post|null
 */
function lh_find_location_page( $state_slug, $city_slug, $slug ) {
	$meta_query = array(
		'relation' => 'AND',
		array(
			'key'   => '_service_city',
			'value' => $city_slug,
		),
	);

	if ( $state_slug ) {
		$meta_query[] = array(
			'key'   => '_service_state',
			'value' => $state_slug,
		);
	}

	$pages = get_posts(
		array(
			'post_type'      => 'page',
			'name'           => $slug,
			'post_status'    => 'publish',
			'posts_per_page' => 1,
			'no_found_rows'  => true,
			'meta_query'     => $meta_query,
		)
	);

	return ! empty( $pages ) ? $pages[0] : null;
}

/**
 * Get home-services post by slug, optionally scoped to location meta.
 *
 * @return WP_Post|null
 */
function lh_get_home_service_by_slug( $slug, $state_slug = '', $city_slug = '' ) {
	if ( '' === $slug ) {
		return null;
	}

	$base_args = array(
		'post_type'              => 'home-services',
		'name'                   => $slug,
		'post_status'            => 'publish',
		'posts_per_page'         => 1,
		'no_found_rows'          => true,
		'update_post_meta_cache' => false,
	);

	if ( $city_slug || $state_slug ) {
		$meta_query = array( 'relation' => 'AND' );
		if ( $city_slug ) {
			$meta_query[] = array(
				'key'   => '_service_city',
				'value' => $city_slug,
			);
		}
		if ( $state_slug ) {
			$meta_query[] = array(
				'key'   => '_service_state',
				'value' => $state_slug,
			);
		}

		$posts = get_posts(
			array_merge(
				$base_args,
				array( 'meta_query' => $meta_query )
			)
		);

		if ( ! empty( $posts ) ) {
			return $posts[0];
		}
	}

	$posts = get_posts( $base_args );

	return ! empty( $posts ) ? $posts[0] : null;
}

/**
 * Resolve listing URL — manual page first, else virtual archive.
 *
 * @return array|null
 */
function lh_resolve_city_services_listing_query( $state_slug, $city_slug ) {
	if ( ! lh_get_city_by_slug( $city_slug, $state_slug ) ) {
		return null;
	}

	$listing_page = lh_find_city_listing_page( $state_slug, $city_slug );
	if ( $listing_page ) {
		return array(
			'page_id'    => $listing_page->ID,
			'city_slug'  => $city_slug,
			'state_slug' => $state_slug,
		);
	}

	return array(
		'post_type'  => 'home-services',
		'state_slug' => $state_slug,
		'city_slug'  => $city_slug,
	);
}

/**
 * Resolve singular service URL — home-services CPT or manual page.
 *
 * @return array|null
 */
function lh_resolve_home_service_singular_query( $state_slug, $city_slug, $slug ) {
	if ( ! lh_get_city_by_slug( $city_slug, $state_slug ) ) {
		return null;
	}

	$service = lh_get_home_service_by_slug( $slug, $state_slug, $city_slug );
	if ( $service ) {
		return array(
			'p'          => $service->ID,
			'post_type'  => 'home-services',
			'name'       => $slug,
			'state_slug' => $state_slug,
			'city_slug'  => $city_slug,
		);
	}

	$page = lh_find_location_page( $state_slug, $city_slug, $slug );
	if ( $page ) {
		return array(
			'page_id'    => $page->ID,
			'state_slug' => $state_slug,
			'city_slug'  => $city_slug,
		);
	}

	// Last resort — let WP try by slug (prevents hard 404 if meta mismatch).
	return array(
		'post_type'  => 'home-services',
		'name'       => $slug,
		'state_slug' => $state_slug,
		'city_slug'  => $city_slug,
	);
}

/**
 * Build public URL for a location-assigned page.
 */
function lh_get_page_location_url( $post_id ) {
	$post = get_post( $post_id );
	if ( ! $post || 'page' !== $post->post_type ) {
		return '';
	}

	$state_slug = get_post_meta( $post_id, '_service_state', true );
	$city_slug  = get_post_meta( $post_id, '_service_city', true );
	$role       = get_post_meta( $post_id, '_lh_page_role', true );

	if ( ! $city_slug || ! $state_slug ) {
		return '';
	}

	if ( 'listing' === $role ) {
		return home_url( $state_slug . '/' . $city_slug . '/home-service/' );
	}

	return home_url( $state_slug . '/' . $city_slug . '/home-service/' . $post->post_name . '/' );
}

/**
 * Auto-set state from city and parent listing page for service pages.
 */
function lh_sync_page_location_hierarchy( $post_id ) {
	if ( 'page' !== get_post_type( $post_id ) ) {
		return;
	}

	$city_slug  = get_post_meta( $post_id, '_service_city', true );
	$state_slug = get_post_meta( $post_id, '_service_state', true );
	$role       = get_post_meta( $post_id, '_lh_page_role', true );

	if ( $city_slug && ! $state_slug ) {
		$city = lh_get_city_by_slug( $city_slug );
		if ( $city ) {
			$state_slug = get_post_meta( $city->ID, '_city_state', true );
			if ( $state_slug ) {
				update_post_meta( $post_id, '_service_state', $state_slug );
			}
		}
	}

	if ( ! $city_slug || ! $state_slug ) {
		return;
	}

	if ( 'listing' === $role ) {
		wp_update_post(
			array(
				'ID'          => $post_id,
				'post_parent' => 0,
			)
		);
		return;
	}

	if ( 'service' === $role ) {
		$listing = lh_find_city_listing_page( $state_slug, $city_slug );
		if ( $listing && (int) $listing->ID !== (int) $post_id ) {
			wp_update_post(
				array(
					'ID'          => $post_id,
					'post_parent' => $listing->ID,
				)
			);
		}
	}
}

add_filter( 'page_link', 'lh_filter_location_page_link', 10, 2 );
function lh_filter_location_page_link( $link, $post_id ) {
	$url = lh_get_page_location_url( $post_id );
	return $url ? $url : $link;
}

add_filter( 'get_sample_permalink_html', 'lh_filter_location_page_permalink_preview', 10, 2 );
function lh_filter_location_page_permalink_preview( $return, $post_id ) {
	$url = lh_get_page_location_url( $post_id );
	if ( ! $url ) {
		return $return;
	}
	return preg_replace( '|>[^<]+<|', '>' . $url . '<', $return );
}

add_action( 'wp', 'lh_inject_page_location_query_vars' );
function lh_inject_page_location_query_vars() {
	if ( ! is_singular( 'page' ) ) {
		return;
	}

	$page_id = get_queried_object_id();
	$state   = get_post_meta( $page_id, '_service_state', true );
	$city    = get_post_meta( $page_id, '_service_city', true );

	if ( $state ) {
		set_query_var( 'state_slug', $state );
	}
	if ( $city ) {
		set_query_var( 'city_slug', $city );
	}
}

add_action( 'pre_get_posts', 'lh_fix_singular_home_service_query', 2 );
function lh_fix_singular_home_service_query( $query ) {
	if ( is_admin() || ! $query->is_main_query() ) {
		return;
	}

	$name      = $query->get( 'name' );
	$post_type = $query->get( 'post_type' );
	$city_slug = $query->get( 'city_slug' ) ?: get_query_var( 'city_slug' );
	$p         = $query->get( 'p' );

	if ( ! $city_slug || ! $name ) {
		return;
	}

	if ( $p ) {
		$query->set( 'p', $p );
		$query->set( 'post_type', 'home-services' );
		$query->is_singular          = true;
		$query->is_single            = true;
		$query->is_archive           = false;
		$query->is_post_type_archive = false;
		$query->is_404               = false;
		return;
	}

	if ( 'home-services' === $post_type ) {
		$query->is_singular          = true;
		$query->is_single            = true;
		$query->is_archive           = false;
		$query->is_post_type_archive = false;
	}
}

add_action( 'template_redirect', 'lh_fix_singular_home_service_404', 1 );
function lh_fix_singular_home_service_404() {
	$name      = get_query_var( 'name' );
	$city_slug = get_query_var( 'city_slug' );
	$post_type = get_query_var( 'post_type' );

	if ( ! $name || ! $city_slug || 'home-services' !== $post_type ) {
		return;
	}

	global $wp_query;

	if ( $wp_query->have_posts() && ! $wp_query->is_404 ) {
		return;
	}

	$service = lh_get_home_service_by_slug(
		$name,
		get_query_var( 'state_slug' ),
		$city_slug
	);

	if ( ! $service ) {
		return;
	}

	$wp_query->posts                 = array( $service );
	$wp_query->post                  = $service;
	$wp_query->post_count            = 1;
	$wp_query->queried_object        = $service;
	$wp_query->queried_object_id     = $service->ID;
	$wp_query->found_posts           = 1;
	$wp_query->max_num_pages         = 1;
	$wp_query->is_404                = false;
	$wp_query->is_singular           = true;
	$wp_query->is_single             = true;
	$wp_query->is_archive            = false;
	$wp_query->is_post_type_archive  = false;

	status_header( 200 );
}

function lh_parse_home_service_request( $parts, $query_vars ) {
	if ( isset( $parts[1] ) && 'home-service' === $parts[1] ) {
		$city_slug = $parts[0];
		$city      = lh_get_city_by_slug( $city_slug );
		if ( ! $city || get_post_meta( $city->ID, '_city_state', true ) ) {
			return $query_vars;
		}
		if ( 2 === count( $parts ) ) {
			return array( 'post_type' => 'home-services', 'city_slug' => $city_slug );
		}
		return array( 'post_type' => 'home-services', 'city_slug' => $city_slug, 'name' => end( $parts ) );
	}

	$state_slug = $parts[0];
	$city_slug  = $parts[1];

	if ( ! lh_get_state_by_slug( $state_slug ) || ! lh_get_city_by_slug( $city_slug, $state_slug ) ) {
		return $query_vars;
	}

	if ( 3 === count( $parts ) ) {
		$listing = lh_resolve_city_services_listing_query( $state_slug, $city_slug );
		return $listing ? $listing : $query_vars;
	}

	if ( count( $parts ) >= 4 ) {
		$slug   = end( $parts );
		$parsed = lh_resolve_home_service_singular_query( $state_slug, $city_slug, $slug );
		return $parsed ? $parsed : $query_vars;
	}

	return $query_vars;
}

// ============================================================
// 8. TEMPLATE LOADER
// ============================================================
add_filter( 'template_include', 'city_service_template_router', 20 );
function city_service_template_router( $template ) {
	$city_slug  = get_query_var( 'city_slug' );
	$state_slug = get_query_var( 'state_slug' );
	$post_type  = get_query_var( 'post_type' );

	if ( is_singular( 'state' ) ) {
		$t = get_stylesheet_directory() . '/template-state.php';
		if ( file_exists( $t ) ) {
			return $t;
		}
	}

	if ( is_singular( 'city' ) ) {
		$t = get_stylesheet_directory() . '/template-city.php';
		if ( file_exists( $t ) ) {
			return $t;
		}
	}

	if ( $city_slug && ( lh_is_city_services_listing() || ( 'home-services' === $post_type && ! is_singular( 'home-services' ) ) ) ) {
		$t = get_stylesheet_directory() . '/template-city-services.php';
		if ( file_exists( $t ) ) {
			return $t;
		}
	}

	if ( is_singular( 'home-services' ) ) {
		$t = locate_template( array( 'single-home-services.php', 'single.php' ) );
		if ( $t ) {
			return $t;
		}
	}

	return $template;
}

// ============================================================
// 9. SLUG CONFLICT PREVENTION
// ============================================================
add_filter( 'wp_unique_post_slug', 'prevent_slug_conflicts', 10, 6 );
function prevent_slug_conflicts( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) {
	if ( 'city' === $post_type && get_page_by_path( $slug, OBJECT, 'page' ) ) {
		return $slug . '-city';
	}
	if ( 'state' === $post_type && get_page_by_path( $slug, OBJECT, 'page' ) ) {
		return $slug . '-state';
	}
	return $slug;
}

// ============================================================
// 10. FORCE STATE PERMALINK (NO /state/ PREFIX)
// ============================================================
add_filter( 'post_type_link', 'remove_state_prefix_from_permalink', 10, 2 );
function remove_state_prefix_from_permalink( $url, $post ) {
	if ( 'state' === $post->post_type ) {
		return home_url( $post->post_name . '/' );
	}
	return $url;
}

add_filter( 'get_sample_permalink_html', 'fix_state_permalink_preview', 10, 2 );
function fix_state_permalink_preview( $return, $post_id ) {
	$post = get_post( $post_id );
	if ( $post && 'state' === $post->post_type ) {
		$return = preg_replace( '|>[^<]+<|', '>' . home_url( $post->post_name . '/' ) . '<', $return );
	}
	return $return;
}

// ============================================================
// 11. FORCE CITY PERMALINK → /{state}/{city}/
// ============================================================
add_filter( 'post_type_link', 'remove_city_prefix_from_permalink', 10, 2 );
function remove_city_prefix_from_permalink( $url, $post ) {
	if ( 'city' !== $post->post_type ) {
		return $url;
	}
	$state_slug = get_post_meta( $post->ID, '_city_state', true );
	if ( $state_slug ) {
		return home_url( $state_slug . '/' . $post->post_name . '/' );
	}
	return home_url( $post->post_name . '/' );
}

add_filter( 'get_sample_permalink_html', 'fix_city_permalink_preview', 10, 2 );
function fix_city_permalink_preview( $return, $post_id ) {
	$post = get_post( $post_id );
	if ( $post && 'city' === $post->post_type ) {
		$state_slug = get_post_meta( $post_id, '_city_state', true );
		$url        = $state_slug
			? home_url( $state_slug . '/' . $post->post_name . '/' )
			: home_url( $post->post_name . '/' );
		$return = preg_replace( '|>[^<]+<|', '>' . $url . '<', $return );
	}
	return $return;
}

// ============================================================
// 12. SERVICE PERMALINK → /{state}/{city}/home-service/{slug}/
// ============================================================
add_filter( 'post_type_link', 'modify_service_permalink_for_city', 10, 2 );
function modify_service_permalink_for_city( $url, $post ) {
	if ( 'home-services' !== $post->post_type ) {
		return $url;
	}

	$city_slug  = get_post_meta( $post->ID, '_service_city', true );
	$state_slug = get_post_meta( $post->ID, '_service_state', true );

	if ( $city_slug && $state_slug ) {
		return home_url( $state_slug . '/' . $city_slug . '/home-service/' . $post->post_name . '/' );
	}
	if ( $city_slug ) {
		return home_url( $city_slug . '/home-service/' . $post->post_name . '/' );
	}
	return $url;
}

// ============================================================
// 13. STATE SELECTOR META BOX FOR CITY
// ============================================================
add_action( 'add_meta_boxes', 'add_city_state_meta_box' );
function add_city_state_meta_box() {
	add_meta_box( 'city_state_selector', '🗺️ City State', 'city_state_selector_callback', 'city', 'side', 'high' );
}

function city_state_selector_callback( $post ) {
	wp_nonce_field( 'save_city_state', 'city_state_nonce' );
	$selected = get_post_meta( $post->ID, '_city_state', true );
	$states   = get_posts( array( 'post_type' => 'state', 'posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC', 'post_status' => 'publish' ) );

	echo '<select name="city_state" style="width:100%;padding:4px;font-size:14px;">';
	echo '<option value="">— No State —</option>';
	foreach ( $states as $state ) {
		printf( '<option value="%s" %s>🗺️ %s</option>', esc_attr( $state->post_name ), selected( $selected, $state->post_name, false ), esc_html( $state->post_title ) );
	}
	echo '</select>';

	$url = $selected ? home_url( $selected . '/' . $post->post_name . '/' ) : home_url( $post->post_name . '/' );
	echo '<p style="margin-top:8px;font-size:11px;color:#2271b1;word-break:break-all;"><strong>City URL:</strong><br>' . esc_url( $url ) . '</p>';
	$listing_url = lh_get_city_services_listing_url( $post );
	if ( $listing_url ) {
		echo '<p style="margin-top:8px;font-size:11px;color:#2271b1;word-break:break-all;"><strong>Services Listing URL:</strong><br>' . esc_url( $listing_url ) . '</p>';
		echo '<p class="description">Create a Page, set role to City Services Listing, and assign this city.</p>';
	}
}

add_action( 'save_post', 'save_city_state_meta' );
function save_city_state_meta( $post_id ) {
	if ( ! isset( $_POST['city_state_nonce'] ) || ! wp_verify_nonce( $_POST['city_state_nonce'], 'save_city_state' ) ) {
		return;
	}
	if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
		return;
	}
	if ( ! current_user_can( 'edit_post', $post_id ) ) {
		return;
	}
	if ( 'city' !== get_post_type( $post_id ) ) {
		return;
	}
	if ( isset( $_POST['city_state'] ) ) {
		$val = sanitize_text_field( $_POST['city_state'] );
		$val ? update_post_meta( $post_id, '_city_state', $val ) : delete_post_meta( $post_id, '_city_state' );
	}
}

// ============================================================
// 14. LOCATION SELECTOR — home-services + Pages
// ============================================================
add_action( 'add_meta_boxes', 'add_all_location_selector_meta_boxes' );
function add_all_location_selector_meta_boxes() {
	add_meta_box( 'location_selector', '📍 Service Location', 'location_selector_callback', 'home-services', 'side', 'high' );
	add_meta_box( 'location_selector', '📍 Page Location', 'page_location_selector_callback', 'page', 'side', 'high' );
}

function page_location_selector_callback( $post ) {
	wp_nonce_field( 'save_location_selector', 'location_selector_nonce' );
	$selected_state = get_post_meta( $post->ID, '_service_state', true );
	$selected_city  = get_post_meta( $post->ID, '_service_city', true );
	$page_role      = get_post_meta( $post->ID, '_lh_page_role', true );
	$cities         = get_posts( array( 'post_type' => 'city', 'posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC', 'post_status' => 'publish' ) );

	echo '<label style="font-weight:600;font-size:12px;display:block;margin-bottom:4px;">Page Role</label>';
	echo '<select name="lh_page_role" style="width:100%;padding:4px;font-size:13px;margin-bottom:10px;">';
	echo '<option value="">— Not a location page —</option>';
	echo '<option value="listing"' . selected( $page_role, 'listing', false ) . '>City Services Listing</option>';
	echo '<option value="service"' . selected( $page_role, 'service', false ) . '>Service Page (child of listing)</option>';
	echo '</select>';

	echo '<label style="font-weight:600;font-size:12px;display:block;margin-bottom:4px;">📍 City</label>';
	echo '<select name="service_city" id="lh_page_city_select" style="width:100%;padding:4px;font-size:13px;margin-bottom:10px;">';
	echo '<option value="">— Select City —</option>';
	foreach ( $cities as $city ) {
		$city_state = get_post_meta( $city->ID, '_city_state', true );
		printf( '<option value="%s" data-state="%s" %s>📍 %s</option>', esc_attr( $city->post_name ), esc_attr( $city_state ), selected( $selected_city, $city->post_name, false ), esc_html( $city->post_title ) );
	}
	echo '</select>';

	echo '<label style="font-weight:600;font-size:12px;display:block;margin-bottom:4px;">🗺️ State (auto from city)</label>';
	echo '<input type="text" id="lh_page_state_display" readonly style="width:100%;padding:4px;font-size:13px;background:#f6f7f7;" value="' . esc_attr( $selected_state ? ucwords( str_replace( '-', ' ', $selected_state ) ) : '' ) . '">';
	echo '<input type="hidden" name="service_state" id="lh_page_state_input" value="' . esc_attr( $selected_state ) . '">';

	$url = lh_get_page_location_url( $post->ID );
	if ( $url ) {
		echo '<p style="margin-top:8px;font-size:11px;color:#2271b1;word-break:break-all;"><strong>URL:</strong><br>' . esc_url( $url ) . '</p>';
	}
	?>
	<script>
	(function($){
		function syncState(){ var s=$('#lh_page_city_select option:selected').data('state')||''; $('#lh_page_state_input').val(s); $('#lh_page_state_display').val(s?s.replace(/-/g,' ').replace(/\b\w/g,function(l){return l.toUpperCase();}):''); }
		$('#lh_page_city_select').on('change', syncState); syncState();
	})(jQuery);
	</script>
	<?php
}

function location_selector_callback( $post ) {
	wp_nonce_field( 'save_location_selector', 'location_selector_nonce' );
	$selected_state = get_post_meta( $post->ID, '_service_state', true );
	$selected_city  = get_post_meta( $post->ID, '_service_city', true );

	$states = get_posts( array( 'post_type' => 'state', 'posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC', 'post_status' => 'publish' ) );
	$cities = get_posts( array( 'post_type' => 'city', 'posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC', 'post_status' => 'publish' ) );

	echo '<label style="font-weight:600;font-size:12px;display:block;margin-bottom:4px;">📍 City</label>';
	echo '<select name="service_city" id="service_city_select" style="width:100%;padding:4px;font-size:13px;margin-bottom:10px;">';
	echo '<option value="">— All Cities (Canonical) —</option>';
	foreach ( $cities as $city ) {
		$city_state = get_post_meta( $city->ID, '_city_state', true );
		printf( '<option value="%s" data-state="%s" %s>📍 %s</option>', esc_attr( $city->post_name ), esc_attr( $city_state ), selected( $selected_city, $city->post_name, false ), esc_html( $city->post_title ) );
	}
	echo '</select>';
	echo '<label style="font-weight:600;font-size:12px;display:block;margin-bottom:4px;">🗺️ State (auto from city)</label>';
	echo '<input type="text" id="service_state_display" readonly style="width:100%;padding:4px;font-size:13px;background:#f6f7f7;" value="' . esc_attr( $selected_state ? ucwords( str_replace( '-', ' ', $selected_state ) ) : '' ) . '">';
	echo '<input type="hidden" name="service_state" id="service_state_select" value="' . esc_attr( $selected_state ) . '">';

	if ( $selected_state && $selected_city ) {
		$preview = home_url( $selected_state . '/' . $selected_city . '/home-service/' . $post->post_name . '/' );
	} elseif ( $selected_city ) {
		$preview = home_url( $selected_city . '/home-service/' . $post->post_name . '/' );
	} else {
		$preview = home_url( 'home-service/' . $post->post_name . '/' );
	}
	echo '<p style="margin-top:8px;font-size:11px;color:#2271b1;word-break:break-all;"><strong>URL:</strong><br>' . esc_url( $preview ) . '</p>';
	?>
	<script>
	(function($){
		function syncState(){ var s=$('#service_city_select option:selected').data('state')||''; $('#service_state_select').val(s); $('#service_state_display').val(s?s.replace(/-/g,' ').replace(/\b\w/g,function(l){return l.toUpperCase();}):''); }
		$('#service_city_select').on('change', syncState); syncState();
	})(jQuery);
	</script>
	<?php
}

// ============================================================
// 15. SAVE LOCATION META (home-services + pages)
// ============================================================
add_action( 'save_post', 'save_location_selector' );
function save_location_selector( $post_id ) {
	if ( ! isset( $_POST['location_selector_nonce'] ) || ! wp_verify_nonce( $_POST['location_selector_nonce'], 'save_location_selector' ) ) {
		return;
	}
	if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
		return;
	}
	if ( ! current_user_can( 'edit_post', $post_id ) ) {
		return;
	}
	if ( ! in_array( get_post_type( $post_id ), array( 'home-services', 'page' ), true ) ) {
		return;
	}

	if ( ! empty( $_POST['service_city'] ) ) {
		$city = lh_get_city_by_slug( sanitize_text_field( wp_unslash( $_POST['service_city'] ) ) );
		if ( $city ) {
			$city_state = get_post_meta( $city->ID, '_city_state', true );
			if ( $city_state ) {
				$_POST['service_state'] = $city_state;
			}
		}
	}

	if ( 'page' === get_post_type( $post_id ) && isset( $_POST['lh_page_role'] ) ) {
		$role = sanitize_text_field( wp_unslash( $_POST['lh_page_role'] ) );
		$role ? update_post_meta( $post_id, '_lh_page_role', $role ) : delete_post_meta( $post_id, '_lh_page_role' );
	}

	if ( isset( $_POST['service_state'] ) ) {
		$state = sanitize_text_field( wp_unslash( $_POST['service_state'] ) );
		$state ? update_post_meta( $post_id, '_service_state', $state ) : delete_post_meta( $post_id, '_service_state' );
	}
	if ( isset( $_POST['service_city'] ) ) {
		$city = sanitize_text_field( wp_unslash( $_POST['service_city'] ) );
		$city ? update_post_meta( $post_id, '_service_city', $city ) : delete_post_meta( $post_id, '_service_city' );
	}

	if ( 'page' === get_post_type( $post_id ) ) {
		lh_sync_page_location_hierarchy( $post_id );
	}
}

// ============================================================
// 16. ADMIN COLUMNS — State + City
// ============================================================
add_filter( 'manage_home-services_posts_columns', 'add_location_admin_columns' );
function add_location_admin_columns( $columns ) {
	$new = array();
	foreach ( $columns as $k => $v ) {
		$new[ $k ] = $v;
		if ( 'title' === $k ) {
			$new['service_state'] = '🗺️ State';
			$new['service_city']  = '📍 City';
		}
	}
	return $new;
}

add_action( 'manage_home-services_posts_custom_column', 'display_location_admin_columns', 10, 2 );
function display_location_admin_columns( $column, $post_id ) {
	if ( 'service_state' === $column ) {
		$state = get_post_meta( $post_id, '_service_state', true );
		echo $state
			? '<span data-state-slug="' . esc_attr( $state ) . '">🗺️ ' . esc_html( ucwords( str_replace( '-', ' ', $state ) ) ) . '</span>'
			: '<span data-state-slug="" style="color:#999;">—</span>';
	}
	if ( 'service_city' === $column ) {
		$city = get_post_meta( $post_id, '_service_city', true );
		echo $city
			? '<span data-city-slug="' . esc_attr( $city ) . '">📍 ' . esc_html( ucwords( str_replace( '-', ' ', $city ) ) ) . '</span>'
			: '<span data-city-slug="" style="color:#999;">🌐 All</span>';
	}
}

// ============================================================
// 17. ADMIN FILTER DROPDOWNS — State + City
// ============================================================
add_action( 'restrict_manage_posts', 'add_location_filter_dropdowns' );
function add_location_filter_dropdowns( $post_type ) {
	if ( 'home-services' !== $post_type ) {
		return;
	}

	$states = get_posts( array( 'post_type' => 'state', 'posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC', 'post_status' => 'publish' ) );
	$cities = get_posts( array( 'post_type' => 'city', 'posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC', 'post_status' => 'publish' ) );

	$sel_state = isset( $_GET['filter_state'] ) ? sanitize_text_field( wp_unslash( $_GET['filter_state'] ) ) : '';
	$sel_city  = isset( $_GET['service_city'] ) ? sanitize_text_field( wp_unslash( $_GET['service_city'] ) ) : '';

	echo '<select name="filter_state"><option value="">🗺️ All States</option>';
	foreach ( $states as $s ) {
		printf( '<option value="%s" %s>🗺️ %s</option>', esc_attr( $s->post_name ), selected( $sel_state, $s->post_name, false ), esc_html( $s->post_title ) );
	}
	echo '</select> ';

	echo '<select name="service_city"><option value="">📍 All Cities</option>';
	foreach ( $cities as $c ) {
		$c_state = get_post_meta( $c->ID, '_city_state', true );
		printf( '<option value="%s" data-state="%s" %s>📍 %s</option>', esc_attr( $c->post_name ), esc_attr( $c_state ), selected( $sel_city, $c->post_name, false ), esc_html( $c->post_title ) );
	}
	echo '</select>';
}

add_action( 'pre_get_posts', 'filter_by_location_admin' );
function filter_by_location_admin( $query ) {
	if ( ! is_admin() || ! $query->is_main_query() || 'home-services' !== $query->get( 'post_type' ) ) {
		return;
	}

	$meta_query = array( 'relation' => 'AND' );
	if ( ! empty( $_GET['filter_state'] ) ) {
		$meta_query[] = array( 'key' => '_service_state', 'value' => sanitize_text_field( wp_unslash( $_GET['filter_state'] ) ) );
	}
	if ( ! empty( $_GET['service_city'] ) ) {
		$meta_query[] = array( 'key' => '_service_city', 'value' => sanitize_text_field( wp_unslash( $_GET['service_city'] ) ) );
	}
	if ( count( $meta_query ) > 1 ) {
		$query->set( 'meta_query', $meta_query );
	}
}

// ============================================================
// 18. BLOCK /city/ AND /state/ RAW ARCHIVE URLS
// ============================================================
add_action( 'template_redirect', 'block_raw_cpt_urls' );
function block_raw_cpt_urls() {
	$uri = isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '';
	if (
		false !== strpos( $uri, '/city/' ) || is_post_type_archive( 'city' ) ||
		false !== strpos( $uri, '/state/' ) || is_post_type_archive( 'state' )
	) {
		global $wp_query;
		$wp_query->set_404();
		status_header( 404 );
		get_template_part( '404' );
		exit;
	}
}

// ============================================================
// 19. YOAST SEO INTEGRATION
// ============================================================
add_action( 'wp', 'inject_location_query_vars_from_post_meta' );
function inject_location_query_vars_from_post_meta() {
	if ( ! is_singular( 'home-services' ) ) {
		return;
	}
	global $post;
	if ( ! get_query_var( 'city_slug' ) ) {
		$meta_city = get_post_meta( $post->ID, '_service_city', true );
		if ( $meta_city ) {
			set_query_var( 'city_slug', $meta_city );
		}
	}
	if ( ! get_query_var( 'state_slug' ) ) {
		$meta_state = get_post_meta( $post->ID, '_service_state', true );
		if ( $meta_state ) {
			set_query_var( 'state_slug', $meta_state );
		}
	}
}

add_filter( 'wpseo_breadcrumb_links', 'fix_yoast_breadcrumbs_for_city_services' );
function fix_yoast_breadcrumbs_for_city_services( $crumbs ) {
	$city_slug  = get_query_var( 'city_slug' );
	$state_slug = get_query_var( 'state_slug' );
	if ( ! $city_slug && ! $state_slug ) {
		return $crumbs;
	}

	$state_post = $state_slug ? get_posts( array( 'post_type' => 'state', 'name' => $state_slug, 'posts_per_page' => 1, 'post_status' => 'publish' ) ) : array();
	$city_post  = $city_slug ? get_posts( array( 'post_type' => 'city', 'name' => $city_slug, 'posts_per_page' => 1, 'post_status' => 'publish' ) ) : array();

	$state_name = ! empty( $state_post ) ? $state_post[0]->post_title : ucwords( str_replace( '-', ' ', $state_slug ) );
	$city_name  = ! empty( $city_post ) ? $city_post[0]->post_title : ucwords( str_replace( '-', ' ', $city_slug ) );

	$state_url        = $state_slug ? home_url( $state_slug . '/' ) : '';
	$city_url         = $state_slug ? home_url( $state_slug . '/' . $city_slug . '/' ) : home_url( $city_slug . '/' );
	$city_service_url = $state_slug ? home_url( $state_slug . '/' . $city_slug . '/home-service/' ) : home_url( $city_slug . '/home-service/' );

	$new_crumbs = array(
		array( 'text' => 'Home', 'url' => home_url( '/' ), 'allow_html' => false ),
	);
	if ( $state_slug ) {
		$new_crumbs[] = array( 'text' => $state_name, 'url' => $state_url, 'allow_html' => false );
	}
	if ( $city_slug ) {
		$new_crumbs[] = array( 'text' => $city_name, 'url' => $city_url, 'allow_html' => false );
	}
	if ( is_singular( 'home-services' ) ) {
		$new_crumbs[] = array( 'text' => 'Home Services', 'url' => $city_service_url, 'allow_html' => false );
		$new_crumbs[] = array( 'text' => get_the_title(), 'url' => '', 'allow_html' => false );
	} else {
		$new_crumbs[] = array( 'text' => 'Home Services', 'url' => '', 'allow_html' => false );
	}
	return $new_crumbs;
}

add_filter( 'wpseo_title', 'fix_yoast_title_for_city_services' );
function fix_yoast_title_for_city_services( $title ) {
	$city_slug  = get_query_var( 'city_slug' );
	$state_slug = get_query_var( 'state_slug' );
	if ( ! $city_slug ) {
		return $title;
	}

	$city_post  = get_posts( array( 'post_type' => 'city', 'name' => $city_slug, 'posts_per_page' => 1, 'post_status' => 'publish' ) );
	$state_post = $state_slug ? get_posts( array( 'post_type' => 'state', 'name' => $state_slug, 'posts_per_page' => 1, 'post_status' => 'publish' ) ) : array();

	$city_name  = ! empty( $city_post ) ? $city_post[0]->post_title : ucwords( str_replace( '-', ' ', $city_slug ) );
	$state_name = ! empty( $state_post ) ? $state_post[0]->post_title : ucwords( str_replace( '-', ' ', $state_slug ) );
	$location   = $city_name . ( $state_name ? ', ' . $state_name : '' );
	$sep        = ' | ';

	if ( ! is_singular( 'home-services' ) ) {
		return 'Home Services in ' . $location . $sep . get_bloginfo( 'name' );
	}
	return get_the_title() . ' in ' . $location . $sep . get_bloginfo( 'name' );
}

add_filter( 'wpseo_metadesc', 'fix_yoast_metadesc_for_city_services' );
function fix_yoast_metadesc_for_city_services( $desc ) {
	$city_slug  = get_query_var( 'city_slug' );
	$state_slug = get_query_var( 'state_slug' );
	if ( ! $city_slug ) {
		return $desc;
	}

	$city_post  = get_posts( array( 'post_type' => 'city', 'name' => $city_slug, 'posts_per_page' => 1, 'post_status' => 'publish' ) );
	$state_post = $state_slug ? get_posts( array( 'post_type' => 'state', 'name' => $state_slug, 'posts_per_page' => 1, 'post_status' => 'publish' ) ) : array();

	$city_name  = ! empty( $city_post ) ? $city_post[0]->post_title : ucwords( str_replace( '-', ' ', $city_slug ) );
	$state_name = ! empty( $state_post ) ? $state_post[0]->post_title : ucwords( str_replace( '-', ' ', $state_slug ) );
	$location   = $city_name . ( $state_name ? ', ' . $state_name : '' );

	if ( ! is_singular( 'home-services' ) ) {
		return 'Professional home services in ' . $location . '. Exterior, interior, restoration & general services. Licensed & insured. Free estimates.';
	}
	if ( is_singular( 'home-services' ) && empty( $desc ) ) {
		return 'Professional ' . get_the_title() . ' services in ' . $location . '. Licensed & insured contractors. Free estimates available.';
	}
	return $desc;
}

add_filter( 'wpseo_canonical', 'fix_yoast_canonical_for_city_services' );
function fix_yoast_canonical_for_city_services( $canonical ) {
	$city_slug  = get_query_var( 'city_slug' );
	$state_slug = get_query_var( 'state_slug' );
	if ( ! $city_slug || is_singular() ) {
		return $canonical;
	}
	return $state_slug
		? home_url( $state_slug . '/' . $city_slug . '/home-service/' )
		: home_url( $city_slug . '/home-service/' );
}

add_filter( 'wpseo_schema_graph', 'add_yoast_schema_for_location_pages', 10, 2 );
function add_yoast_schema_for_location_pages( $graph, $context ) {
	$city_slug  = get_query_var( 'city_slug' );
	$state_slug = get_query_var( 'state_slug' );

	if ( is_singular( 'state' ) ) {
		$graph[] = array(
			'@type'       => 'LocalBusiness',
			'name'        => get_bloginfo( 'name' ) . ' - ' . get_the_title(),
			'description' => 'Professional home services across ' . get_the_title(),
			'areaServed'  => get_the_title(),
		);
	}
	if ( is_singular( 'city' ) ) {
		$state_slug_meta = get_post_meta( get_the_ID(), '_city_state', true );
		$state_name      = $state_slug_meta ? ucwords( str_replace( '-', ' ', $state_slug_meta ) ) : '';
		$graph[] = array(
			'@type'       => 'LocalBusiness',
			'name'        => get_bloginfo( 'name' ) . ' - ' . get_the_title(),
			'description' => 'Professional home services in ' . get_the_title() . ( $state_name ? ', ' . $state_name : '' ),
			'areaServed'  => get_the_title(),
		);
	}
	if ( $city_slug && is_singular( 'home-services' ) ) {
		$city_name  = ucwords( str_replace( '-', ' ', $city_slug ) );
		$state_name = $state_slug ? ucwords( str_replace( '-', ' ', $state_slug ) ) : '';
		$area       = $city_name . ( $state_name ? ', ' . $state_name : '' );
		$graph[] = array(
			'@context'   => 'https://schema.org',
			'@type'      => 'Service',
			'name'       => get_the_title(),
			'provider'   => array( '@type' => 'LocalBusiness', 'name' => get_bloginfo( 'name' ), 'areaServed' => $area ),
			'areaServed' => $area,
		);
	}
	return $graph;
}

add_filter( 'wpseo_title', 'fix_yoast_title_for_state_city', 5 );
function fix_yoast_title_for_state_city( $title ) {
	if ( is_singular( 'state' ) ) {
		return get_the_title() . ' Home Services | ' . get_bloginfo( 'name' );
	}
	if ( is_singular( 'city' ) ) {
		$city_name  = get_the_title();
		$state_slug = get_post_meta( get_the_ID(), '_city_state', true );
		$state_name = $state_slug ? ucwords( str_replace( '-', ' ', $state_slug ) ) : '';
		return $city_name . ( $state_name ? ', ' . $state_name : '' ) . ' Home Services | ' . get_bloginfo( 'name' );
	}
	return $title;
}

add_filter( 'wpseo_metadesc', 'fix_yoast_metadesc_for_state_city', 5 );
function fix_yoast_metadesc_for_state_city( $desc ) {
	if ( is_singular( 'state' ) ) {
		return 'Professional home services across ' . get_the_title() . '. Find trusted local contractors. Free estimates.';
	}
	if ( is_singular( 'city' ) ) {
		$city_name  = get_the_title();
		$state_slug = get_post_meta( get_the_ID(), '_city_state', true );
		$state_name = $state_slug ? ucwords( str_replace( '-', ' ', $state_slug ) ) : '';
		return 'Professional home services in ' . $city_name . ( $state_name ? ', ' . $state_name : '' ) . '. Exterior, interior, restoration & general services. Free estimates.';
	}
	return $desc;
}

add_filter( 'wpseo_sitemap_post_types', 'add_all_cpts_to_yoast_sitemap' );
function add_all_cpts_to_yoast_sitemap( $post_types ) {
	$post_types['state']         = 'state';
	$post_types['city']          = 'city';
	$post_types['home-services'] = 'home-services';
	return $post_types;
}

add_filter( 'wpseo_sitemap_entry', 'fix_cpt_yoast_sitemap_urls', 10, 3 );
function fix_cpt_yoast_sitemap_urls( $url, $type, $object ) {
	if ( 'post' === $type ) {
		if ( 'state' === $object->post_type ) {
			$url['loc'] = home_url( $object->post_name . '/' );
		}
		if ( 'city' === $object->post_type ) {
			$state_slug = get_post_meta( $object->ID, '_city_state', true );
			$url['loc'] = $state_slug
				? home_url( $state_slug . '/' . $object->post_name . '/' )
				: home_url( $object->post_name . '/' );
		}
	}
	return $url;
}

// ============================================================
// 20. SCHEMA MARKUP (Fallback if Yoast not active)
// ============================================================
add_action( 'wp_footer', 'add_fallback_schema' );
function add_fallback_schema() {
	if ( class_exists( 'WPSEO_Options' ) ) {
		return;
	}

	if ( is_singular( 'home-services' ) ) {
		$city_slug  = get_query_var( 'city_slug' );
		$state_slug = get_query_var( 'state_slug' );
		$city_name  = $city_slug ? ucwords( str_replace( '-', ' ', $city_slug ) ) : 'All Areas';
		$state_name = $state_slug ? ucwords( str_replace( '-', ' ', $state_slug ) ) : '';
		$area       = $city_name . ( $state_name ? ', ' . $state_name : '' );
		$schema = array(
			'@context'    => 'https://schema.org',
			'@type'       => 'Service',
			'name'        => get_the_title(),
			'description' => 'Professional ' . get_the_title() . ' services' . ( $city_slug ? ' in ' . $area : '' ) . '.',
			'provider'    => array( '@type' => 'LocalBusiness', 'name' => get_bloginfo( 'name' ) ),
			'areaServed'  => $area,
		);
		echo '<script type="application/ld+json">' . wp_json_encode( $schema, JSON_UNESCAPED_SLASHES ) . '</script>';
	}

	if ( is_singular( 'city' ) ) {
		$state_slug = get_post_meta( get_the_ID(), '_city_state', true );
		$state_name = $state_slug ? ucwords( str_replace( '-', ' ', $state_slug ) ) : '';
		$schema = array(
			'@context'    => 'https://schema.org',
			'@type'       => 'LocalBusiness',
			'name'        => get_bloginfo( 'name' ) . ' - ' . get_the_title(),
			'description' => 'Professional home services in ' . get_the_title() . ( $state_name ? ', ' . $state_name : '' ),
			'areaServed'  => get_the_title(),
		);
		echo '<script type="application/ld+json">' . wp_json_encode( $schema, JSON_UNESCAPED_SLASHES ) . '</script>';
	}

	if ( is_singular( 'state' ) ) {
		$schema = array(
			'@context'    => 'https://schema.org',
			'@type'       => 'LocalBusiness',
			'name'        => get_bloginfo( 'name' ) . ' - ' . get_the_title(),
			'description' => 'Professional home services across ' . get_the_title(),
			'areaServed'  => get_the_title(),
		);
		echo '<script type="application/ld+json">' . wp_json_encode( $schema, JSON_UNESCAPED_SLASHES ) . '</script>';
	}
}

// ============================================================
// 21. ENQUEUE STYLES
// ============================================================
add_action( 'wp_enqueue_scripts', 'lowlead_child_enqueue_styles', 20 );
function lowlead_child_enqueue_styles() {
	wp_enqueue_style( 'lowlead-parent-style', get_template_directory_uri() . '/style.css' );
	wp_enqueue_style( 'lowlead-child-style', get_stylesheet_directory_uri() . '/style.css', array( 'lowlead-parent-style' ), wp_get_theme()->get( 'Version' ) );
}

// ============================================================
// 22. UNIVERSAL CARD STYLES
// ============================================================
add_action( 'wp_enqueue_scripts', 'add_universal_card_styles', 999 );
function add_universal_card_styles() {
	$css = '
	.service-shortcode-grid .row,.city-services-grid .row{display:flex;flex-wrap:wrap;margin:0 -15px}
	.tf-practise-area-col,.city-service-card-col{margin-bottom:30px;padding:0 15px}
	.tf-practise-area-post,.city-service-card{background:#fff;border-radius:10px;overflow:hidden;transition:all 0.3s ease;box-shadow:0 5px 15px rgba(0,0,0,0.08);height:100%}
	.tf-practise-area-post .post-content,.city-service-card .service-content{background:#fff;padding:8px 20px;transition:all 0.3s ease}
	.tf-practise-area-post .read-more-btn,.city-service-card .read-more-btn{display:flex;justify-content:space-between;align-items:center;width:100%;text-decoration:none;font-size:18px;font-weight:500}
	.tf-practise-area-post .read-more-btn .title-text,.city-service-card .read-more-btn .title-text,.city-service-card h2 a{color:#222;transition:color 0.3s ease;text-decoration:none}
	.tf-practise-area-post .read-more-btn .arrow-icon,.city-service-card .read-more-btn .arrow-icon{color:#22c55e;transition:transform 0.3s ease}
	.tf-practise-area-post:hover,.tf-practise-area-post:hover .post-content,.city-service-card:hover,.city-service-card:hover .service-content{background:#22c55e}
	.tf-practise-area-post:hover .read-more-btn .title-text,.tf-practise-area-post:hover .read-more-btn .arrow-icon,.city-service-card:hover .read-more-btn .title-text,.city-service-card:hover .read-more-btn .arrow-icon,.city-service-card:hover h2 a{color:#fff}
	.tf-practise-area-post:hover .read-more-btn .arrow-icon,.city-service-card:hover .read-more-btn .arrow-icon{transform:translateX(5px)}
	.tf-practise-area-post .practise-area-image,.city-service-card .service-image{overflow:hidden}
	.tf-practise-area-post .practise-area-image img,.city-service-card .service-image img{width:100%;height:250px;object-fit:cover;transition:transform 0.3s ease}
	.tf-practise-area-post:hover .practise-area-image img,.city-service-card:hover .service-image img{transform:scale(1.05)}
	.city-faq h2{font-size:24px;margin-bottom:20px}
	.city-faq h3{font-size:18px;margin-top:20px;color:#333}
	.city-faq p{color:#666;line-height:1.6}
	@media(max-width:768px){.tf-practise-area-col,.city-service-card-col{margin-bottom:20px}.tf-practise-area-post .practise-area-image img,.city-service-card .service-image img{height:200px}}
	';
	wp_add_inline_style( 'lowlead-child-style', $css );
}

add_action( 'wp_enqueue_scripts', 'fix_city_services_footer_styles', 1000 );
function fix_city_services_footer_styles() {
	$footer_fix = '
	.site-footer,footer.site-footer,#colophon,#footer,.footer-area,.footer-widget-area,.footer-widgets,.footer-bottom,.footer-copyright,.footer-bar{background-color:revert !important;color:revert !important}
	.city-services-main{background:#fff;position:relative;z-index:1}
	.city-services-hero{position:relative;z-index:1}
	';
	wp_add_inline_style( 'lowlead-child-style', $footer_fix );
}

// ============================================================
// 23. ELEMENTOR SUPPORT
// ============================================================
add_action( 'init', 'enable_elementor_support' );
function enable_elementor_support() {
	add_post_type_support( 'home-services', 'elementor' );
	add_post_type_support( 'city', 'elementor' );
	add_post_type_support( 'state', 'elementor' );
}

add_action( 'init', function () {
	if ( ! class_exists( 'Elementor\Plugin' ) ) {
		return;
	}
	$elementor_settings = get_option( 'elementor_cpt_support', array() );
	$required_cpts      = array( 'home-services', 'city', 'state' );
	$updated            = false;
	foreach ( $required_cpts as $cpt ) {
		if ( ! in_array( $cpt, $elementor_settings, true ) ) {
			$elementor_settings[] = $cpt;
			$updated              = true;
		}
	}
	if ( $updated ) {
		update_option( 'elementor_cpt_support', $elementor_settings );
	}
}, 20 );

// ============================================================
// 24. ELEMENTOR WIDGET
// ============================================================
add_action( 'elementor/widgets/register', 'register_custom_elementor_widgets' );
function register_custom_elementor_widgets( $widgets_manager ) {
	if ( ! class_exists( 'TF_Universal_Service_Widget' ) ) {
		class TF_Universal_Service_Widget extends \Elementor\Widget_Base {
			public function get_name()       { return 'tf_universal_service_widget'; }
			public function get_title()      { return esc_html__( 'Home Services Grid', 'text-domain' ); }
			public function get_icon()       { return 'eicon-post-list'; }
			public function get_categories() { return array( 'general' ); }

			protected function register_controls() {
				$this->start_controls_section( 'content_section', array( 'label' => esc_html__( 'Content', 'text-domain' ), 'tab' => \Elementor\Controls_Manager::TAB_CONTENT ) );
				$this->add_control( 'post_type_select', array( 'label' => esc_html__( 'Post Type', 'text-domain' ), 'type' => \Elementor\Controls_Manager::SELECT, 'default' => 'home-services', 'options' => array( 'home-services' => 'Home Services', 'city' => 'Cities', 'state' => 'States' ) ) );
				$this->add_control( 'posts_per_page', array( 'label' => esc_html__( 'Items Per Page', 'text-domain' ), 'type' => \Elementor\Controls_Manager::NUMBER, 'default' => 9 ) );
				$this->add_control( 'columns', array( 'label' => esc_html__( 'Columns', 'text-domain' ), 'type' => \Elementor\Controls_Manager::SELECT, 'default' => 3, 'options' => array( 1 => '1', 2 => '2', 3 => '3', 4 => '4' ) ) );
				$this->add_control( 'show_image', array( 'label' => esc_html__( 'Show Image', 'text-domain' ), 'type' => \Elementor\Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => 'yes' ) );
				$this->add_control( 'show_parent_only', array( 'label' => esc_html__( 'Show Parent Only', 'text-domain' ), 'type' => \Elementor\Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => 'yes' ) );
				$this->add_control( 'orderby', array( 'label' => esc_html__( 'Order By', 'text-domain' ), 'type' => \Elementor\Controls_Manager::SELECT, 'default' => 'menu_order', 'options' => array( 'menu_order' => 'Page Order', 'title' => 'Title', 'date' => 'Date' ) ) );
				$this->add_control( 'order', array( 'label' => esc_html__( 'Order', 'text-domain' ), 'type' => \Elementor\Controls_Manager::SELECT, 'default' => 'ASC', 'options' => array( 'ASC' => 'Ascending', 'DESC' => 'Descending' ) ) );
				$this->add_control( 'filter_by_state', array( 'label' => esc_html__( 'Filter by State Slug', 'text-domain' ), 'type' => \Elementor\Controls_Manager::TEXT ) );
				$this->add_control( 'filter_by_city', array( 'label' => esc_html__( 'Filter by City Slug', 'text-domain' ), 'type' => \Elementor\Controls_Manager::TEXT ) );
				$this->end_controls_section();
				$this->start_controls_section( 'style_section', array( 'label' => esc_html__( 'Style', 'text-domain' ), 'tab' => \Elementor\Controls_Manager::TAB_STYLE ) );
				$this->add_control( 'title_color', array( 'label' => esc_html__( 'Title Color', 'text-domain' ), 'type' => \Elementor\Controls_Manager::COLOR, 'selectors' => array( '{{WRAPPER}} .title-text, {{WRAPPER}} h2 a' => 'color: {{VALUE}}' ) ) );
				$this->add_control( 'title_hover_color', array( 'label' => esc_html__( 'Hover Color', 'text-domain' ), 'type' => \Elementor\Controls_Manager::COLOR, 'selectors' => array( '{{WRAPPER}} .tf-practise-area-post:hover .title-text, {{WRAPPER}} .city-service-card:hover h2 a' => 'color: {{VALUE}}' ) ) );
				$this->add_control( 'arrow_color', array( 'label' => esc_html__( 'Arrow Color', 'text-domain' ), 'type' => \Elementor\Controls_Manager::COLOR, 'selectors' => array( '{{WRAPPER}} .arrow-icon' => 'color: {{VALUE}}' ) ) );
				$this->add_control( 'bg_hover_color', array( 'label' => esc_html__( 'Background Hover', 'text-domain' ), 'type' => \Elementor\Controls_Manager::COLOR, 'selectors' => array( '{{WRAPPER}} .tf-practise-area-post:hover, {{WRAPPER}} .tf-practise-area-post:hover .post-content, {{WRAPPER}} .city-service-card:hover, {{WRAPPER}} .city-service-card:hover .service-content' => 'background-color: {{VALUE}}' ) ) );
				$this->end_controls_section();
			}

			protected function render() {
				$settings  = $this->get_settings_for_display();
				$post_type = $settings['post_type_select'];
				$args = array( 'post_type' => $post_type, 'posts_per_page' => intval( $settings['posts_per_page'] ), 'post_status' => 'publish', 'orderby' => $settings['orderby'], 'order' => $settings['order'] );
				if ( 'yes' === $settings['show_parent_only'] ) {
					$args['post_parent'] = 0;
				}
				$meta_query = array();
				if ( ! empty( $settings['filter_by_state'] ) ) {
					$meta_query[] = array( 'key' => '_service_state', 'value' => sanitize_text_field( $settings['filter_by_state'] ) );
				}
				if ( ! empty( $settings['filter_by_city'] ) ) {
					$meta_query[] = array( 'key' => '_service_city', 'value' => sanitize_text_field( $settings['filter_by_city'] ) );
				}
				if ( ! empty( $meta_query ) ) {
					$meta_query['relation'] = 'AND';
					$args['meta_query']     = $meta_query;
				}
				$q = new WP_Query( $args );
				if ( $q->have_posts() ) {
					$col = 12 / intval( $settings['columns'] );
					echo '<div class="service-shortcode-grid"><div class="row">';
					while ( $q->have_posts() ) {
						$q->the_post();
						if ( 'state' === $post_type ) {
							$link = home_url( get_post_field( 'post_name' ) . '/' );
						} elseif ( 'city' === $post_type ) {
							$state_slug = get_post_meta( get_the_ID(), '_city_state', true );
							$link = $state_slug ? home_url( $state_slug . '/' . get_post_field( 'post_name' ) . '/' ) : home_url( get_post_field( 'post_name' ) . '/' );
						} else {
							$link = get_permalink();
						}
						echo '<div class="col-lg-' . $col . ' col-md-6 col-sm-12 tf-practise-area-col"><div class="tf-practise-area-post tf-practise-area-style1">';
						if ( 'yes' === $settings['show_image'] && has_post_thumbnail() ) {
							echo '<div class="practise-area-image"><a href="' . esc_url( $link ) . '">' . get_the_post_thumbnail( get_the_ID(), 'medium_large' ) . '</a></div>';
						}
						echo '<div class="post-content"><div class="practise-area-read-more"><a href="' . esc_url( $link ) . '" class="read-more-btn"><span class="title-text">' . get_the_title() . '</span><span class="arrow-icon">→</span></a></div></div></div></div>';
					}
					echo '</div></div>';
					wp_reset_postdata();
				}
			}
		}
	}
	$widgets_manager->register( new TF_Universal_Service_Widget() );
}

// ============================================================
// 25. SHORTCODE
// ============================================================
add_shortcode( 'display_home_services', 'display_universal_shortcode' );
function display_universal_shortcode( $atts ) {
	$atts = shortcode_atts( array( 'post_type' => 'home-services', 'posts_per_page' => 9, 'columns' => 3, 'show_image' => 'yes', 'show_parent_only' => 'yes', 'orderby' => 'menu_order', 'order' => 'ASC', 'state' => '', 'city' => '' ), $atts );
	$args = array( 'post_type' => $atts['post_type'], 'posts_per_page' => intval( $atts['posts_per_page'] ), 'post_status' => 'publish', 'orderby' => $atts['orderby'], 'order' => $atts['order'] );
	if ( 'yes' === $atts['show_parent_only'] ) {
		$args['post_parent'] = 0;
	}
	$meta_query = array();
	if ( ! empty( $atts['state'] ) ) {
		$meta_query[] = array( 'key' => '_service_state', 'value' => $atts['state'] );
	}
	if ( ! empty( $atts['city'] ) ) {
		$meta_query[] = array( 'key' => '_service_city', 'value' => $atts['city'] );
	}
	if ( ! empty( $meta_query ) ) {
		$meta_query['relation'] = 'AND';
		$args['meta_query']     = $meta_query;
	}
	$q = new WP_Query( $args );
	if ( ! $q->have_posts() ) {
		return '<p>No items found.</p>';
	}
	$col = 12 / intval( $atts['columns'] );
	$out = '<div class="service-shortcode-grid"><div class="row">';
	while ( $q->have_posts() ) {
		$q->the_post();
		if ( 'state' === $atts['post_type'] ) {
			$link = home_url( get_post_field( 'post_name' ) . '/' );
		} elseif ( 'city' === $atts['post_type'] ) {
			$state_slug = get_post_meta( get_the_ID(), '_city_state', true );
			$link = $state_slug ? home_url( $state_slug . '/' . get_post_field( 'post_name' ) . '/' ) : home_url( get_post_field( 'post_name' ) . '/' );
		} else {
			$link = get_permalink();
		}
		$out .= '<div class="col-lg-' . $col . ' col-md-6 col-sm-12 tf-practise-area-col"><div class="tf-practise-area-post tf-practise-area-style1">';
		if ( 'yes' === $atts['show_image'] && has_post_thumbnail() ) {
			$out .= '<div class="practise-area-image"><a href="' . esc_url( $link ) . '">' . get_the_post_thumbnail( get_the_ID(), 'medium_large' ) . '</a></div>';
		}
		$out .= '<div class="post-content"><div class="practise-area-read-more"><a href="' . esc_url( $link ) . '" class="read-more-btn"><span class="title-text">' . get_the_title() . '</span><span class="arrow-icon">→</span></a></div></div></div></div>';
	}
	$out .= '</div></div>';
	wp_reset_postdata();
	return $out;
}

// ============================================================
// 26. PAGE ATTRIBUTES META BOX
// ============================================================
add_action( 'add_meta_boxes', 'ensure_page_attributes_meta_box' );
function ensure_page_attributes_meta_box() {
	add_meta_box( 'pageparentdiv', 'Page Attributes', 'page_attributes_meta_box', 'home-services', 'side', 'core' );
}

// ============================================================
// 27. FLUSH REWRITE RULES ON ACTIVATION
// ============================================================
add_action( 'after_switch_theme', 'flush_rewrite_rules' );
add_action( 'load-options-permalink.php', function () {
	if ( isset( $_POST['permalink_structure'] ) ) {
		flush_rewrite_rules();
	}
} );

// ============================================================
// 28. CITY SEO META BOX
// ============================================================
add_action( 'add_meta_boxes', 'add_city_seo_meta_box' );
function add_city_seo_meta_box() {
	add_meta_box( 'city_seo', 'City SEO Settings', 'city_seo_callback', 'city', 'normal', 'high' );
}

function city_seo_callback( $post ) {
	wp_nonce_field( 'save_city_seo', 'city_seo_nonce' );
	$faq = get_post_meta( $post->ID, '_city_faq', true );
	?>
	<p><label><strong>FAQ Section:</strong></label><br>
	<textarea name="city_faq" rows="10" style="width:100%"><?php echo esc_textarea( $faq ); ?></textarea></p>
	<p class="description">Add frequently asked questions about services in this city.</p>
	<?php
}

add_action( 'save_post', 'save_city_seo' );
function save_city_seo( $post_id ) {
	if ( ! isset( $_POST['city_seo_nonce'] ) || ! wp_verify_nonce( $_POST['city_seo_nonce'], 'save_city_seo' ) ) {
		return;
	}
	if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
		return;
	}
	if ( ! current_user_can( 'edit_post', $post_id ) || 'city' !== get_post_type( $post_id ) ) {
		return;
	}
	if ( isset( $_POST['city_faq'] ) ) {
		update_post_meta( $post_id, '_city_faq', wp_kses_post( wp_unslash( $_POST['city_faq'] ) ) );
	}
}

// ============================================================
// 29. STATE SEO META BOX
// ============================================================
add_action( 'add_meta_boxes', 'add_state_seo_meta_box' );
function add_state_seo_meta_box() {
	add_meta_box( 'state_seo', 'State SEO Settings', 'state_seo_callback', 'state', 'normal', 'high' );
}

function state_seo_callback( $post ) {
	wp_nonce_field( 'save_state_seo', 'state_seo_nonce' );
	$faq = get_post_meta( $post->ID, '_state_faq', true );
	?>
	<p><label><strong>FAQ Section:</strong></label><br>
	<textarea name="state_faq" rows="10" style="width:100%"><?php echo esc_textarea( $faq ); ?></textarea></p>
	<p class="description">Add frequently asked questions about services in this state.</p>
	<?php
}

add_action( 'save_post', 'save_state_seo' );
function save_state_seo( $post_id ) {
	if ( ! isset( $_POST['state_seo_nonce'] ) || ! wp_verify_nonce( $_POST['state_seo_nonce'], 'save_state_seo' ) ) {
		return;
	}
	if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
		return;
	}
	if ( ! current_user_can( 'edit_post', $post_id ) || 'state' !== get_post_type( $post_id ) ) {
		return;
	}
	if ( isset( $_POST['state_faq'] ) ) {
		update_post_meta( $post_id, '_state_faq', wp_kses_post( wp_unslash( $_POST['state_faq'] ) ) );
	}
}

// ============================================================
// 30. QUICK EDIT — City + State
// ============================================================
add_action( 'quick_edit_custom_box', 'add_location_quick_edit', 10, 2 );
function add_location_quick_edit( $column_name, $post_type ) {
	if ( 'home-services' !== $post_type || 'service_state' !== $column_name ) {
		return;
	}
	wp_nonce_field( 'quick_edit_location_nonce', 'location_quick_edit_nonce' );
	$states = get_posts( array( 'post_type' => 'state', 'posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC', 'post_status' => 'publish' ) );
	$cities = get_posts( array( 'post_type' => 'city', 'posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC', 'post_status' => 'publish' ) );
	?>
	<fieldset class="inline-edit-col-right">
		<div class="inline-edit-col">
			<label class="alignleft" style="margin-bottom:10px;display:block;width:100%;">
				<span class="title">🗺️ State</span>
				<select name="service_state" id="service_state_quick" style="width:100%;">
					<option value="">— All States (Canonical) —</option>
					<?php foreach ( $states as $s ) : ?>
						<option value="<?php echo esc_attr( $s->post_name ); ?>">🗺️ <?php echo esc_html( $s->post_title ); ?></option>
					<?php endforeach; ?>
				</select>
			</label>
			<label class="alignleft" style="display:block;width:100%;">
				<span class="title">📍 City</span>
				<select name="service_city" id="service_city_quick" style="width:100%;">
					<option value="">🌐 All Cities (Canonical)</option>
					<?php foreach ( $cities as $c ) : ?>
						<option value="<?php echo esc_attr( $c->post_name ); ?>" data-state="<?php echo esc_attr( get_post_meta( $c->ID, '_city_state', true ) ); ?>">📍 <?php echo esc_html( $c->post_title ); ?></option>
					<?php endforeach; ?>
				</select>
			</label>
		</div>
	</fieldset>
	<?php
}

add_action( 'admin_footer-edit.php', 'add_location_quick_edit_script' );
function add_location_quick_edit_script() {
	global $pagenow;
	if ( 'edit.php' !== $pagenow || 'home-services' !== get_current_screen()->post_type ) {
		return;
	}
	?>
	<script type="text/javascript">
	jQuery(document).ready(function($) {
		function filterCitiesByState(stateSelect, citySelect) {
			var stateVal = $(stateSelect).val();
			$(citySelect).find('option').each(function() {
				if ($(this).val() === '') { $(this).show(); return; }
				var cityState = $(this).data('state') || '';
				$(this).toggle(!stateVal || cityState === stateVal);
			});
			var $sel = $(citySelect).find('option:selected');
			if ($sel.val() && $sel.is(':hidden')) { $(citySelect).val(''); }
		}
		var $wp_inline_edit = inlineEditPost.edit;
		inlineEditPost.edit = function(id) {
			$wp_inline_edit.apply(this, arguments);
			var post_id = typeof(id) === 'object' ? parseInt(this.getId(id)) : parseInt(id);
			if (post_id > 0) {
				var $post_row = $('#post-' + post_id);
				var $edit_row = $('#edit-' + post_id);
				var state_val = $post_row.find('.column-service_state span').data('state-slug') || '';
				var city_val  = $post_row.find('.column-service_city span').data('city-slug') || '';
				var $stateQE  = $edit_row.find('select[name="service_state"]');
				var $cityQE   = $edit_row.find('select[name="service_city"]');
				$stateQE.val(state_val);
				filterCitiesByState($stateQE, $cityQE);
				$cityQE.val(city_val);
				$stateQE.off('change.qe').on('change.qe', function() { filterCitiesByState(this, $cityQE); });
			}
		};
	});
	</script>
	<?php
}

add_action( 'save_post', 'save_quick_edit_location', 10, 2 );
function save_quick_edit_location( $post_id, $post ) {
	if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE || 'home-services' !== $post->post_type ) {
		return;
	}
	if ( ! current_user_can( 'edit_post', $post_id ) ) {
		return;
	}
	if ( ! isset( $_POST['_inline_edit'] ) || ! wp_verify_nonce( $_POST['_inline_edit'], 'inlineeditnonce' ) ) {
		return;
	}
	if ( array_key_exists( 'service_state', $_POST ) ) {
		$state = sanitize_text_field( wp_unslash( $_POST['service_state'] ) );
		$state !== '' ? update_post_meta( $post_id, '_service_state', $state ) : delete_post_meta( $post_id, '_service_state' );
	}
	if ( array_key_exists( 'service_city', $_POST ) ) {
		$city = sanitize_text_field( wp_unslash( $_POST['service_city'] ) );
		$city !== '' ? update_post_meta( $post_id, '_service_city', $city ) : delete_post_meta( $post_id, '_service_city' );
	}
}

// ============================================================
// 31. BULK EDIT — State + City
// ============================================================
add_action( 'bulk_edit_custom_box', 'add_location_bulk_edit', 10, 2 );
function add_location_bulk_edit( $column_name, $post_type ) {
	if ( 'home-services' !== $post_type || 'service_state' !== $column_name ) {
		return;
	}
	$states = get_posts( array( 'post_type' => 'state', 'posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC', 'post_status' => 'publish' ) );
	$cities = get_posts( array( 'post_type' => 'city', 'posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC', 'post_status' => 'publish' ) );
	?>
	<fieldset class="inline-edit-col-right">
		<div class="inline-edit-col">
			<label class="alignleft" style="margin-bottom:10px;display:block;width:100%;">
				<span class="title">🗺️ State</span>
				<select name="service_state" id="service_state_bulk" style="width:100%;">
					<option value="-1">— No Change —</option>
					<option value="">— All States (Canonical) —</option>
					<?php foreach ( $states as $s ) : ?>
						<option value="<?php echo esc_attr( $s->post_name ); ?>">🗺️ <?php echo esc_html( $s->post_title ); ?></option>
					<?php endforeach; ?>
				</select>
			</label>
			<label class="alignleft" style="display:block;width:100%;">
				<span class="title">📍 City</span>
				<select name="service_city" id="service_city_bulk" style="width:100%;">
					<option value="-1">— No Change —</option>
					<option value="">🌐 All Cities (Canonical)</option>
					<?php foreach ( $cities as $c ) : ?>
						<option value="<?php echo esc_attr( $c->post_name ); ?>" data-state="<?php echo esc_attr( get_post_meta( $c->ID, '_city_state', true ) ); ?>">📍 <?php echo esc_html( $c->post_title ); ?></option>
					<?php endforeach; ?>
				</select>
			</label>
		</div>
	</fieldset>
	<script type="text/javascript">
	jQuery(document).ready(function($) {
		$('#service_state_bulk').on('change', function() {
			var stateVal = $(this).val();
			$('#service_city_bulk option').each(function() {
				if ($(this).val() === '' || $(this).val() === '-1') { $(this).show(); return; }
				var cityState = $(this).data('state') || '';
				$(this).toggle(!stateVal || stateVal === '-1' || cityState === stateVal);
			});
			var $sel = $('#service_city_bulk option:selected');
			if ($sel.val() && $sel.val() !== '-1' && $sel.is(':hidden')) { $('#service_city_bulk').val('-1'); }
		});
	});
	</script>
	<?php
}

add_action( 'wp_ajax_save_bulk_edit_location', 'save_bulk_edit_location' );
function save_bulk_edit_location() {
	$post_ids = ( isset( $_POST['post_ids'] ) && ! empty( $_POST['post_ids'] ) ) ? array_map( 'absint', (array) $_POST['post_ids'] ) : array();
	$state    = ( isset( $_POST['service_state'] ) && '-1' !== $_POST['service_state'] ) ? sanitize_text_field( wp_unslash( $_POST['service_state'] ) ) : false;
	$city     = ( isset( $_POST['service_city'] ) && '-1' !== $_POST['service_city'] ) ? sanitize_text_field( wp_unslash( $_POST['service_city'] ) ) : false;

	foreach ( $post_ids as $post_id ) {
		if ( ! current_user_can( 'edit_post', $post_id ) || 'home-services' !== get_post_type( $post_id ) ) {
			continue;
		}
		if ( false !== $state ) {
			$state ? update_post_meta( $post_id, '_service_state', $state ) : delete_post_meta( $post_id, '_service_state' );
		}
		if ( false !== $city ) {
			$city ? update_post_meta( $post_id, '_service_city', $city ) : delete_post_meta( $post_id, '_service_city' );
		}
	}
	wp_die();
}

add_action( 'admin_footer-edit.php', 'add_bulk_edit_script' );
function add_bulk_edit_script() {
	global $pagenow;
	if ( 'edit.php' !== $pagenow || 'home-services' !== get_current_screen()->post_type ) {
		return;
	}
	?>
	<script type="text/javascript">
	jQuery(document).ready(function($) {
		$('#bulk_edit').on('click', function() {
			var $bulk_row = $('#bulk-edit');
			var $post_ids = [];
			$bulk_row.find('#bulk-titles-list li button').each(function() { $post_ids.push($(this).val()); });
			var state = $bulk_row.find('select[name="service_state"]').val();
			var city  = $bulk_row.find('select[name="service_city"]').val();
			if (state === '-1' && city === '-1') return;
			$.ajax({ url: ajaxurl, type: 'POST', async: false, data: { action: 'save_bulk_edit_location', post_ids: $post_ids, service_state: state, service_city: city } });
		});
	});
	</script>
	<?php
}


