<?php
/**
 * "My Profile" — self-service staff profile view/edit at /my-profile.
 *
 * Mirrors the Laravel site's /my-profile page. In Laravel a profile is a row in
 * `staff_profiles` linked to a login account via `user_id` ("Connect User
 * Account"). Here the profile IS the existing `staff` CPT post (the same record
 * the public /staff/{slug} page and the team-modal blocks render), so there is a
 * single source of truth. A new `staff_user_id` post meta is the user link.
 *
 * Field mapping (Laravel column -> WordPress):
 *   first_name / last_name   -> staff_first_name / staff_last_name meta
 *                               (post_title kept = "First Last")
 *   credentials              -> staff_credentials meta  (existing)
 *   departments  ("Titles &  -> staff_position meta     (existing)
 *     Departments" text)
 *   tags (Categories, M2M)   -> department taxonomy      (existing)
 *   user_id (Connect User)   -> staff_user_id meta       (new)
 *   photo                    -> featured image           (existing)
 *   bio                      -> post_content             (existing)
 *
 * The page is a normal WP Page (slug `my-profile`); we hook the_content (like
 * the single-staff / livestream views) so all of Kadence's boxed page chrome
 * (the white card + gradient) is inherited automatically. View mode reuses the
 * shared bw_render_staff() renderer; edit mode renders the form and saves over
 * admin-ajax (direct save, no draft/publish workflow).
 *
 * @package Kadence-Child
 */

defined( 'ABSPATH' ) || exit;

/** Post meta key linking a staff profile to a WP user (Connect User Account). */
if ( ! defined( 'BW_PROFILE_USER_META' ) ) {
	define( 'BW_PROFILE_USER_META', 'staff_user_id' );
}

/* =========================================================================
 * ACF fields (admin side): first/last name + the user link on the staff edit
 * screen. Self-contained group so we don't touch the JSON-synced "Staff
 * Details" group. ACF merges multiple groups on the same screen.
 * ====================================================================== */
add_action( 'acf/init', function () {
	if ( ! function_exists( 'acf_add_local_field_group' ) ) {
		return;
	}
	acf_add_local_field_group( array(
		'key'        => 'group_bw_profile_link',
		'title'      => 'Profile (self-service)',
		'menu_order' => 5,
		'fields'     => array(
			array( 'key' => 'field_bw_staff_first', 'label' => 'First Name', 'name' => 'staff_first_name', 'type' => 'text' ),
			array( 'key' => 'field_bw_staff_last',  'label' => 'Last Name',  'name' => 'staff_last_name',  'type' => 'text' ),
			array(
				'key'           => 'field_bw_staff_user',
				'label'         => 'Connect User Account',
				'name'          => BW_PROFILE_USER_META,
				'type'          => 'user',
				'return_format' => 'id',
				'multiple'      => 0,
				'allow_null'    => 1,
				'instructions'  => 'The login account allowed to edit this profile at /my-profile.',
			),
		),
		'location'   => array( array( array( 'param' => 'post_type', 'operator' => '==', 'value' => 'staff' ) ) ),
	) );
} );

/* =========================================================================
 * Lookups / capability helpers
 * ====================================================================== */

/** The staff post linked to a user, or null. */
function bw_profile_for_user( $user_id ) {
	$user_id = (int) $user_id;
	if ( $user_id < 1 || ! post_type_exists( 'staff' ) ) {
		return null;
	}
	$q = new WP_Query( array(
		'post_type'           => 'staff',
		'post_status'         => array( 'publish', 'pending', 'draft', 'private' ),
		'posts_per_page'      => 1,
		'meta_key'            => BW_PROFILE_USER_META,
		'meta_value'          => $user_id,
		'no_found_rows'       => true,
		'ignore_sticky_posts' => true,
	) );
	return $q->have_posts() ? $q->posts[0] : null;
}

/** Can this user edit this profile? Owner of the link, or an editor/admin. */
function bw_profile_can_edit( $post, $user_id ) {
	if ( ! $post instanceof WP_Post ) {
		return false;
	}
	$user_id = (int) $user_id;
	if ( $user_id < 1 ) {
		return false;
	}
	if ( (int) get_post_meta( $post->ID, BW_PROFILE_USER_META, true ) === $user_id ) {
		return true;
	}
	return user_can( $user_id, 'edit_others_posts' );
}

/** Manager = may (re)assign the Connect User Account link and edit any profile. */
function bw_profile_is_manager( $user_id = 0 ) {
	$user_id = $user_id ? (int) $user_id : get_current_user_id();
	return user_can( $user_id, 'edit_users' );
}

/** Permalink of the /my-profile page (the feature is hardwired to it). */
function bw_profile_page_url() {
	$p = get_page_by_path( 'my-profile' );
	return $p instanceof WP_Post ? get_permalink( $p ) : home_url( '/my-profile/' );
}

/**
 * Build a /my-profile URL for a given profile in view or edit mode. Keeps the
 * ?staff=ID context only when a manager is acting on someone else's profile, so
 * get_permalink() of the staff post (which points at /staff/...) is never used.
 */
function bw_profile_url( $post, $edit ) {
	$args = $edit ? array( 'edit' => '1' ) : array();
	if ( (int) get_post_meta( $post->ID, BW_PROFILE_USER_META, true ) !== get_current_user_id() ) {
		$args['staff_id'] = $post->ID;
	}
	$url = bw_profile_page_url();
	return $args ? add_query_arg( $args, $url ) : $url;
}

/** Write a value via ACF (keeps the field-key reference) or raw meta. */
function bw_profile_set( $post_id, $meta_key, $field_key, $value ) {
	if ( function_exists( 'update_field' ) ) {
		update_field( $field_key, $value, $post_id );
	} else {
		update_post_meta( $post_id, $meta_key, $value );
	}
}

/* =========================================================================
 * Front-end: replace the content of the /my-profile page
 * ====================================================================== */
add_filter( 'the_content', 'bw_profile_content', 20 );
function bw_profile_content( $content ) {
	if ( is_admin() || ! in_the_loop() || ! is_main_query() || ! is_page( 'my-profile' ) ) {
		return $content;
	}

	if ( ! is_user_logged_in() ) {
		$login = esc_url( wp_login_url( get_permalink() ) );
		return '<div class="bw-profile bw-profile--empty"><p>Please <a href="' . $login . '">log in</a> to view your profile.</p></div>';
	}

	$uid  = get_current_user_id();
	$post = bw_profile_for_user( $uid );

	// Managers may edit a specific profile via ?staff_id=ID (e.g. marketing
	// helping a staff member, or one not yet linked to an account). NB: the
	// param is staff_id, NOT staff — `staff` is the CPT's own query var (it would
	// route to a single staff post by slug and 404 the page).
	if ( bw_profile_is_manager( $uid ) && isset( $_GET['staff_id'] ) ) {
		$p2 = get_post( (int) $_GET['staff_id'] );
		if ( $p2 instanceof WP_Post && 'staff' === $p2->post_type ) {
			$post = $p2;
		}
	}

	if ( ! $post instanceof WP_Post ) {
		$extra = bw_profile_is_manager( $uid )
			? ' (Tip: open a staff member with <code>/my-profile/?staff_id=ID</code>.)'
			: '';
		return '<div class="bw-profile bw-profile--empty"><p>You don’t have a profile linked to your account yet. Please contact marketing.' . $extra . '</p></div>';
	}

	$can_edit = bw_profile_can_edit( $post, $uid );
	$editing  = $can_edit && isset( $_GET['edit'] );

	return $editing ? bw_profile_render_edit( $post ) : bw_profile_render_view( $post, $can_edit );
}

/** Hide Kadence's page title on /my-profile (the card carries its own heading). */
add_filter( 'kadence_post_layout', function ( $layout ) {
	if ( is_array( $layout ) && is_page( 'my-profile' ) ) {
		$layout['title'] = 'hide';
	}
	return $layout;
} );

/* =========================================================================
 * Renderers
 * ====================================================================== */

/** View mode: the public profile look + an Edit button. */
function bw_profile_render_view( $post, $can_edit ) {
	$out = '<div class="bw-profile bw-profile--view">';
	if ( $can_edit ) {
		$edit_url = esc_url( bw_profile_url( $post, true ) );
		$out     .= '<div class="bw-profile__bar"><a class="bw-profile__btn" href="' . $edit_url . '">Edit Profile</a></div>';
	}
	if ( function_exists( 'bw_render_staff' ) ) {
		$out .= bw_render_staff( $post );
	} else {
		$out .= '<h1>' . esc_html( get_the_title( $post ) ) . '</h1>'
			. '<div>' . wp_kses_post( wpautop( $post->post_content ) ) . '</div>';
	}
	$out .= '</div>';
	return $out;
}

/** Edit mode: the form (mirrors the Laravel "Edit Profile" screen). */
function bw_profile_render_edit( $post ) {
	$pid = $post->ID;

	$first = (string) get_post_meta( $pid, 'staff_first_name', true );
	$last  = (string) get_post_meta( $pid, 'staff_last_name', true );
	if ( '' === trim( $first . $last ) ) {
		// First time: derive from the full-name title (last token = surname).
		$parts = preg_split( '/\s+/', trim( (string) $post->post_title ) );
		if ( is_array( $parts ) && count( $parts ) > 1 ) {
			$last  = (string) array_pop( $parts );
			$first = implode( ' ', $parts );
		} else {
			$first = (string) $post->post_title;
		}
	}
	$creds  = (string) get_post_meta( $pid, 'staff_credentials', true );
	$depts  = (string) get_post_meta( $pid, 'staff_position', true );
	$bio    = (string) $post->post_content;
	$sel    = wp_get_object_terms( $pid, 'department', array( 'fields' => 'ids' ) );
	$sel    = is_wp_error( $sel ) ? array() : array_map( 'intval', $sel );
	$terms  = get_terms( array( 'taxonomy' => 'department', 'hide_empty' => false ) );
	$terms  = is_wp_error( $terms ) ? array() : $terms;
	$thumb  = get_the_post_thumbnail_url( $pid, 'medium' );
	$is_mgr = bw_profile_is_manager();

	$linked_id = (int) get_post_meta( $pid, BW_PROFILE_USER_META, true );
	$linked_u  = $linked_id ? get_user_by( 'id', $linked_id ) : null;

	ob_start();
	?>
	<div class="bw-profile bw-profile--edit">
		<form class="bw-pform" data-bw-pform enctype="multipart/form-data" novalidate>
			<input type="hidden" name="post_id" value="<?php echo esc_attr( $pid ); ?>">

			<h2 class="bw-pform__title">Edit Profile</h2>
			<div class="bw-pform__status" data-bw-status hidden></div>

			<div class="bw-pform__grid">
				<div class="bw-pform__main">

					<div class="bw-prow bw-prow--2">
						<div class="bw-pfield">
							<label class="bw-plabel" for="bw_first">First Name</label>
							<input class="bw-pinput" type="text" id="bw_first" name="first_name" value="<?php echo esc_attr( $first ); ?>">
						</div>
						<div class="bw-pfield">
							<label class="bw-plabel" for="bw_last">Last Name</label>
							<input class="bw-pinput" type="text" id="bw_last" name="last_name" value="<?php echo esc_attr( $last ); ?>">
						</div>
					</div>

					<div class="bw-pfield">
						<input class="bw-pinput" type="text" name="credentials" value="<?php echo esc_attr( $creds ); ?>"
							placeholder="Degrees, Post Secondary Schools &amp; Credentials" aria-label="Degrees, Post Secondary Schools &amp; Credentials">
					</div>

					<div class="bw-pfield">
						<input class="bw-pinput" type="text" name="departments" value="<?php echo esc_attr( $depts ); ?>"
							placeholder="Titles &amp; Departments" aria-label="Titles &amp; Departments">
					</div>

					<div class="bw-pfield">
						<label class="bw-plabel">Categories</label>
						<div class="bw-ms" data-bw-ms>
							<div class="bw-ms__control">
								<ul class="bw-ms__tokens" data-bw-ms-tokens></ul>
								<input class="bw-ms__search" type="text" placeholder="Select Categories" data-bw-ms-search>
							</div>
							<div class="bw-ms__menu" data-bw-ms-menu hidden>
								<?php foreach ( $terms as $t ) : ?>
									<label class="bw-ms__opt">
										<input type="checkbox" name="categories[]" value="<?php echo esc_attr( $t->term_id ); ?>"
											<?php checked( in_array( (int) $t->term_id, $sel, true ) ); ?>>
										<span><?php echo esc_html( $t->name ); ?></span>
									</label>
								<?php endforeach; ?>
							</div>
						</div>
					</div>

					<?php if ( $is_mgr ) : ?>
						<div class="bw-pfield">
							<label class="bw-plabel">Connect User Account</label>
							<div class="bw-userpick" data-bw-userpick>
								<input type="hidden" name="user_id" value="<?php echo esc_attr( $linked_id ?: '' ); ?>" data-bw-userpick-id>
								<input class="bw-pinput bw-userpick__search" type="text" placeholder="Search users…"
									value="<?php echo $linked_u ? esc_attr( $linked_u->display_name . ' (' . $linked_u->user_login . ')' ) : ''; ?>"
									data-bw-userpick-search autocomplete="off">
								<button type="button" class="bw-userpick__clear" data-bw-userpick-clear aria-label="Disconnect user">&times;</button>
								<div class="bw-userpick__menu" data-bw-userpick-menu hidden></div>
							</div>
						</div>
					<?php endif; ?>

					<div class="bw-pfield">
						<label class="bw-plabel" for="bw_bio">Biography</label>
						<?php
						wp_editor(
							$bio,
							'bw_bio',
							array(
								'textarea_name' => 'bio',
								'media_buttons' => false,
								'teeny'         => true,
								'textarea_rows' => 10,
								'quicktags'     => true,
								'tinymce'       => array( 'toolbar1' => 'bold,italic,blockquote,bullist,numlist,link,unlink,undo,redo' ),
							)
						);
						?>
					</div>

				</div><!-- .bw-pform__main -->

				<aside class="bw-pform__aside">
					<div class="bw-pphoto" data-bw-photo>
						<div class="bw-pphoto__preview"<?php echo $thumb ? ' style="background-image:url(\'' . esc_url( $thumb ) . '\')"' : ''; ?> data-bw-photo-preview>
							<?php if ( ! $thumb ) : ?>
								<svg viewBox="0 0 24 24" aria-hidden="true" class="bw-pphoto__ph"><path d="M4 3h16a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1Zm8 4a3 3 0 1 0 0 6 3 3 0 0 0 0-6Zm-5 11h10a5 5 0 0 0-10 0Z"/></svg>
							<?php endif; ?>
						</div>
						<label class="bw-pphoto__btn">
							<input type="file" name="photo" accept="image/*" hidden data-bw-photo-input>
							<span>Upload A Photo</span>
						</label>
					</div>
				</aside>
			</div><!-- .bw-pform__grid -->

			<div class="bw-pform__actions">
				<button type="submit" class="bw-pbtn bw-pbtn--save" data-bw-save>Save Profile</button>
				<a class="bw-pbtn bw-pbtn--ghost" href="<?php echo esc_url( bw_profile_url( $post, false ) ); ?>">Cancel</a>
			</div>
		</form>
	</div>
	<?php
	return ob_get_clean();
}

/* =========================================================================
 * Assets
 * ====================================================================== */
add_action( 'wp_enqueue_scripts', function () {
	if ( ! is_page( 'my-profile' ) ) {
		return;
	}
	$dir = get_stylesheet_directory();
	$uri = get_stylesheet_directory_uri();

	// View mode reuses the staff / team-modal styles.
	if ( wp_style_is( 'bw-team-modal', 'registered' ) ) {
		wp_enqueue_style( 'bw-team-modal' );
	}
	if ( file_exists( $dir . '/assets/staff.css' ) ) {
		wp_enqueue_style( 'bw-staff', $uri . '/assets/staff.css', array( 'bw-team-modal' ), filemtime( $dir . '/assets/staff.css' ) );
	}
	if ( file_exists( $dir . '/assets/bw-my-profile.css' ) ) {
		wp_enqueue_style( 'bw-my-profile', $uri . '/assets/bw-my-profile.css', array(), filemtime( $dir . '/assets/bw-my-profile.css' ) );
	}
	if ( file_exists( $dir . '/assets/bw-my-profile.js' ) ) {
		wp_enqueue_script( 'bw-my-profile', $uri . '/assets/bw-my-profile.js', array(), filemtime( $dir . '/assets/bw-my-profile.js' ), true );
		wp_localize_script( 'bw-my-profile', 'BW_PROFILE', array(
			'ajax'      => admin_url( 'admin-ajax.php' ),
			'nonce'     => wp_create_nonce( 'bw_profile' ),
			'isManager' => bw_profile_is_manager() ? 1 : 0,
		) );
	}
} );

/* =========================================================================
 * AJAX: save profile (direct save)
 * ====================================================================== */
add_action( 'wp_ajax_bw_save_profile', 'bw_profile_ajax_save' );
function bw_profile_ajax_save() {
	if ( ! is_user_logged_in() ) {
		wp_send_json_error( array( 'msg' => 'You are not logged in.' ), 403 );
	}
	check_ajax_referer( 'bw_profile', 'nonce' );

	$uid     = get_current_user_id();
	$post_id = isset( $_POST['post_id'] ) ? (int) $_POST['post_id'] : 0;
	$post    = $post_id ? get_post( $post_id ) : null;

	if ( ! $post instanceof WP_Post || 'staff' !== $post->post_type ) {
		wp_send_json_error( array( 'msg' => 'Profile not found.' ), 404 );
	}
	if ( ! bw_profile_can_edit( $post, $uid ) ) {
		wp_send_json_error( array( 'msg' => 'You are not allowed to edit this profile.' ), 403 );
	}

	$first = isset( $_POST['first_name'] ) ? sanitize_text_field( wp_unslash( $_POST['first_name'] ) ) : '';
	$last  = isset( $_POST['last_name'] ) ? sanitize_text_field( wp_unslash( $_POST['last_name'] ) ) : '';
	$creds = isset( $_POST['credentials'] ) ? sanitize_text_field( wp_unslash( $_POST['credentials'] ) ) : '';
	$depts = isset( $_POST['departments'] ) ? sanitize_text_field( wp_unslash( $_POST['departments'] ) ) : '';
	$bio   = isset( $_POST['bio'] ) ? wp_kses_post( wp_unslash( $_POST['bio'] ) ) : '';

	$cats = isset( $_POST['categories'] ) ? (array) wp_unslash( $_POST['categories'] ) : array();
	$cats = array_values( array_filter( array_map( 'intval', $cats ) ) );

	// Title from first + last (keep existing if both blank).
	$title  = trim( $first . ' ' . $last );
	$update = array( 'ID' => $post_id, 'post_content' => $bio );
	if ( '' !== $title ) {
		$update['post_title'] = $title;
	}
	wp_update_post( $update );

	bw_profile_set( $post_id, 'staff_first_name',  'field_bw_staff_first',         $first );
	bw_profile_set( $post_id, 'staff_last_name',   'field_bw_staff_last',          $last );
	bw_profile_set( $post_id, 'staff_credentials', 'field_bwm_staff_credentials',  $creds );
	bw_profile_set( $post_id, 'staff_position',    'field_bwm_staff_position',     $depts );

	if ( taxonomy_exists( 'department' ) ) {
		wp_set_object_terms( $post_id, $cats, 'department', false );
	}

	// Connect User Account — managers only.
	if ( bw_profile_is_manager( $uid ) && isset( $_POST['user_id'] ) ) {
		$raw  = trim( (string) wp_unslash( $_POST['user_id'] ) );
		$link = (int) $raw;
		if ( $link > 0 && get_user_by( 'id', $link ) ) {
			bw_profile_set( $post_id, BW_PROFILE_USER_META, 'field_bw_staff_user', $link );
		} elseif ( '' === $raw ) {
			bw_profile_set( $post_id, BW_PROFILE_USER_META, 'field_bw_staff_user', '' );
		}
	}

	// Photo upload (optional).
	if ( ! empty( $_FILES['photo']['name'] ) ) {
		$att = bw_profile_handle_photo( $post_id );
		if ( is_wp_error( $att ) ) {
			wp_send_json_error( array( 'msg' => 'Photo upload failed: ' . $att->get_error_message() ), 400 );
		}
	}

	$post = get_post( $post_id );
	wp_send_json_success( array(
		'msg'     => 'Profile saved.',
		'view'    => bw_profile_render_view( $post, true ),
		'viewUrl' => bw_profile_url( $post, false ),
	) );
}

/** Handle the profile photo upload and set it as the featured image. */
function bw_profile_handle_photo( $post_id ) {
	require_once ABSPATH . 'wp-admin/includes/file.php';
	require_once ABSPATH . 'wp-admin/includes/media.php';
	require_once ABSPATH . 'wp-admin/includes/image.php';

	$file = $_FILES['photo'];
	$ft   = wp_check_filetype( $file['name'] );
	$ok   = array( 'jpg', 'jpeg', 'png', 'gif', 'webp' );
	if ( ! $ft['ext'] || ! in_array( strtolower( $ft['ext'] ), $ok, true ) ) {
		return new WP_Error( 'bad_type', 'Please upload a JPG, PNG, GIF or WebP image.' );
	}

	$att_id = media_handle_upload( 'photo', $post_id );
	if ( is_wp_error( $att_id ) ) {
		return $att_id;
	}
	set_post_thumbnail( $post_id, $att_id );
	return $att_id;
}

/* =========================================================================
 * AJAX: user search for "Connect User Account" (managers only)
 * ====================================================================== */
add_action( 'wp_ajax_bw_profile_user_search', 'bw_profile_ajax_user_search' );
function bw_profile_ajax_user_search() {
	check_ajax_referer( 'bw_profile', 'nonce' );
	if ( ! bw_profile_is_manager() ) {
		wp_send_json_error( array(), 403 );
	}
	$term  = isset( $_GET['q'] ) ? sanitize_text_field( wp_unslash( $_GET['q'] ) ) : '';
	$users = get_users( array(
		'search'         => '*' . $term . '*',
		'search_columns' => array( 'user_login', 'user_email', 'display_name', 'user_nicename' ),
		'number'         => 20,
		'orderby'        => 'display_name',
	) );
	$out = array();
	foreach ( $users as $u ) {
		$out[] = array( 'id' => $u->ID, 'text' => $u->display_name . ' (' . $u->user_login . ')' );
	}
	wp_send_json_success( $out );
}
