<?php

/**
 * SocialPromoter — Compose page.
 *
 * Standalone post composer. Supports multiple accounts with independent
 * copy per platform, seeded from a master copy field.
 *
 * @package PublisherKits_SocialPromoter
 */
if ( !defined( 'ABSPATH' ) ) {
    exit;
}
$accounts = PKITS_SP_Accounts::get_active();
$connectors = PKITS_SP_Platform_Registry::get_all();
// Campaigns are premium only; the free build has no campaign code at all.
$campaigns = array();
$has_accounts = !empty( $accounts );
// Build per-platform char limits for JS.
$char_limits = array();
foreach ( $accounts as $storage_id => $account ) {
    $connector = PKITS_SP_Platform_Registry::get( $account['platform'] );
    $char_limits[$storage_id] = ( $connector ? (int) $connector->get_char_limit() : 5000 );
}
// Settings - copy template for pre-fill hint.
$settings = get_option( 'pkits_sp_settings', array() );
$settings = ( is_array( $settings ) ? $settings : array() );
?>
<div class="wrap pkits-sp-wrap">

	<h1 class="pkits-sp-page-title">
		<span class="pkits-sp-logo-mark">SP</span>
		<?php 
esc_html_e( 'SocialPromoter &mdash; Compose', 'publisherkits-socialpromoter' );
?>
	</h1>

	<?php 
if ( !$has_accounts ) {
    ?>
		<div class="pkits-sp-empty-state" style="max-width:860px;">
			<p><?php 
    esc_html_e( 'No social accounts connected yet.', 'publisherkits-socialpromoter' );
    ?></p>
			<a href="<?php 
    echo esc_url( admin_url( 'admin.php?page=publisherkits-socialpromoter-accounts' ) );
    ?>" class="button button-primary">
				<?php 
    esc_html_e( 'Connect an account', 'publisherkits-socialpromoter' );
    ?>
			</a>
		</div>
	<?php 
} else {
    ?>

	<div id="pkits-sp-compose-result" class="pkits-sp-nudge-result" style="display:none;max-width:860px;margin-bottom:16px;padding:12px 16px;border-radius:6px;font-size:13px;"></div>

	<div class="pkits-sp-page-layout">

		<!-- ── MAIN COLUMN ──────────────────────────────────────── -->
		<div class="pkits-sp-page-main">

			<!-- Mode toggle -->
			<div class="pkits-sp-card" style="margin-bottom:0;border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom:none;">
				<div class="pkits-sp-card-body" style="padding:12px 20px;">
					<div class="pkits-sp-mode-toggle">
						<button type="button" class="pkits-sp-mode-btn is-active" data-mode="select-post">
							&#128196; <?php 
    esc_html_e( 'Select a post', 'publisherkits-socialpromoter' );
    ?>
						</button>
						<button type="button" class="pkits-sp-mode-btn" data-mode="write-new">
							&#9998; <?php 
    esc_html_e( 'Write new', 'publisherkits-socialpromoter' );
    ?>
						</button>
					</div>
				</div>
			</div>

			<!-- Select post mode -->
			<div id="pkits-sp-mode-select-post" class="pkits-sp-card" style="border-top-left-radius:0;border-top-right-radius:0;">
				<div class="pkits-sp-card-body">

					<!-- Type pills - populated by JS -->
					<div id="pkits-sp-type-pills" style="display:flex;flex-wrap:wrap;gap:6px;margin-bottom:12px;">
						<button type="button" class="pkits-sp-type-pill is-active" data-type="all">
							<?php 
    esc_html_e( 'All', 'publisherkits-socialpromoter' );
    ?>
						</button>
					</div>

					<!-- Search field -->
					<div style="position:relative;margin-bottom:10px;">
						<input type="text" id="pkits-sp-post-search"
							placeholder="<?php 
    esc_attr_e( 'Filter by title...', 'publisherkits-socialpromoter' );
    ?>"
							autocomplete="off"
							style="width:100%;padding:8px 32px 8px 12px;border:1.5px solid #d0e0f0;border-radius:5px;font-size:13px;font-family:'Source Sans 3',Arial,sans-serif;box-sizing:border-box;" />
						<span id="pkits-sp-search-clear" style="display:none;position:absolute;right:10px;top:50%;transform:translateY(-50%);cursor:pointer;color:#8a9ab0;font-size:16px;line-height:1;">&times;</span>
					</div>

					<!-- Results list -->
					<div id="pkits-sp-post-list" style="border:1px solid #d0e0f0;border-radius:5px;max-height:280px;overflow-y:auto;background:#fff;">
						<div id="pkits-sp-post-list-loading" style="padding:16px;text-align:center;font-size:12px;color:#8a9ab0;">
							<?php 
    esc_html_e( 'Loading...', 'publisherkits-socialpromoter' );
    ?>
						</div>
					</div>

					<!-- Selected post confirmation -->
					<div id="pkits-sp-selected-post" style="display:none;margin-top:10px;padding:10px 14px;background:#f5f9ff;border:1.5px solid #4a7fc1;border-radius:5px;">
						<div style="display:flex;align-items:center;gap:12px;">
							<div id="pkits-sp-selected-thumb" style="flex-shrink:0;"></div>
							<div style="flex:1;min-width:0;">
								<div id="pkits-sp-selected-title" style="font-weight:700;color:#1a2d4a;font-size:13px;margin-bottom:2px;"></div>
								<div id="pkits-sp-selected-url" style="font-size:11px;color:#8a9ab0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;"></div>
							</div>
							<button type="button" id="pkits-sp-clear-post" style="background:none;border:none;color:#8a9ab0;cursor:pointer;font-size:20px;padding:0;line-height:1;" title="Clear">&times;</button>
						</div>
					</div>

					<input type="hidden" id="pkits-sp-selected-post-id" value="" />

					<?php 
    ?>

					<?php 
    ?>
				</div>
			</div>

			<!-- Step 1: Select accounts -->
			<div class="pkits-sp-card" id="pkits-sp-compose-accounts-card">
				<div class="pkits-sp-card-header">
					<h2 class="pkits-sp-card-title"><?php 
    esc_html_e( 'Select accounts', 'publisherkits-socialpromoter' );
    ?></h2>
					<p class="pkits-sp-card-desc"><?php 
    esc_html_e( 'Choose which accounts to post to. Each gets its own copy panel.', 'publisherkits-socialpromoter' );
    ?></p>
				</div>
				<div class="pkits-sp-card-body">
					<div class="pkits-sp-compose-accounts">
						<?php 
    foreach ( $accounts as $storage_id => $account ) {
        $connector = PKITS_SP_Platform_Registry::get( $account['platform'] );
        $badge = ( $connector ? $connector->get_badge() : strtoupper( $account['platform'] ) );
        $limit = ( $connector ? (int) $connector->get_char_limit() : 5000 );
        $limit_str = ( $limit >= 10000 ? esc_html__( 'No practical limit', 'publisherkits-socialpromoter' ) : number_format( $limit ) . ' ' . esc_html__( 'char limit', 'publisherkits-socialpromoter' ) );
        ?>
							<label class="pkits-sp-compose-account-option" data-storage-id="<?php 
        echo esc_attr( $storage_id );
        ?>">
								<input type="checkbox"
									class="pkits-sp-compose-account-cb"
									value="<?php 
        echo esc_attr( $storage_id );
        ?>"
									data-platform="<?php 
        echo esc_attr( $account['platform'] );
        ?>"
									data-label="<?php 
        echo esc_attr( $account['label'] );
        ?>"
									data-limit="<?php 
        echo (int) $limit;
        ?>"
									data-badge="<?php 
        echo esc_attr( $badge );
        ?>" />
								<span class="pkits-sp-platform-badge pkits-sp-badge-<?php 
        echo esc_attr( $account['platform'] );
        ?>">
									<?php 
        echo esc_html( $badge );
        ?>
								</span>
								<span class="pkits-sp-compose-account-name"><?php 
        echo esc_html( $account['label'] );
        ?></span>
								<span class="pkits-sp-compose-account-limit"><?php 
        echo esc_html( $limit_str );
        ?></span>
							</label>
						<?php 
    }
    ?>
					</div>
				</div>
			</div>

			<?php 
    ?>

			<!-- Step 2: Master copy -->
			<div class="pkits-sp-card">
				<div class="pkits-sp-card-header">
					<h2 class="pkits-sp-card-title"><?php 
    esc_html_e( 'Master copy', 'publisherkits-socialpromoter' );
    ?></h2>
					<p class="pkits-sp-card-desc"><?php 
    esc_html_e( 'Write your base copy here. Select accounts above and it seeds each platform panel below.', 'publisherkits-socialpromoter' );
    ?></p>
				</div>
				<div class="pkits-sp-card-body">
					<div class="pkits-sp-form-group" style="margin-bottom:0;">
						<textarea id="pkits-sp-master-copy" rows="4"
							placeholder="<?php 
    esc_attr_e( 'Write your post copy here…', 'publisherkits-socialpromoter' );
    ?>"
							style="width:100%;font-family:'Source Sans 3','Source Sans Pro',Arial,sans-serif;font-size:13px;line-height:1.5;border:1px solid #d0e0f0;border-radius:5px;padding:8px 10px;resize:vertical;"></textarea>
						<div style="display:flex;justify-content:space-between;margin-top:4px;">
							<span style="font-size:11px;color:#8a9ab0;"><?php 
    esc_html_e( 'Selecting an account below seeds it from this copy.', 'publisherkits-socialpromoter' );
    ?></span>
							<button type="button" id="pkits-sp-seed-all" class="pkits-sp-btn-secondary" style="font-size:11px;padding:3px 10px;">
								<?php 
    esc_html_e( 'Apply to all open panels', 'publisherkits-socialpromoter' );
    ?>
							</button>
						</div>
					</div>
				</div>
			</div>

			<!-- Step 3: Per-platform copy panels (populated by JS) -->
			<div id="pkits-sp-platform-panels"></div>

			<!-- Step 4: Shared options -->
			<div class="pkits-sp-card" id="pkits-sp-compose-options">
				<div class="pkits-sp-card-header">
					<h2 class="pkits-sp-card-title"><?php 
    esc_html_e( 'Options', 'publisherkits-socialpromoter' );
    ?></h2>
				</div>
				<div class="pkits-sp-card-body">
					<div class="pkits-sp-form-grid">

						<!-- Image picker -->
						<div class="pkits-sp-form-group full-width">
							<label><?php 
    esc_html_e( 'Image', 'publisherkits-socialpromoter' );
    ?></label>
							<div style="display:flex;align-items:center;gap:10px;flex-wrap:wrap;">
								<input type="hidden" id="pkits-sp-compose-image-id" value="" />
								<input type="url" id="pkits-sp-compose-image-url" value=""
									placeholder="<?php 
    esc_attr_e( 'No image selected', 'publisherkits-socialpromoter' );
    ?>"
									readonly style="flex:1;min-width:180px;background:#f8f8f8;color:#8a9ab0;" />
								<button type="button" id="pkits-sp-compose-image-select" class="pkits-sp-btn-secondary" style="font-size:12px;padding:5px 12px;">
									<?php 
    esc_html_e( 'Select image', 'publisherkits-socialpromoter' );
    ?>
								</button>
								<button type="button" id="pkits-sp-compose-image-remove" class="pkits-sp-btn-secondary" style="font-size:12px;padding:5px 12px;display:none;">
									<?php 
    esc_html_e( 'Remove', 'publisherkits-socialpromoter' );
    ?>
								</button>
							</div>
							<div id="pkits-sp-compose-image-thumb" style="margin-top:6px;"></div>
							<span class="pkits-sp-field-hint">
								<?php 
    $sp_image_hint = __( 'Posted as-is to all selected platforms.', 'publisherkits-socialpromoter' );
    echo esc_html( $sp_image_hint );
    ?>
							</span>
						</div>

						<div class="pkits-sp-form-group full-width">
							<label for="pkits-sp-compose-url"><?php 
    esc_html_e( 'URL', 'publisherkits-socialpromoter' );
    ?></label>
							<input type="url" id="pkits-sp-compose-url"
								placeholder="https://"
								style="width:100%;" />
							<span class="pkits-sp-field-hint"><?php 
    esc_html_e( 'Optional. Appended to copy if not already present.', 'publisherkits-socialpromoter' );
    ?></span>
						</div>

						<div class="pkits-sp-form-group full-width">
							<label for="pkits-sp-compose-schedule"><?php 
    esc_html_e( 'Schedule', 'publisherkits-socialpromoter' );
    ?></label>
							<input type="datetime-local" id="pkits-sp-compose-schedule" style="width:100%;" />
							<span class="pkits-sp-field-hint"><?php 
    esc_html_e( 'Leave blank to post immediately. Same time applied to all selected accounts.', 'publisherkits-socialpromoter' );
    ?></span>
						</div>

						<?php 
    ?>

					</div>
				</div>
			</div>

			<!-- Action bar -->
			<div class="pkits-sp-action-bar">
				<button type="button" id="pkits-sp-compose-submit" class="pkits-sp-btn-primary" disabled>
					<?php 
    esc_html_e( 'Post now', 'publisherkits-socialpromoter' );
    ?>
				</button>
				<button type="button" id="pkits-sp-compose-preview" class="pkits-sp-btn-secondary" style="display:none;">
					&#128065; <?php 
    esc_html_e( 'Preview', 'publisherkits-socialpromoter' );
    ?>
				</button>
				<span id="pkits-sp-compose-status" style="font-size:12px;color:#5a6a7a;"></span>
			</div>

		</div>

		<!-- ── SIDEBAR ───────────────────────────────────────────── -->
		<div class="pkits-sp-page-aside">

			<!-- Connected accounts summary -->
			<div class="pkits-sp-widget">
				<div class="pkits-sp-widget-header">
					<div class="pkits-sp-widget-icon">&#9783;</div>
					<h3 class="pkits-sp-widget-title"><?php 
    esc_html_e( 'Connected accounts', 'publisherkits-socialpromoter' );
    ?></h3>
				</div>
				<div class="pkits-sp-widget-body">
					<?php 
    foreach ( $accounts as $storage_id => $account ) {
        $connector = PKITS_SP_Platform_Registry::get( $account['platform'] );
        $badge = ( $connector ? $connector->get_badge() : strtoupper( $account['platform'] ) );
        ?>
						<div class="pkits-sp-summary-row">
							<div class="pkits-sp-summary-value" style="display:flex;align-items:center;gap:6px;">
								<span class="pkits-sp-platform-badge pkits-sp-badge-<?php 
        echo esc_attr( $account['platform'] );
        ?>" style="font-size:9px;">
									<?php 
        echo esc_html( $badge );
        ?>
								</span>
								<?php 
        echo esc_html( $account['label'] );
        ?>
							</div>
						</div>
					<?php 
    }
    ?>
					<div style="margin-top:10px;">
						<a href="<?php 
    echo esc_url( admin_url( 'admin.php?page=publisherkits-socialpromoter-accounts' ) );
    ?>" class="pkits-sp-widget-link">
							<?php 
    esc_html_e( 'Manage platforms', 'publisherkits-socialpromoter' );
    ?> &rarr;
						</a>
					</div>
				</div>
			</div>

			<!-- Guidance -->
			<div class="pkits-sp-widget pkits-sp-guidance-widget">
				<div class="pkits-sp-widget-header">
					<div class="pkits-sp-widget-icon">&#128161;</div>
					<h3 class="pkits-sp-widget-title"><?php 
    esc_html_e( 'Tips', 'publisherkits-socialpromoter' );
    ?></h3>
				</div>
				<div class="pkits-sp-widget-body">
					<ul class="pkits-sp-guidance-list">
						<li><?php 
    esc_html_e( 'X has a strict 280 character limit — keep it tight.', 'publisherkits-socialpromoter' );
    ?></li>
						<li><?php 
    esc_html_e( 'LinkedIn performs better with slightly longer, more professional copy.', 'publisherkits-socialpromoter' );
    ?></li>
						<li><?php 
    esc_html_e( 'The URL is appended automatically if not already in the copy.', 'publisherkits-socialpromoter' );
    ?></li>
						<li><?php 
    esc_html_e( 'Scheduling applies the same time to all selected accounts.', 'publisherkits-socialpromoter' );
    ?></li>
					</ul>
				</div>
			</div>

			<?php 
    ?>

		</div>
	</div>

	<?php 
}
// has_accounts
?>

<?php 
// Build account metadata for preview mockups.
$preview_accounts = array();
foreach ( $accounts as $storage_id => $account ) {
    $preview_accounts[$storage_id] = array(
        'platform' => $account['platform'],
        'label'    => $account['label'],
    );
}
?>
<!-- Preview modal -->
<div id="pkits-sp-preview-modal" style="display:none;position:fixed;inset:0;z-index:99999;background:rgba(0,0,0,0.6);overflow-y:auto;padding:40px 20px;">
	<div style="max-width:720px;margin:0 auto;position:relative;">
		<div style="background:#fff;border-radius:10px;overflow:hidden;box-shadow:0 20px 60px rgba(0,0,0,0.3);">

			<!-- Modal header -->
			<div style="background:#1a2d4a;padding:14px 20px;display:flex;align-items:center;justify-content:space-between;">
				<span style="color:#fff;font-weight:700;font-size:15px;font-family:'Roboto Slab',Georgia,serif;">
					&#128065; <?php 
esc_html_e( 'Post Preview', 'publisherkits-socialpromoter' );
?>
				</span>
				<button type="button" id="pkits-sp-preview-close"
					style="background:none;border:none;color:#fff;font-size:22px;cursor:pointer;padding:0;line-height:1;opacity:0.8;">&times;</button>
			</div>

			<!-- Platform tabs -->
			<div id="pkits-sp-preview-tabs" style="display:flex;border-bottom:2px solid #e8f0f8;background:#f5f9ff;"></div>

			<!-- Preview content -->
			<div id="pkits-sp-preview-content" style="padding:20px;background:#e8edf2;min-height:300px;">
				<div id="pkits-sp-preview-loading" style="text-align:center;padding:40px;color:#8a9ab0;font-size:13px;display:none;">
					<?php 
$sp_preview_loading = __( 'Preparing image preview...', 'publisherkits-socialpromoter' );
echo esc_html( $sp_preview_loading );
?>
				</div>
				<div id="pkits-sp-preview-card"></div>
			</div>

			<!-- Modal footer -->
			<div style="padding:12px 20px;background:#f5f9ff;border-top:1px solid #e8f0f8;text-align:right;">
				<span style="font-size:11px;color:#8a9ab0;margin-right:12px;" id="pkits-sp-preview-note"></span>
				<button type="button" id="pkits-sp-preview-fullsize"
					class="pkits-sp-btn-secondary" style="font-size:12px;padding:6px 16px;display:none;margin-right:8px;">
					<?php 
esc_html_e( 'View full size', 'publisherkits-socialpromoter' );
?>
				</button>
				<button type="button" id="pkits-sp-preview-close-btn" class="pkits-sp-btn-secondary" style="font-size:12px;padding:6px 16px;">
					<?php 
esc_html_e( 'Close', 'publisherkits-socialpromoter' );
?>
				</button>
			</div>

		</div>
	</div>
</div>
</div>

<!-- Full-size image overlay (in-page; data: URLs are blocked from opening in a new tab) -->
<div id="pkits-sp-fullsize-overlay" style="display:none;position:fixed;inset:0;z-index:100001;background:rgba(0,0,0,0.92);overflow:auto;padding:24px;text-align:center;cursor:zoom-out;">
	<div style="position:sticky;top:0;text-align:right;margin-bottom:8px;">
		<button type="button" id="pkits-sp-fullsize-close" class="pkits-sp-btn-secondary" style="font-size:13px;padding:6px 16px;">
			<?php 
esc_html_e( 'Close', 'publisherkits-socialpromoter' );
?> &times;
		</button>
	</div>
	<img id="pkits-sp-fullsize-img" src="" alt="<?php 
echo esc_attr__( 'Full size preview', 'publisherkits-socialpromoter' );
?>"
		style="max-width:100%;height:auto;display:inline-block;box-shadow:0 4px 30px rgba(0,0,0,0.5);cursor:default;" />
</div>

<?php 
ob_start();
?>
( function( $ ) {
	'use strict';

	var nonce        = <?php 
echo wp_json_encode( wp_create_nonce( 'pkits_sp_metabox' ) );
?>;
	var ajaxUrl      = <?php 
echo wp_json_encode( admin_url( 'admin-ajax.php' ) );
?>;
	var charLimits   = <?php 
echo wp_json_encode( $char_limits );
?>;
<?php 
?>
	var selectedAccounts = {};

	// ----------------------------------------------------------------
	// Mode toggle: Select post / Write new
	// ----------------------------------------------------------------
	var currentPostId = 0;
	var currentPostUrl = '';

	$( '.pkits-sp-mode-btn' ).on( 'click', function() {
		var mode = $( this ).data( 'mode' );
		$( '.pkits-sp-mode-btn' ).removeClass( 'is-active' );
		$( this ).addClass( 'is-active' );
		if ( mode === 'select-post' ) {
			$( '#pkits-sp-mode-select-post' ).show();
		} else {
			$( '#pkits-sp-mode-select-post' ).hide();
			// Clear any selected post when switching to write new
			clearSelectedPost();
		}
	} );

	// ----------------------------------------------------------------
	// Post selector: type pills + recent list + search filter
	// ----------------------------------------------------------------
	var currentType  = 'all';
	var searchTimer;
	var postTypes    = [];

	// Load post types and populate pills on page load.
	function loadPostTypes() {
		$.ajax( {
			url: ajaxUrl, type: 'POST',
			data: { action: 'pkits_sp_get_post_types', nonce: nonce },
			success: function( r ) {
				if ( ! r.success ) { return; }
				postTypes = r.data;
				$.each( postTypes, function( i, pt ) {
					var $pill = $( '<button type="button" class="pkits-sp-type-pill">' )
						.text( pt.label )
						.data( 'type', pt.slug );
					$( '#pkits-sp-type-pills' ).append( $pill );
				} );
				// Load recent posts for default "All" type.
				loadPosts();
			}
		} );
	}

	// Load/search posts into the list.
	function loadPosts() {
		var query = $( '#pkits-sp-post-search' ).val().trim();
		$( '#pkits-sp-post-list' ).html( '<div id="pkits-sp-post-list-loading" style="padding:16px;text-align:center;font-size:12px;color:#8a9ab0;"><?php 
echo esc_js( __( 'Loading...', 'publisherkits-socialpromoter' ) );
?></div>' );
		$.ajax( {
			url: ajaxUrl, type: 'POST',
			data: { action: 'pkits_sp_search_posts', nonce: nonce, query: query, post_type: currentType },
			success: function( r ) {
				var $list = $( '#pkits-sp-post-list' ).empty();
				if ( ! r.success || ! r.data.length ) {
					$list.html( '<div style="padding:14px;font-size:12px;color:#8a9ab0;text-align:center;"><?php 
echo esc_js( __( 'No results found.', 'publisherkits-socialpromoter' ) );
?></div>' );
					return;
				}
				$.each( r.data, function( i, post ) {
					var $row = $( '<div>' ).css( {
						padding: '8px 12px', cursor: 'pointer',
						borderBottom: '1px solid #f0f4f8',
						display: 'flex', alignItems: 'center', gap: '10px',
					} );
					// Thumbnail
					if ( post.thumbnail ) {
						$row.append( $( '<img>' ).attr( 'src', post.thumbnail ).attr( 'style', 'width:44px;height:30px;object-fit:cover;border-radius:3px;flex-shrink:0;border:1px solid #e8f0f8;' ) );
					} else {
						$row.append( '<div style="width:44px;height:30px;background:#e8f0f8;border-radius:3px;flex-shrink:0;display:flex;align-items:center;justify-content:center;color:#b0c0d0;font-size:16px;">&#9781;</div>' );
					}
					// Title + meta
					var $text = $( '<div>' ).css( { flex: '1', minWidth: 0 } );
					$text.append( $( '<div>' ).css( { fontSize: '12px', color: '#1a2d4a', fontWeight: '600', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', lineHeight: '1.3' } ).text( post.title ) );
					var meta = post.date + ( currentType === 'all' ? '  ·  ' + post.type : '' );
					$text.append( $( '<div>' ).css( { fontSize: '10px', color: '#8a9ab0', marginTop: '1px' } ).text( meta ) );
					$row.append( $text );
					$row.data( 'post', post )
						.on( 'mouseenter', function() { $( this ).css( 'background', '#f0f6ff' ); } )
						.on( 'mouseleave', function() { $( this ).css( 'background', '' ); } )
						.on( 'click', function() { selectPost( $( this ).data( 'post' ) ); } );
					$list.append( $row );
				} );
			}
		} );
	}

	// Type pill click.
	$( document ).on( 'click', '.pkits-sp-type-pill', function() {
		$( '.pkits-sp-type-pill' ).removeClass( 'is-active' );
		$( this ).addClass( 'is-active' );
		currentType = $( this ).data( 'type' );
		$( '#pkits-sp-post-search' ).val( '' );
		$( '#pkits-sp-search-clear' ).hide();
		loadPosts();
	} );

	// Search input.
	$( '#pkits-sp-post-search' ).on( 'input', function() {
		var val = $( this ).val();
		$( '#pkits-sp-search-clear' ).toggle( val.length > 0 );
		clearTimeout( searchTimer );
		searchTimer = setTimeout( loadPosts, 350 );
	} );

	// Clear search.
	$( '#pkits-sp-search-clear' ).on( 'click', function() {
		$( '#pkits-sp-post-search' ).val( '' );
		$( this ).hide();
		clearTimeout( searchTimer );
		loadPosts();
	} );

	// Load on mode switch to select-post.
	$( '.pkits-sp-mode-btn' ).on( 'click.postloader', function() {
		if ( $( this ).data( 'mode' ) === 'select-post' && ! postTypes.length ) {
			loadPostTypes();
		} else if ( $( this ).data( 'mode' ) === 'select-post' && postTypes.length ) {
			loadPosts();
		}
	} );

	// Load immediately if select-post is the default active mode.
	if ( $( '#pkits-sp-mode-select-post' ).is( ':visible' ) ) {
		loadPostTypes();
	}

	function selectPost( post ) {
		// Data from PHP AJAX handler: id, title (plain string), url, type, thumbnail
		currentPostId  = post.id;
		currentPostUrl = post.url;
		var title = post.title || '';

		// Show selected post panel
		$( '#pkits-sp-selected-title' ).text( title + ( post.type ? ' (' + post.type + ')' : '' ) );
		$( '#pkits-sp-selected-url' ).text( post.url );
		$( '#pkits-sp-selected-post-id' ).val( post.id );
		$( '#pkits-sp-selected-thumb' ).empty();

		// Thumbnail returned directly from AJAX - no second API call needed
		if ( post.thumbnail ) {
			$( '#pkits-sp-selected-thumb' ).html(
				$( '<img>' ).attr( 'src', post.thumbnail ).attr( 'style', 'width:60px;height:40px;object-fit:cover;border-radius:3px;border:1px solid #d0e0f0;' )
			);
			// Auto-populate the image field from the post's FULL featured image
			// (never the 150px square 'thumbnail', which would brand a cropped,
			// upscaled stamp of the picture). Fall back to thumb only if no full.
			var sourceImg = post.full_image || post.thumbnail;
			if ( ! $( '#pkits-sp-compose-image-url' ).val() ) {
				$( '#pkits-sp-compose-image-url' ).val( sourceImg );
				$( '#pkits-sp-compose-image-thumb' ).empty().append( $( '<img>' ).attr( 'src', post.thumbnail || sourceImg ).attr( 'style', 'height:50px;border-radius:3px;border:1px solid #d0e0f0;' ) );
				$( '#pkits-sp-compose-image-remove' ).show();
				$( '#pkits-sp-compose-image-select' ).text( <?php 
echo wp_json_encode( esc_html__( 'Change image', 'publisherkits-socialpromoter' ) );
?> );
			}
		}

		$( '#pkits-sp-selected-post' ).show();
		$( '#pkits-sp-post-results' ).hide();
		$( '#pkits-sp-post-search' ).val( '' );

		// Pre-fill master copy with post title
		$( '#pkits-sp-master-copy' ).val( title );

		// Pre-fill global URL
		$( '#pkits-sp-compose-url' ).val( post.url ).trigger( 'input' );

		// Load author tags for this post
		<?php 
?>

		// Seed any already-open platform panels
		$( '.pkits-sp-platform-copy' ).each( function() {
			if ( ! $( this ).val() ) {
				$( this ).val( title ).trigger( 'input' );
			}
		} );
		$( '.pkits-sp-platform-url' ).each( function() {
			$( this ).val( post.url ).data( 'manual', false );
		} );
	}

	function clearSelectedPost() {
		currentPostId  = 0;
		currentPostUrl = '';
		$( '#pkits-sp-selected-post' ).hide();
		$( '#pkits-sp-selected-post-id' ).val( '' );
		$( '#pkits-sp-post-search' ).val( '' );
		<?php 
?>
		<?php 
?>
		// Clear image if it was auto-populated from a post.
		$( '#pkits-sp-compose-image-url' ).val( '' );
		$( '#pkits-sp-compose-image-id' ).val( '' );
		$( '#pkits-sp-compose-image-thumb' ).empty();
		$( '#pkits-sp-compose-image-remove' ).hide();
		$( '#pkits-sp-compose-image-select' ).text( <?php 
echo wp_json_encode( esc_html__( 'Select image', 'publisherkits-socialpromoter' ) );
?> );
	}

	$( '#pkits-sp-clear-post' ).on( 'click', clearSelectedPost );

	// ----------------------------------------------------------------
	// Account checkbox: open / close per-platform panel
	// ----------------------------------------------------------------
	$( document ).on( 'change', '.pkits-sp-compose-account-cb', function() {
		var storageId = $( this ).val();
		var platform  = $( this ).data( 'platform' );
		var label     = $( this ).data( 'label' );
		var limit     = parseInt( $( this ).data( 'limit' ), 10 );
		var badge     = $( this ).data( 'badge' );

		if ( $( this ).is( ':checked' ) ) {
			selectedAccounts[ storageId ] = true;
			addPanel( storageId, platform, label, badge, limit );
		} else {
			delete selectedAccounts[ storageId ];
			removePanel( storageId );
		}

		updateSubmitButton();
		updatePreviewBtn();
		$( '.pkits-sp-compose-account-option[data-storage-id="' + storageId + '"]' )
			.toggleClass( 'is-selected', $( this ).is( ':checked' ) );
	} );

	// ----------------------------------------------------------------
	// Add a platform panel
	// ----------------------------------------------------------------
	function addPanel( storageId, platform, label, badge, limit ) {
		if ( $( '#pkits-sp-panel-' + storageId ).length ) { return; }

		var masterCopy = $( '#pkits-sp-master-copy' ).val();
		var badgeClass = 'pkits-sp-badge-' + platform;
		var limitText  = limit >= 10000
			? <?php 
echo wp_json_encode( esc_html__( 'No practical limit', 'publisherkits-socialpromoter' ) );
?>
			: limit + ' ' + <?php 
echo wp_json_encode( esc_html__( 'char limit', 'publisherkits-socialpromoter' ) );
?>;

		var $panel = $( '<div>', {
			id: 'pkits-sp-panel-' + storageId,
			'class': 'pkits-sp-card pkits-sp-platform-panel',
			'data-storage-id': storageId,
			'data-limit': limit
		} );

		var $header = $( '<div class="pkits-sp-card-header" style="display:flex;align-items:center;gap:10px;">' );
		$header.append( '<span class="pkits-sp-platform-badge ' + badgeClass + '" style="flex-shrink:0;">' + $( '<span>' ).text( badge ).html() + '</span>' );
		$header.append( '<span class="pkits-sp-card-title" style="flex:1;font-size:14px;">' + $( '<span>' ).text( label ).html() + '</span>' );
		$header.append( '<span style="font-size:11px;color:#8a9ab0;">' + limitText + '</span>' );
		$header.append( '<button type="button" class="pkits-sp-reapply-master pkits-sp-btn-secondary" style="font-size:11px;padding:3px 10px;">' + <?php 
echo wp_json_encode( esc_html__( 'Re-apply master', 'publisherkits-socialpromoter' ) );
?> + '</button>' );

		var $body = $( '<div class="pkits-sp-card-body">' );

		var $textarea = $( '<textarea>', {
			id: 'pkits-sp-copy-' + storageId,
			'class': 'pkits-sp-platform-copy',
			'data-storage-id': storageId,
			rows: 4,
			style: 'width:100%;font-family:\'Source Sans 3\',\'Source Sans Pro\',Arial,sans-serif;font-size:13px;line-height:1.5;border:1px solid #d0e0f0;border-radius:5px;padding:8px 10px;resize:vertical;box-sizing:border-box;'
		} ).val( masterCopy );

		var $counter = $( '<div style="display:flex;justify-content:space-between;margin-top:4px;">' );
		var charCount = masterCopy.length;
		var overLimit = limit < 10000 && charCount > limit;
		$counter.append(
			'<span class="pkits-sp-copy-counter' + ( overLimit ? ' pkits-sp-over-limit' : '' ) + '" data-storage-id="' + storageId + '" style="font-size:11px;' + ( overLimit ? 'color:#d63638;font-weight:700;' : 'color:#8a9ab0;' ) + '">' +
			charCount + ' / ' + ( limit < 10000 ? limit : '&#8734;' ) + '</span>'
		);

		// URL override per platform
		var $urlRow = $( '<div style="margin-top:10px;">' );
		$urlRow.append( '<label style="font-size:10px;font-weight:700;color:#5a6a7a;text-transform:uppercase;letter-spacing:0.5px;display:block;margin-bottom:4px;">' + <?php 
echo wp_json_encode( esc_html__( 'URL override for this platform', 'publisherkits-socialpromoter' ) );
?> + '</label>' );
		var $urlInput = $( '<input>', {
			type: 'url',
			id: 'pkits-sp-url-' + storageId,
			'class': 'pkits-sp-platform-url',
			'data-storage-id': storageId,
			placeholder: 'https://',
			style: 'width:100%;padding:7px 10px;border:1px solid #d0e0f0;border-radius:5px;font-size:12px;font-family:\'Source Sans 3\',Arial,sans-serif;box-sizing:border-box;'
		} );
		// Pre-fill from global URL field if set
		var globalUrl = $( '#pkits-sp-compose-url' ).val();
		if ( globalUrl ) { $urlInput.val( globalUrl ); }
		$urlRow.append( $urlInput );

		// Extension point: additional panel content may attach here.
		$body.append( $textarea ).append( $counter ).append( $urlRow );
		if ( typeof attachAiPanel === 'function' ) { attachAiPanel( $body, storageId ); }
		$panel.append( $header ).append( $body );
		$( '#pkits-sp-platform-panels' ).append( $panel );

		$textarea.trigger( 'focus' );
	}

	// ----------------------------------------------------------------
	// Remove a platform panel
	// ----------------------------------------------------------------
	function removePanel( storageId ) {
		$( '#pkits-sp-panel-' + storageId ).remove();
	}

	// ----------------------------------------------------------------
	// Character counter update
	// ----------------------------------------------------------------
	$( document ).on( 'input', '.pkits-sp-platform-copy', function() {
		var storageId = $( this ).data( 'storage-id' );
		var limit     = parseInt( $( '#pkits-sp-panel-' + storageId ).data( 'limit' ), 10 );
		var len       = $( this ).val().length;
		var over      = limit < 10000 && len > limit;
		var $counter  = $( '.pkits-sp-copy-counter[data-storage-id="' + storageId + '"]' );
		$counter
			.text( len + ' / ' + ( limit < 10000 ? limit : '\u221e' ) )
			.toggleClass( 'pkits-sp-over-limit', over )
			.css( { color: over ? '#d63638' : '#8a9ab0', fontWeight: over ? '700' : '400' } );
		updateSubmitButton();
	} );

	// ----------------------------------------------------------------
	// Re-apply master to a specific panel
	// ----------------------------------------------------------------
	$( document ).on( 'click', '.pkits-sp-reapply-master', function() {
		var storageId = $( this ).closest( '.pkits-sp-platform-panel' ).data( 'storage-id' );
		$( '#pkits-sp-copy-' + storageId ).val( $( '#pkits-sp-master-copy' ).val() ).trigger( 'input' );
	} );

	// ----------------------------------------------------------------
	// Apply master to all open panels
	// ----------------------------------------------------------------
	$( '#pkits-sp-seed-all' ).on( 'click', function() {
		var master = $( '#pkits-sp-master-copy' ).val();
		$( '.pkits-sp-platform-copy' ).val( master ).trigger( 'input' );
	} );

	// ----------------------------------------------------------------
	// Global URL change → update all platform URL fields
	// ----------------------------------------------------------------
	$( '#pkits-sp-compose-url' ).on( 'input', function() {
		var url = $( this ).val();
		$( '.pkits-sp-platform-url' ).each( function() {
			if ( ! $( this ).data( 'manual' ) ) {
				$( this ).val( url );
			}
		} );
	} );

	$( document ).on( 'input', '.pkits-sp-platform-url', function() {
		$( this ).data( 'manual', true );
	} );

	// ----------------------------------------------------------------
	// Schedule changes button label
	// ----------------------------------------------------------------
	$( '#pkits-sp-compose-schedule' ).on( 'change', function() {
		var $btn = $( '#pkits-sp-compose-submit' );
		if ( $( this ).val() ) {
			$btn.text( <?php 
echo wp_json_encode( esc_html__( 'Schedule posts', 'publisherkits-socialpromoter' ) );
?> );
		} else {
			$btn.text( <?php 
echo wp_json_encode( esc_html__( 'Post now', 'publisherkits-socialpromoter' ) );
?> );
		}
	} );

	// ----------------------------------------------------------------
	// Enable/disable submit button
	// ----------------------------------------------------------------
	function updateSubmitButton() {
		var hasPanels     = $( '.pkits-sp-platform-panel' ).length > 0;
		var allHaveCopy   = true;
		var anyOverLimit  = false;

		$( '.pkits-sp-platform-panel' ).each( function() {
			var storageId = $( this ).data( 'storage-id' );
			var copy      = $( '#pkits-sp-copy-' + storageId ).val().trim();
			var limit     = parseInt( $( this ).data( 'limit' ), 10 );
			if ( ! copy ) { allHaveCopy = false; }
			if ( limit < 10000 && copy.length > limit ) { anyOverLimit = true; }
		} );

		var enabled = hasPanels && allHaveCopy && ! anyOverLimit;
		$( '#pkits-sp-compose-submit' ).prop( 'disabled', ! enabled );

		if ( anyOverLimit ) {
			$( '#pkits-sp-compose-status' ).text( <?php 
echo wp_json_encode( esc_html__( 'Some posts exceed the character limit.', 'publisherkits-socialpromoter' ) );
?> );
		} else if ( ! allHaveCopy && hasPanels ) {
			$( '#pkits-sp-compose-status' ).text( <?php 
echo wp_json_encode( esc_html__( 'Add copy to all open panels.', 'publisherkits-socialpromoter' ) );
?> );
		} else {
			$( '#pkits-sp-compose-status' ).text( '' );
		}
	}

	// ----------------------------------------------------------------
	// Submit
	// ----------------------------------------------------------------
	$( '#pkits-sp-compose-submit' ).on( 'click', function() {
		var $btn = $( this );

		// Build copies object { storageId: copy }
		var copies = {};
		$( '.pkits-sp-platform-panel' ).each( function() {
			var storageId = $( this ).data( 'storage-id' );
			copies[ storageId ] = $( '#pkits-sp-copy-' + storageId ).val().trim();
		} );

		if ( $.isEmptyObject( copies ) ) { return; }

		$btn.text( <?php 
echo wp_json_encode( esc_html__( 'Sending…', 'publisherkits-socialpromoter' ) );
?> ).prop( 'disabled', true );
		$( '#pkits-sp-compose-result' ).hide();

		// Build URL overrides
		var urlOverrides = {};
		$( '.pkits-sp-platform-url' ).each( function() {
			var storageId = $( this ).data( 'storage-id' );
			urlOverrides[ storageId ] = $( this ).val().trim();
		} );

		$.ajax( {
			url: ajaxUrl,
			type: 'POST',
			data: {
				action:      'pkits_sp_compose_post',
				nonce:       nonce,
				copies:      copies,
				url:         $( '#pkits-sp-compose-url' ).val().trim(),
				image_url:   $( '#pkits-sp-compose-image-url' ).val().trim(),
				scheduled_at: $( '#pkits-sp-compose-schedule' ).val(),
				<?php 
?>
				post_id:     currentPostId || 0,
			},
			success: function( r ) {
				var $result = $( '#pkits-sp-compose-result' );
				if ( r.success ) {
					$result.removeClass( 'error' ).addClass( 'success' )
						.css( { background: '#d1f5e8', color: '#1d9e75', border: '1px solid #a8e6d0' } )
						.empty().text( r.data.message );
					if ( r.data.errors && r.data.errors.length ) {
						$( '<span>' ).css( 'color', '#856404' ).text( r.data.errors.join( ' ' ) )
							.prepend( $( '<br>' ) ).appendTo( $result );
					}
					$result.show();

					// Reset form
					$( '.pkits-sp-compose-account-cb:checked' ).prop( 'checked', false ).trigger( 'change' );
					$( '#pkits-sp-master-copy' ).val( '' );
					$( '#pkits-sp-compose-url,#pkits-sp-compose-schedule' ).val( '' );
					<?php 
?>
					$btn.text( <?php 
echo wp_json_encode( esc_html__( 'Post now', 'publisherkits-socialpromoter' ) );
?> ).prop( 'disabled', true );
					$( 'html, body' ).animate( { scrollTop: 0 }, 300 );
				} else {
					$result.removeClass( 'success' ).addClass( 'error' )
						.css( { background: '#fde8e8', color: '#d63638', border: '1px solid #f5c6c6' } )
						.text( r.data ? r.data.message : <?php 
echo wp_json_encode( esc_html__( 'Something went wrong.', 'publisherkits-socialpromoter' ) );
?> )
						.show();
					$btn.text( <?php 
echo wp_json_encode( esc_html__( 'Post now', 'publisherkits-socialpromoter' ) );
?> ).prop( 'disabled', false );
				}
			},
			error: function() {
				$( '#pkits-sp-compose-result' )
					.css( { background: '#fde8e8', color: '#d63638', border: '1px solid #f5c6c6' } )
					.text( <?php 
echo wp_json_encode( esc_html__( 'Request failed. Please try again.', 'publisherkits-socialpromoter' ) );
?> )
					.show();
				$btn.text( <?php 
echo wp_json_encode( esc_html__( 'Post now', 'publisherkits-socialpromoter' ) );
?> ).prop( 'disabled', false );
			}
		} );
	} );


	// ----------------------------------------------------------------
	// Post preview modal
	// ----------------------------------------------------------------
	var previewAccounts = <?php 
echo wp_json_encode( $preview_accounts );
?>;
	var previewImageCache = {}; // { platform_imageurl: dataUrl }
	var currentFullsizeUrl = ''; // Tracks the preview image for the full-size overlay
	var currentPreviewPlatform = '';

	// Show/hide preview button when panels exist with copy
	function updatePreviewBtn() {
		var hasPanels = $( '.pkits-sp-platform-panel' ).length > 0;
		$( '#pkits-sp-compose-preview' ).toggle( hasPanels );
	}

	$( document ).on( 'input', '.pkits-sp-platform-copy', updatePreviewBtn );

	// Build platform tabs from open panels
	function buildPreviewTabs() {
		var $tabs = $( '#pkits-sp-preview-tabs' ).empty();
		var first = true;
		$( '.pkits-sp-platform-panel' ).each( function() {
			var storageId = $( this ).data( 'storage-id' );
			var acc = previewAccounts[ storageId ];
			if ( ! acc ) { return; }
			var copy = $( '#pkits-sp-copy-' + storageId ).val().trim();
			if ( ! copy ) { return; }
			var platform = acc.platform;
			var labels = { x: 'X', facebook: 'Facebook', linkedin: 'LinkedIn' };
			var colours = { x: '#000', facebook: '#1877F2', linkedin: '#0A66C2' };
			var $tab = $( '<button type="button">' ).css( {
				padding: '10px 18px', border: 'none', background: 'transparent',
				color: '#5a6a7a', fontSize: '13px', fontWeight: '600', cursor: 'pointer',
				fontFamily: "'Source Sans 3',Arial,sans-serif", borderBottom: '3px solid transparent',
			} )
			.text( labels[ platform ] || platform )
			.attr( 'data-storage-id', storageId )
			.attr( 'data-platform', platform )
			.on( 'click', function() {
				$tabs.find( 'button' ).css( { color: '#5a6a7a', borderBottomColor: 'transparent', background: 'transparent' } );
				$( this ).css( { color: colours[ platform ] || '#1a2d4a', borderBottomColor: colours[ platform ] || '#1a2d4a', background: '#fff' } );
				currentPreviewPlatform = platform;
				renderPreviewCard( storageId, platform );
			} );
			if ( first ) {
				$tab.css( { color: colours[ platform ] || '#1a2d4a', borderBottomColor: colours[ platform ] || '#1a2d4a', background: '#fff' } );
				currentPreviewPlatform = platform;
				first = false;
			}
			$tabs.append( $tab );
		} );
	}

	// Render a platform card
	function renderPreviewCard( storageId, platform ) {
		var acc      = previewAccounts[ storageId ];
		var copy     = $( '#pkits-sp-copy-' + storageId ).val().trim();
		var imageUrl = $( '#pkits-sp-compose-image-url' ).val().trim();
		var postId   = currentPostId || 0;
		var $card    = $( '#pkits-sp-preview-card' ).empty();
		$( '#pkits-sp-preview-note' ).text( '' );

		var cacheKey = platform + '_' + imageUrl;

		if ( imageUrl && previewImageCache[ cacheKey ] ) {
			var cached = previewImageCache[ cacheKey ];
			currentFullsizeUrl = cached.data_url; $( '#pkits-sp-preview-fullsize' ).show();
			buildCard( $card, platform, acc, copy, cached.data_url );
			// Neutral hook: an add-on may enhance the rendered card (e.g. Pro
			// branded-image feedback). The free build attaches nothing.
			$( document ).trigger( 'pkits_sp_preview_rendered', [ $card, cached ] );
		} else if ( imageUrl ) {
			// Fetch the preview image
			$( '#pkits-sp-preview-loading' ).show();
			$.ajax( {
				url: ajaxUrl, type: 'POST',
				data: { action: 'pkits_sp_preview_image', nonce: nonce,
					image_url: imageUrl, platform: platform, post_id: postId },
				success: function( r ) {
					$( '#pkits-sp-preview-loading' ).hide();
					if ( r.success ) {
						previewImageCache[ cacheKey ] = r.data;
						currentFullsizeUrl = r.data.data_url; $( '#pkits-sp-preview-fullsize' ).show();
						buildCard( $card, platform, acc, copy, r.data.data_url );
						$( document ).trigger( 'pkits_sp_preview_rendered', [ $card, r.data ] );
					} else {
						// Fall back to raw image URL
						$( '#pkits-sp-preview-fullsize' ).hide();
						buildCard( $card, platform, acc, copy, imageUrl );
					}
				},
				error: function() {
					$( '#pkits-sp-preview-loading' ).hide();
					buildCard( $card, platform, acc, copy, imageUrl );
				}
			} );
		} else {
			$( '#pkits-sp-preview-fullsize' ).hide();
			buildCard( $card, platform, acc, copy, null );
		}
	}

<?php 
?>

	// Build the platform card HTML
	function buildCard( $card, platform, acc, copy, imageUrl ) {
		var platformConfig = {
			x: {
				bgColour: '#fff', accentColour: '#000',
				avatarBg: '#1a2d4a', avatarText: 'PK',
				imageRatio: '56.25%', // 16:9
				footer: '&#128172;&nbsp; &nbsp;&#128257;&nbsp; &nbsp;&#9825;&nbsp; &nbsp;&#128202;',
				footerColour: '#536471',
				maxChars: 280,
			},
			facebook: {
				bgColour: '#fff', accentColour: '#1877F2',
				avatarBg: '#1877F2', avatarText: 'PK',
				imageRatio: '52.36%', // 1.91:1
				footer: '&#128077; Like &nbsp;&nbsp; &#128172; Comment &nbsp;&nbsp; &#8599; Share',
				footerColour: '#606770',
				maxChars: 63206,
			},
			linkedin: {
				bgColour: '#fff', accentColour: '#0A66C2',
				avatarBg: '#0A66C2', avatarText: 'PK',
				imageRatio: '52.25%', // 1.91:1
				footer: '&#128077; Like &nbsp;&nbsp; &#128172; Comment &nbsp;&nbsp; &#128257; Repost &nbsp;&nbsp; &#9993; Send',
				footerColour: '#666',
				maxChars: 3000,
			},
			bluesky: {
				bgColour: '#fff', accentColour: '#0085FF',
				avatarBg: '#0085FF', avatarText: 'PK',
				imageRatio: '56.25%', // 16:9
				footer: '&#128172;&nbsp; &nbsp;&#128257;&nbsp; &nbsp;&#9825;',
				footerColour: '#42576c',
				maxChars: 300,
			},
		};

		var cfg       = platformConfig[ platform ] || platformConfig.x;
		var label     = acc ? acc.label : platform;
		var charCount = copy.length;
		var overLimit = cfg.maxChars < 10000 && charCount > cfg.maxChars;

		// Truncate copy for Facebook preview (shows first 3 lines then "See more")
		var displayCopy = copy;
		var seeMore     = '';
		if ( platform === 'facebook' && copy.length > 120 ) {
			displayCopy = copy.substring( 0, 120 );
			seeMore     = '... <span style="color:#1877F2;cursor:pointer;">See more</span>';
		} else if ( platform === 'linkedin' && copy.length > 200 ) {
			displayCopy = copy.substring( 0, 200 );
			seeMore     = '... <span style="color:#0A66C2;cursor:pointer;">see more</span>';
		}

		var html = '<div style="background:' + cfg.bgColour + ';border-radius:8px;box-shadow:0 1px 3px rgba(0,0,0,0.12),0 4px 16px rgba(0,0,0,0.08);overflow:hidden;">';

		// Card header
		html += '<div style="padding:12px 14px;display:flex;align-items:center;gap:10px;">';
		html += '<div style="width:38px;height:38px;border-radius:' + ( platform === 'x' ? '50%' : '4px' ) + ';background:' + cfg.avatarBg + ';display:flex;align-items:center;justify-content:center;color:#fff;font-size:11px;font-weight:700;flex-shrink:0;">' + cfg.avatarText + '</div>';
		html += '<div style="flex:1;">';
		html += '<div style="font-weight:700;font-size:13px;color:#0f1419;">' + $( '<span>' ).text( label ).html() + '</div>';

		if ( platform === 'x' ) {
			html += '<div style="font-size:12px;color:#536471;">@' + $( '<span>' ).text( label.toLowerCase().replace( /[^a-z0-9]/g, '' ) ).html() + '</div>';
		} else if ( platform === 'facebook' ) {
			html += '<div style="font-size:11px;color:#606770;">Just now &middot; &#127757;</div>';
		} else if ( platform === 'linkedin' ) {
			html += '<div style="font-size:11px;color:#666;">Just now &middot; &#127757;</div>';
		}
		html += '</div>';
		if ( platform === 'x' ) {
			html += '<div style="background:#000;color:#fff;font-size:11px;font-weight:700;padding:4px 12px;border-radius:20px;cursor:pointer;">Follow</div>';
		}
		html += '</div>';

		// Copy text
		html += '<div style="padding:2px 14px 12px;font-size:14px;color:#0f1419;line-height:1.5;white-space:pre-wrap;">';
		html += $( '<span>' ).text( displayCopy ).html() + seeMore;
		html += '</div>';

		// Image
		if ( imageUrl ) {
			html += '<div style="position:relative;width:100%;padding-top:' + cfg.imageRatio + ';background:#e8edf2;overflow:hidden;">';
			html += '<img class="pkits-sp-preview-img" alt="" style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;" />'; // src set via .attr() after insertion (below)
			html += '</div>';
		} else {
			// Placeholder
			var dims = { x: '1200×675', facebook: '1200×630', linkedin: '1200×627' };
			html += '<div style="position:relative;width:100%;padding-top:' + cfg.imageRatio + ';background:#e8edf2;">';
			html += '<div style="position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#aaa;font-size:12px;">No image selected &nbsp;&#183;&nbsp; ' + ( dims[ platform ] || '' ) + '</div>';
			html += '</div>';
		}

		// Footer actions
		html += '<div style="padding:8px 14px;border-top:1px solid #f0f0f0;font-size:12px;color:' + cfg.footerColour + ';display:flex;justify-content:space-around;">';
		html += cfg.footer;
		html += '</div></div>';

		// Character count badge
		var charHtml = '<div style="margin-top:8px;text-align:right;font-size:11px;color:' + ( overLimit ? '#d63638' : '#8a9ab0' ) + ';">'
			+ charCount + ' / ' + ( cfg.maxChars < 10000 ? cfg.maxChars : '&#8734;' ) + ' chars'
			+ ( overLimit ? ' &nbsp;<strong>Over limit</strong>' : '' )
			+ '</div>';

		$card.html( html + charHtml );
		// Set the preview image src via attr() so a data: or user URL is never
		// interpolated into an HTML string (attribute-context safety).
		if ( imageUrl ) { $card.find( '.pkits-sp-preview-img' ).attr( 'src', imageUrl ); }
	}

	// Open preview modal
	$( '#pkits-sp-compose-preview' ).on( 'click', function() {
		previewImageCache = {}; // Clear cache on each open so fresh images are fetched
		buildPreviewTabs();
		// Trigger click on first tab
		$( '#pkits-sp-preview-tabs button:first' ).trigger( 'click' );
		$( '#pkits-sp-preview-modal' ).fadeIn( 200 );
		$( 'body' ).css( 'overflow', 'hidden' );
	} );

	// Close preview modal
	$( '#pkits-sp-preview-close, #pkits-sp-preview-close-btn' ).on( 'click', closePreview );

	// Full-size overlay: render the preview image in-page (data: URLs cannot
	// be opened as a top-level new tab in modern browsers, hence the overlay).
	$( '#pkits-sp-preview-fullsize' ).on( 'click', function() {
		if ( ! currentFullsizeUrl ) { return; }
		$( '#pkits-sp-fullsize-img' ).attr( 'src', currentFullsizeUrl );
		$( '#pkits-sp-fullsize-overlay' ).css( 'display', 'block' );
	} );
	function closeFullsize() {
		$( '#pkits-sp-fullsize-overlay' ).hide();
		$( '#pkits-sp-fullsize-img' ).attr( 'src', '' );
	}
	$( '#pkits-sp-fullsize-close' ).on( 'click', closeFullsize );
	$( '#pkits-sp-fullsize-overlay' ).on( 'click', function( e ) {
		if ( e.target === this ) { closeFullsize(); }
	} );

<?php 
?>
	$( '#pkits-sp-preview-modal' ).on( 'click', function( e ) {
		if ( $( e.target ).is( '#pkits-sp-preview-modal' ) ) { closePreview(); }
	} );
	$( document ).on( 'keydown', function( e ) {
		if ( e.key === 'Escape' ) { closePreview(); }
	} );

	function closePreview() {
		$( '#pkits-sp-preview-modal' ).fadeOut( 150 );
		$( 'body' ).css( 'overflow', '' );
	}

	// ----------------------------------------------------------------
	// Image picker (WP media library)
	// ----------------------------------------------------------------
	var composeMediaFrame;

	$( '#pkits-sp-compose-image-select' ).on( 'click', function() {
		if ( composeMediaFrame ) { composeMediaFrame.open(); return; }
		composeMediaFrame = wp.media( {
			title:    <?php 
echo wp_json_encode( esc_html__( 'Select post image', 'publisherkits-socialpromoter' ) );
?>,
			button:   { text: <?php 
echo wp_json_encode( esc_html__( 'Use this image', 'publisherkits-socialpromoter' ) );
?> },
			multiple: false,
			library:  { type: 'image' },
		} );
		composeMediaFrame.on( 'select', function() {
			var att   = composeMediaFrame.state().get( 'selection' ).first().toJSON();
			var thumb = att.sizes && att.sizes.medium ? att.sizes.medium.url : att.url;
			$( '#pkits-sp-compose-image-id' ).val( att.id );
			$( '#pkits-sp-compose-image-url' ).val( att.url );
			$( '#pkits-sp-compose-image-thumb' ).html(
				$( '<img>' ).attr( 'src', thumb ).attr( 'style', 'height:60px;border-radius:4px;border:1px solid #d0e0f0;object-fit:cover;' )
			);
			$( '#pkits-sp-compose-image-remove' ).show();
			$( '#pkits-sp-compose-image-select' ).text( <?php 
echo wp_json_encode( esc_html__( 'Change image', 'publisherkits-socialpromoter' ) );
?> );
		} );
		composeMediaFrame.open();
	} );

	$( '#pkits-sp-compose-image-remove' ).on( 'click', function() {
		$( '#pkits-sp-compose-image-id' ).val( '' );
		$( '#pkits-sp-compose-image-url' ).val( '' );
		$( '#pkits-sp-compose-image-thumb' ).empty();
		$( this ).hide();
		$( '#pkits-sp-compose-image-select' ).text( <?php 
echo wp_json_encode( esc_html__( 'Select image', 'publisherkits-socialpromoter' ) );
?> );
	} );



} )( jQuery );
<?php 
wp_add_inline_script( 'pkits-sp-admin', ob_get_clean() );
?>

<?php 
ob_start();
?>
/* Compose page account selectors */
.pkits-sp-compose-accounts {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.pkits-sp-compose-account-option {
	display: flex;
	align-items: center;
	gap: 7px;
	padding: 8px 14px 8px 10px;
	border: 1.5px solid #d0e0f0;
	border-radius: 6px;
	cursor: pointer;
	transition: border-color 0.15s, background 0.15s;
	background: #fff;
	user-select: none;
}

.pkits-sp-compose-account-option:hover {
	border-color: #4a7fc1;
	background: #f5f9ff;
}

.pkits-sp-compose-account-option.is-selected {
	border-color: #1a2d4a;
	background: #e8f0f8;
}

.pkits-sp-compose-account-option input[type="checkbox"] {
	display: none;
}

.pkits-sp-compose-account-name {
	font-size: 13px;
	color: #1a2d4a;
	font-weight: 500;
}

.pkits-sp-compose-account-limit {
	font-size: 11px;
	color: #8a9ab0;
}

/* Platform panel animation */
.pkits-sp-platform-panel {
	animation: pkits-fade-in 0.2s ease;
}

@keyframes pkits-fade-in {
	from { opacity: 0; transform: translateY(-4px); }
	to   { opacity: 1; transform: translateY(0); }
}

.pkits-sp-over-limit {
	color: #d63638 !important;
	font-weight: 700 !important;
}
<?php 
wp_add_inline_style( 'pkits-sp-admin', ob_get_clean() );