<?php
/**
 * File Path: includes/admin/authors/class-mbs-author-social-links.php
 *
 * Author Social Links — Platform Registry and Decoder
 *
 * Provides the 38-platform PLATFORMS registry, the decode_social_links()
 * JSON blob reader (with lazy migration from 7 legacy individual meta keys),
 * and the get_platform_info() helper used by templates and the admin card UI.
 *
 * Extracted from MBS_Tab_Authors (REF-009, Session 136).
 * Call sites previously referencing MBS_Tab_Authors::{method} now use
 * MBS_Author_Social_Links::{method}.
 *
 * @package    My_Book_Showroom
 * @subpackage Includes/Admin/Authors
 * @since      1.1.0
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class MBS_Author_Social_Links { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix

	/**
	 * Social platform registry — Sprint SOCIAL-LINKS.
	 *
	 * Replaces the old SOCIAL_FIELDS constant (7 platforms, individual meta keys).
	 * Storage: single JSON blob in term meta key mbs_author_social_links.
	 *
	 * Structure: two groups ('global' and 'regional'), each with a 'label' and
	 * an 'items' sub-array keyed by platform slug. Each item has:
	 *   'label'       — human-readable platform name
	 *   'placeholder' — example URL shown in the admin URL input
	 *   'abbr'        — 2-char badge shown on the front-end icon
	 *
	 * @var array<string, array{label: string, items: array<string, array{label: string, placeholder: string, abbr: string}>}>
	 */
	public const PLATFORMS = array(
		'global' => array(
			'label' => 'Global & Book Platforms',
			'items' => array(
				'facebook'      => array( 'label' => 'Facebook',           'placeholder' => 'https://facebook.com/username',             'abbr' => 'Fb' ),
				'instagram'     => array( 'label' => 'Instagram',          'placeholder' => 'https://instagram.com/username',            'abbr' => 'In' ),
				'tiktok'        => array( 'label' => 'TikTok',             'placeholder' => 'https://tiktok.com/@username',              'abbr' => 'Tk' ),
				'youtube'       => array( 'label' => 'YouTube',            'placeholder' => 'https://youtube.com/@channel',             'abbr' => 'Yt' ),
				'rumble'        => array( 'label' => 'Rumble',             'placeholder' => 'https://rumble.com/user/username',          'abbr' => 'Ru' ),
				'twitch'        => array( 'label' => 'Twitch',             'placeholder' => 'https://twitch.tv/username',               'abbr' => 'Tv' ),
				'linkedin'      => array( 'label' => 'LinkedIn',           'placeholder' => 'https://linkedin.com/in/username',         'abbr' => 'Li' ),
				'twitter'       => array( 'label' => 'X (Twitter)',        'placeholder' => 'https://x.com/username',                  'abbr' => 'X' ),
				'pinterest'     => array( 'label' => 'Pinterest',          'placeholder' => 'https://pinterest.com/username',          'abbr' => 'Pi' ),
				'threads'       => array( 'label' => 'Threads',            'placeholder' => 'https://threads.net/@username',           'abbr' => 'Th' ),
				'bluesky'       => array( 'label' => 'Bluesky',            'placeholder' => 'https://bsky.app/profile/handle',         'abbr' => 'Bs' ),
				'truth-social'  => array( 'label' => 'Truth Social',       'placeholder' => 'https://truthsocial.com/@username',       'abbr' => 'Ts' ),
				'telegram'      => array( 'label' => 'Telegram',           'placeholder' => 'https://t.me/username',                   'abbr' => 'Tg' ),
				'whatsapp'      => array( 'label' => 'WhatsApp',           'placeholder' => 'https://wa.me/phonenumber',              'abbr' => 'Wa' ),
				'snapchat'      => array( 'label' => 'Snapchat',           'placeholder' => 'https://snapchat.com/add/username',      'abbr' => 'Sc' ),
				'reddit'        => array( 'label' => 'Reddit',             'placeholder' => 'https://reddit.com/u/username',          'abbr' => 'Re' ),
				'discord'       => array( 'label' => 'Discord',            'placeholder' => 'https://discord.gg/invite',             'abbr' => 'Dc' ),
				'goodreads'     => array( 'label' => 'Goodreads',          'placeholder' => 'https://goodreads.com/author/show/...',  'abbr' => 'Gr' ),
				'bookbub'       => array( 'label' => 'BookBub',            'placeholder' => 'https://bookbub.com/authors/...',        'abbr' => 'Bb' ),
				'amazon-author' => array( 'label' => 'Amazon Author Page', 'placeholder' => 'https://amazon.com/author/...',          'abbr' => 'Az' ),
				'wattpad'       => array( 'label' => 'Wattpad',            'placeholder' => 'https://wattpad.com/user/username',     'abbr' => 'Wp' ),
				'substack'      => array( 'label' => 'Substack',           'placeholder' => 'https://username.substack.com',         'abbr' => 'Ss' ),
				'patreon'       => array( 'label' => 'Patreon',            'placeholder' => 'https://patreon.com/username',          'abbr' => 'Pa' ),
				'medium'        => array( 'label' => 'Medium',             'placeholder' => 'https://medium.com/@username',          'abbr' => 'Md' ),
				'tumblr'        => array( 'label' => 'Tumblr',             'placeholder' => 'https://username.tumblr.com',           'abbr' => 'Tu' ),
				'quora'         => array( 'label' => 'Quora',              'placeholder' => 'https://quora.com/profile/username',    'abbr' => 'Qu' ),
			),
		),
		'regional' => array(
			'label' => 'Regional Platforms',
			'items' => array(
				'weibo'       => array( 'label' => 'Weibo',                 'placeholder' => 'https://weibo.com/username',                      'abbr' => 'Wb' ),
				'xiaohongshu' => array( 'label' => 'Xiaohongshu (RedNote)', 'placeholder' => 'https://xiaohongshu.com/user/profile/...',       'abbr' => 'XH' ),
				'douyin'      => array( 'label' => 'Douyin',                'placeholder' => 'https://douyin.com/user/...',                     'abbr' => 'Dy' ),
				'bilibili'    => array( 'label' => 'Bilibili',              'placeholder' => 'https://space.bilibili.com/...',                  'abbr' => 'Bi' ),
				'kuaishou'    => array( 'label' => 'Kuaishou',              'placeholder' => 'https://kuaishou.com/...',                        'abbr' => 'Ks' ),
				'qzone'       => array( 'label' => 'Qzone',                 'placeholder' => 'https://user.qzone.qq.com/...',                   'abbr' => 'Qz' ),
				'vk'          => array( 'label' => 'VK (Vkontakte)',        'placeholder' => 'https://vk.com/username',                        'abbr' => 'VK' ),
				'line'        => array( 'label' => 'Line',                  'placeholder' => 'https://line.me/ti/p/...',                        'abbr' => 'Ln' ),
				'viber'       => array( 'label' => 'Viber',                 'placeholder' => 'https://viber.com/...',                           'abbr' => 'Vi' ),
				'wechat'      => array( 'label' => 'WeChat',                'placeholder' => 'WeChat uses QR codes — paste official account URL if available.', 'abbr' => 'Wc' ),
				'naver'       => array( 'label' => 'Naver Blog',            'placeholder' => 'https://blog.naver.com/username',                 'abbr' => 'Nv' ),
				'mastodon'    => array( 'label' => 'Mastodon',              'placeholder' => 'https://mastodon.social/@username',              'abbr' => 'Ma' ),
			),
		),
	);

	/**
	 * Decode the social links JSON blob for a given author term.
	 *
	 * Returns an array of entries, each with keys 'platform', 'url', and
	 * optionally 'label' (for custom platforms). If no JSON blob is stored
	 * yet, lazily migrates from the 7 legacy individual meta keys.
	 *
	 * @param int $term_id Author term ID.
	 * @return array<int, array{platform: string, url: string, label?: string}>
	 */
	public static function decode_social_links( int $term_id ): array {
		// RF-012: read from DB table (MBS_Author_Social_Link_DAO) instead of term meta JSON blob.
		$db_links = MBS_Author_Social_Link_DAO::get_for_term( $term_id );
		if ( ! empty( $db_links ) ) {
			return $db_links;
		}

		// Fallback: read from term meta JSON blob (pre-RF-012 data not yet migrated).
		$json = (string) get_term_meta( $term_id, 'mbs_author_social_links', true );
		if ( '' !== $json ) {
			$decoded = json_decode( $json, true );
			return is_array( $decoded ) ? $decoded : array();
		}

		// Lazy migration from legacy individual meta keys (pre-SOCIAL-LINKS sprint).
		$legacy_map = array(
			'mbs_author_twitter_url'   => 'twitter',
			'mbs_author_facebook_url'  => 'facebook',
			'mbs_author_instagram_url' => 'instagram',
			'mbs_author_tiktok_url'    => 'tiktok',
			'mbs_author_goodreads_url' => 'goodreads',
			'mbs_author_bookbub_url'   => 'bookbub',
			'mbs_author_linkedin_url'  => 'linkedin',
		);
		$migrated = array();
		foreach ( $legacy_map as $meta_key => $slug ) {
			$url = (string) get_term_meta( $term_id, $meta_key, true );
			if ( '' !== $url ) {
				$migrated[] = array( 'platform' => $slug, 'url' => $url );
			}
		}
		// V2-C-025: persist Layer-3 data to the DAO so future loads hit Layer 1
		// instead of re-running 7 get_term_meta() calls on every page load.
		if ( ! empty( $migrated ) ) {
			MBS_Author_Social_Link_DAO::save_for_term( $term_id, $migrated );
		}
		return $migrated;
	}

	/**
	 * Return platform info (label, placeholder, abbr) for a given slug.
	 *
	 * Falls back gracefully for custom or unknown slugs.
	 *
	 * @param string $slug Platform slug (e.g. 'instagram', 'truth-social').
	 * @return array{label: string, placeholder: string, abbr: string}
	 */
	public static function get_platform_info( string $slug ): array {
		foreach ( self::PLATFORMS as $group ) {
			if ( isset( $group['items'][ $slug ] ) ) {
				return $group['items'][ $slug ];
			}
		}
		return array(
			'label'       => ucfirst( str_replace( array( '-', '_' ), ' ', $slug ) ),
			'placeholder' => 'https://...',
			'abbr'        => strtoupper( substr( $slug, 0, 2 ) ),
		);
	}
}
