import { FolkShape } from "./folk-shape";
import { css, html } from "./tags";

const styles = css`
	:host {
		background: var(--rs-bg-surface, #fff);
		color: var(--rs-text-primary, #1e293b);
		border-radius: 12px;
		box-shadow: var(--rs-shadow-sm);
		min-width: 280px;
		min-height: 140px;
		overflow: hidden;
		font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
	}

	:host(:hover) {
		box-shadow: var(--rs-shadow-md);
	}

	:host([data-status="posted"]) {
		box-shadow: 0 0 0 2px rgba(34, 197, 94, 0.4), var(--rs-shadow-sm);
	}

	:host([data-status="scheduled"]) {
		box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.4), var(--rs-shadow-sm);
	}

	:host([data-status="failed"]) {
		box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.4), var(--rs-shadow-sm);
	}

	.header {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 10px 14px;
		cursor: move;
		color: white;
		border-radius: 12px 12px 0 0;
	}

	.header-left {
		display: flex;
		align-items: center;
		gap: 8px;
	}

	.platform-icon {
		font-size: 18px;
		width: 28px;
		height: 28px;
		display: flex;
		align-items: center;
		justify-content: center;
		background: rgba(255, 255, 255, 0.2);
		border-radius: 6px;
	}

	.platform-name {
		font-size: 13px;
		font-weight: 600;
		letter-spacing: 0.3px;
	}

	.header-actions {
		display: flex;
		gap: 4px;
	}

	.header-actions button {
		background: rgba(255, 255, 255, 0.2);
		border: none;
		color: white;
		width: 24px;
		height: 24px;
		border-radius: 4px;
		cursor: pointer;
		font-size: 12px;
		display: flex;
		align-items: center;
		justify-content: center;
	}

	.header-actions button:hover {
		background: rgba(255, 255, 255, 0.3);
	}

	.body {
		padding: 12px 14px;
	}

	.post-type {
		display: inline-block;
		font-size: 10px;
		font-weight: 600;
		text-transform: uppercase;
		letter-spacing: 0.5px;
		padding: 2px 8px;
		border-radius: 10px;
		background: var(--rs-bg-surface-raised);
		color: var(--rs-text-muted);
		margin-bottom: 8px;
	}

	.content-preview {
		font-size: 13px;
		line-height: 1.5;
		color: var(--rs-text-primary);
		display: -webkit-box;
		-webkit-line-clamp: 3;
		-webkit-box-orient: vertical;
		overflow: hidden;
		margin-bottom: 8px;
	}

	.media-preview {
		width: 100%;
		height: 100px;
		border-radius: 8px;
		background: var(--rs-bg-surface-raised);
		display: flex;
		align-items: center;
		justify-content: center;
		margin-bottom: 8px;
		overflow: hidden;
		border: 1px solid var(--rs-border);
	}

	.media-preview img {
		width: 100%;
		height: 100%;
		object-fit: cover;
	}

	.media-placeholder {
		color: var(--rs-text-secondary);
		font-size: 12px;
		display: flex;
		flex-direction: column;
		align-items: center;
		gap: 4px;
	}

	.media-placeholder .icon {
		font-size: 24px;
	}

	.hashtags {
		display: flex;
		flex-wrap: wrap;
		gap: 4px;
		margin-bottom: 8px;
	}

	.hashtag {
		font-size: 11px;
		color: var(--rs-primary);
		background: rgba(99, 102, 241, 0.1);
		padding: 2px 6px;
		border-radius: 4px;
	}

	.footer {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 8px 14px;
		background: var(--rs-bg-surface-raised);
		border-top: 1px solid var(--rs-border);
		border-radius: 0 0 12px 12px;
	}

	.schedule {
		display: flex;
		align-items: center;
		gap: 6px;
		font-size: 11px;
		color: var(--rs-text-muted);
	}

	.schedule-icon {
		font-size: 13px;
	}

	.schedule-time {
		font-weight: 500;
		color: var(--rs-text-secondary);
	}

	.status-badge {
		font-size: 10px;
		font-weight: 600;
		text-transform: uppercase;
		letter-spacing: 0.5px;
		padding: 3px 8px;
		border-radius: 10px;
	}

	.status-badge.draft {
		background: var(--rs-bg-surface-raised);
		color: var(--rs-text-muted);
	}

	.status-badge.scheduled {
		background: rgba(59, 130, 246, 0.15);
		color: #2563eb;
	}

	.status-badge.posted {
		background: rgba(34, 197, 94, 0.15);
		color: var(--rs-success);
	}

	.status-badge.failed {
		background: rgba(239, 68, 68, 0.15);
		color: var(--rs-error);
	}

	.step-number {
		position: absolute;
		top: -8px;
		left: -8px;
		width: 24px;
		height: 24px;
		border-radius: 50%;
		background: var(--rs-bg-surface-raised);
		color: var(--rs-text-primary);
		font-size: 11px;
		font-weight: 700;
		display: flex;
		align-items: center;
		justify-content: center;
		z-index: 1;
		border: 2px solid var(--rs-bg-surface);
		box-shadow: var(--rs-shadow-sm);
	}

	.edit-overlay {
		display: none;
		position: absolute;
		inset: 0;
		background: var(--rs-bg-surface);
		z-index: 10;
		border-radius: 12px;
		flex-direction: column;
	}

	.edit-overlay.active {
		display: flex;
	}

	.edit-header {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 10px 14px;
		border-bottom: 1px solid var(--rs-border);
	}

	.edit-header span {
		font-size: 13px;
		font-weight: 600;
		color: var(--rs-text-primary);
	}

	.edit-body {
		flex: 1;
		padding: 12px 14px;
		overflow-y: auto;
	}

	.edit-field {
		display: flex;
		flex-direction: column;
		gap: 4px;
		margin-bottom: 12px;
	}

	.edit-field label {
		font-size: 11px;
		font-weight: 500;
		color: var(--rs-text-muted);
		text-transform: uppercase;
		letter-spacing: 0.5px;
	}

	.edit-field input,
	.edit-field textarea,
	.edit-field select {
		padding: 8px 10px;
		border: 1px solid var(--rs-input-border);
		border-radius: 6px;
		font-size: 13px;
		outline: none;
		font-family: inherit;
		background: var(--rs-input-bg);
		color: var(--rs-input-text);
	}

	.edit-field input:focus,
	.edit-field textarea:focus,
	.edit-field select:focus {
		border-color: var(--rs-primary);
		box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
	}

	.edit-field textarea {
		min-height: 80px;
		resize: vertical;
	}

	.edit-actions {
		display: flex;
		gap: 8px;
		padding: 10px 14px;
		border-top: 1px solid var(--rs-border);
	}

	.edit-actions button {
		flex: 1;
		padding: 8px;
		border-radius: 6px;
		font-size: 12px;
		font-weight: 500;
		cursor: pointer;
		border: 1px solid var(--rs-border);
	}

	.edit-actions .save-btn {
		background: var(--rs-primary);
		color: white;
		border-color: var(--rs-primary);
	}

	.edit-actions .save-btn:hover {
		background: var(--rs-primary-hover);
	}

	.edit-actions .cancel-btn {
		background: var(--rs-bg-surface);
		color: var(--rs-text-muted);
	}

	.edit-actions .cancel-btn:hover {
		background: var(--rs-bg-surface-raised);
	}
`;

export type SocialPlatform =
	| "x"
	| "linkedin"
	| "instagram"
	| "youtube"
	| "threads"
	| "bluesky"
	| "tiktok"
	| "facebook";

export type PostStatus = "draft" | "scheduled" | "posted" | "failed";

export type PostType =
	| "text"
	| "image"
	| "video"
	| "carousel"
	| "story"
	| "reel"
	| "thread"
	| "article"
	| "short";

const PLATFORM_CONFIG: Record<
	SocialPlatform,
	{ icon: string; label: string; color: string }
> = {
	x: { icon: "𝕏", label: "X", color: "#000000" },
	linkedin: { icon: "in", label: "LinkedIn", color: "#0A66C2" },
	instagram: { icon: "📷", label: "Instagram", color: "#E4405F" },
	youtube: { icon: "▶", label: "YouTube", color: "#FF0000" },
	threads: { icon: "@", label: "Threads", color: "#000000" },
	bluesky: { icon: "🩷", label: "Bluesky", color: "#0085FF" },
	tiktok: { icon: "♫", label: "TikTok", color: "#010101" },
	facebook: { icon: "f", label: "Facebook", color: "#1877F2" },
};

declare global {
	interface HTMLElementTagNameMap {
		"folk-social-post": FolkSocialPost;
	}
}

export class FolkSocialPost extends FolkShape {
	static override tagName = "folk-social-post";

	static {
		const sheet = new CSSStyleSheet();
		const parentRules = Array.from(FolkShape.styles.cssRules)
			.map((r) => r.cssText)
			.join("\n");
		const childRules = Array.from(styles.cssRules)
			.map((r) => r.cssText)
			.join("\n");
		sheet.replaceSync(`${parentRules}\n${childRules}`);
		this.styles = sheet;
	}

	#platform: SocialPlatform = "x";
	#postType: PostType = "text";
	#content = "";
	#mediaUrl = "";
	#mediaType = ""; // "image", "video", "carousel"
	#scheduledAt = "";
	#status: PostStatus = "draft";
	#hashtags: string[] = [];
	#stepNumber = 0;
	#isEditing = false;

	// DOM references
	#contentPreviewEl: HTMLElement | null = null;
	#statusBadgeEl: HTMLElement | null = null;
	#scheduleTimeEl: HTMLElement | null = null;
	#editOverlay: HTMLElement | null = null;
	#mediaPreviewEl: HTMLElement | null = null;
	#hashtagsEl: HTMLElement | null = null;
	#postTypeEl: HTMLElement | null = null;
	#stepNumberEl: HTMLElement | null = null;

	get platform() {
		return this.#platform;
	}
	set platform(value: SocialPlatform) {
		this.#platform = value;
		this.requestUpdate("platform");
		this.#dispatchChange();
	}

	get postType() {
		return this.#postType;
	}
	set postType(value: PostType) {
		this.#postType = value;
		if (this.#postTypeEl) this.#postTypeEl.textContent = value;
		this.requestUpdate("postType");
		this.#dispatchChange();
	}

	get content() {
		return this.#content;
	}
	set content(value: string) {
		this.#content = value;
		if (this.#contentPreviewEl) this.#contentPreviewEl.textContent = value;
		this.requestUpdate("content");
		this.#dispatchChange();
	}

	get mediaUrl() {
		return this.#mediaUrl;
	}
	set mediaUrl(value: string) {
		this.#mediaUrl = value;
		this.#renderMedia();
		this.requestUpdate("mediaUrl");
		this.#dispatchChange();
	}

	get mediaType() {
		return this.#mediaType;
	}
	set mediaType(value: string) {
		this.#mediaType = value;
		this.#renderMedia();
		this.requestUpdate("mediaType");
		this.#dispatchChange();
	}

	get scheduledAt() {
		return this.#scheduledAt;
	}
	set scheduledAt(value: string) {
		this.#scheduledAt = value;
		if (this.#scheduleTimeEl)
			this.#scheduleTimeEl.textContent = this.#formatSchedule(value);
		this.requestUpdate("scheduledAt");
		this.#dispatchChange();
	}

	get status(): PostStatus {
		return this.#status;
	}
	set status(value: PostStatus) {
		this.#status = value;
		this.setAttribute("data-status", value);
		if (this.#statusBadgeEl) {
			this.#statusBadgeEl.className = `status-badge ${value}`;
			this.#statusBadgeEl.textContent = value;
		}
		this.requestUpdate("status");
		this.#dispatchChange();
	}

	get hashtags(): string[] {
		return this.#hashtags;
	}
	set hashtags(value: string[]) {
		this.#hashtags = value;
		this.#renderHashtags();
		this.requestUpdate("hashtags");
		this.#dispatchChange();
	}

	get stepNumber(): number {
		return this.#stepNumber;
	}
	set stepNumber(value: number) {
		this.#stepNumber = value;
		if (this.#stepNumberEl) {
			this.#stepNumberEl.textContent = String(value);
			this.#stepNumberEl.style.display = value > 0 ? "flex" : "none";
		}
		this.requestUpdate("stepNumber");
		this.#dispatchChange();
	}

	#dispatchChange() {
		this.dispatchEvent(
			new CustomEvent("content-change", {
				detail: this.toJSON(),
			}),
		);
	}

	override createRenderRoot() {
		const root = super.createRenderRoot();

		// Parse attributes
		const platformAttr = this.getAttribute("platform") as SocialPlatform;
		if (platformAttr && platformAttr in PLATFORM_CONFIG)
			this.#platform = platformAttr;
		const postTypeAttr = this.getAttribute("post-type") as PostType;
		if (postTypeAttr) this.#postType = postTypeAttr;
		const contentAttr = this.getAttribute("content");
		if (contentAttr) this.#content = contentAttr;
		const statusAttr = this.getAttribute("status") as PostStatus;
		if (statusAttr) this.#status = statusAttr;
		const stepAttr = this.getAttribute("step");
		if (stepAttr) this.#stepNumber = parseInt(stepAttr, 10);

		const config = PLATFORM_CONFIG[this.#platform];

		const wrapper = document.createElement("div");
		wrapper.style.position = "relative";
		wrapper.style.height = "100%";

		wrapper.innerHTML = html`
			<span
				class="step-number"
				style="display: ${this.#stepNumber > 0 ? "flex" : "none"}"
				>${this.#stepNumber}</span
			>
			<div class="header" style="background: ${config.color}">
				<div class="header-left">
					<span class="platform-icon">${config.icon}</span>
					<span class="platform-name">${config.label}</span>
				</div>
				<div class="header-actions">
					<button class="edit-btn" title="Edit">✏</button>
					<button class="close-btn" title="Remove">×</button>
				</div>
			</div>
			<div class="body">
				<span class="post-type">${this.#escapeHtml(this.#postType)}</span>
				<div class="content-preview">
					${this.#escapeHtml(this.#content) || "No content yet..."}
				</div>
				<div class="media-preview">
					<div class="media-placeholder">
						<span class="icon">🖼</span>
						<span>No media</span>
					</div>
				</div>
				<div class="hashtags"></div>
			</div>
			<div class="footer">
				<div class="schedule">
					<span class="schedule-icon">📅</span>
					<span class="schedule-time"
						>${this.#formatSchedule(this.#scheduledAt)}</span
					>
				</div>
				<span class="status-badge ${this.#status}">${this.#status}</span>
			</div>
			<div class="edit-overlay">
				<div class="edit-header">
					<span>Edit Post</span>
				</div>
				<div class="edit-body">
					<div class="edit-field">
						<label>Platform</label>
						<select class="edit-platform">
							<option value="x">X (Twitter)</option>
							<option value="linkedin">LinkedIn</option>
							<option value="instagram">Instagram</option>
							<option value="youtube">YouTube</option>
							<option value="threads">Threads</option>
							<option value="bluesky">Bluesky</option>
							<option value="tiktok">TikTok</option>
							<option value="facebook">Facebook</option>
						</select>
					</div>
					<div class="edit-field">
						<label>Post Type</label>
						<select class="edit-post-type">
							<option value="text">Text</option>
							<option value="image">Image</option>
							<option value="video">Video</option>
							<option value="carousel">Carousel</option>
							<option value="story">Story</option>
							<option value="reel">Reel</option>
							<option value="thread">Thread</option>
							<option value="article">Article</option>
							<option value="short">Short</option>
						</select>
					</div>
					<div class="edit-field">
						<label>Content</label>
						<textarea
							class="edit-content"
							placeholder="Write your post..."
						></textarea>
					</div>
					<div class="edit-field">
						<label>Media URL</label>
						<input
							type="text"
							class="edit-media-url"
							placeholder="https://..."
						/>
					</div>
					<div class="edit-field">
						<label>Scheduled At</label>
						<input type="datetime-local" class="edit-scheduled" />
					</div>
					<div class="edit-field">
						<label>Hashtags (comma-separated)</label>
						<input
							type="text"
							class="edit-hashtags"
							placeholder="#launch, #product"
						/>
					</div>
					<div class="edit-field">
						<label>Status</label>
						<select class="edit-status">
							<option value="draft">Draft</option>
							<option value="scheduled">Scheduled</option>
							<option value="posted">Posted</option>
							<option value="failed">Failed</option>
						</select>
					</div>
				</div>
				<div class="edit-actions">
					<button class="cancel-btn">Cancel</button>
					<button class="save-btn">Save</button>
				</div>
			</div>
		`;

		// Replace the container div (slot's parent) with our wrapper
		const slot = root.querySelector("slot");
		const containerDiv = slot?.parentElement as HTMLElement;
		if (containerDiv) {
			containerDiv.replaceWith(wrapper);
		}

		// Cache DOM refs
		this.#contentPreviewEl = wrapper.querySelector(".content-preview");
		this.#statusBadgeEl = wrapper.querySelector(".status-badge");
		this.#scheduleTimeEl = wrapper.querySelector(".schedule-time");
		this.#editOverlay = wrapper.querySelector(".edit-overlay");
		this.#mediaPreviewEl = wrapper.querySelector(".media-preview");
		this.#hashtagsEl = wrapper.querySelector(".hashtags");
		this.#postTypeEl = wrapper.querySelector(".post-type");
		this.#stepNumberEl = wrapper.querySelector(".step-number");

		// Set initial attribute state
		this.setAttribute("data-status", this.#status);

		// Edit button
		const editBtn = wrapper.querySelector(".edit-btn") as HTMLButtonElement;
		editBtn.addEventListener("click", (e) => {
			e.stopPropagation();
			this.#openEditor();
		});

		// Close button
		const closeBtn = wrapper.querySelector(".close-btn") as HTMLButtonElement;
		closeBtn.addEventListener("click", (e) => {
			e.stopPropagation();
			this.dispatchEvent(new CustomEvent("close"));
		});

		// Save button
		const saveBtn = wrapper.querySelector(".save-btn") as HTMLButtonElement;
		saveBtn.addEventListener("click", (e) => {
			e.stopPropagation();
			this.#saveEdit(wrapper);
		});

		// Cancel button
		const cancelBtn = wrapper.querySelector(
			".cancel-btn",
		) as HTMLButtonElement;
		cancelBtn.addEventListener("click", (e) => {
			e.stopPropagation();
			this.#closeEditor();
		});

		// Render media and hashtags
		this.#renderMedia();
		this.#renderHashtags();

		return root;
	}

	#openEditor() {
		if (!this.#editOverlay) return;
		this.#isEditing = true;
		this.#editOverlay.classList.add("active");

		const root = this.#editOverlay.closest("div") as HTMLElement;
		const platformSel = root.querySelector(
			".edit-platform",
		) as HTMLSelectElement;
		const postTypeSel = root.querySelector(
			".edit-post-type",
		) as HTMLSelectElement;
		const contentArea = root.querySelector(
			".edit-content",
		) as HTMLTextAreaElement;
		const mediaInput = root.querySelector(
			".edit-media-url",
		) as HTMLInputElement;
		const scheduledInput = root.querySelector(
			".edit-scheduled",
		) as HTMLInputElement;
		const hashtagsInput = root.querySelector(
			".edit-hashtags",
		) as HTMLInputElement;
		const statusSel = root.querySelector(
			".edit-status",
		) as HTMLSelectElement;

		if (platformSel) platformSel.value = this.#platform;
		if (postTypeSel) postTypeSel.value = this.#postType;
		if (contentArea) contentArea.value = this.#content;
		if (mediaInput) mediaInput.value = this.#mediaUrl;
		if (scheduledInput) scheduledInput.value = this.#scheduledAt;
		if (hashtagsInput) hashtagsInput.value = this.#hashtags.join(", ");
		if (statusSel) statusSel.value = this.#status;
	}

	#closeEditor() {
		if (!this.#editOverlay) return;
		this.#isEditing = false;
		this.#editOverlay.classList.remove("active");
	}

	#saveEdit(wrapper: HTMLElement) {
		const platformSel = wrapper.querySelector(
			".edit-platform",
		) as HTMLSelectElement;
		const postTypeSel = wrapper.querySelector(
			".edit-post-type",
		) as HTMLSelectElement;
		const contentArea = wrapper.querySelector(
			".edit-content",
		) as HTMLTextAreaElement;
		const mediaInput = wrapper.querySelector(
			".edit-media-url",
		) as HTMLInputElement;
		const scheduledInput = wrapper.querySelector(
			".edit-scheduled",
		) as HTMLInputElement;
		const hashtagsInput = wrapper.querySelector(
			".edit-hashtags",
		) as HTMLInputElement;
		const statusSel = wrapper.querySelector(
			".edit-status",
		) as HTMLSelectElement;

		if (platformSel)
			this.#platform = platformSel.value as SocialPlatform;
		if (postTypeSel) this.postType = postTypeSel.value as PostType;
		if (contentArea) this.content = contentArea.value;
		if (mediaInput) this.mediaUrl = mediaInput.value;
		if (scheduledInput) this.scheduledAt = scheduledInput.value;
		if (hashtagsInput)
			this.hashtags = hashtagsInput.value
				.split(",")
				.map((t) => t.trim())
				.filter(Boolean);
		if (statusSel) this.status = statusSel.value as PostStatus;

		// Update header color for new platform
		const header = wrapper.querySelector(".header") as HTMLElement;
		const config = PLATFORM_CONFIG[this.#platform];
		if (header && config) {
			header.style.background = config.color;
			const iconEl = header.querySelector(".platform-icon");
			const nameEl = header.querySelector(".platform-name");
			if (iconEl) iconEl.textContent = config.icon;
			if (nameEl) nameEl.textContent = config.label;
		}

		this.#closeEditor();
	}

	#renderMedia() {
		if (!this.#mediaPreviewEl) return;

		if (this.#mediaUrl) {
			this.#mediaPreviewEl.innerHTML = `<img src="${this.#escapeHtml(this.#mediaUrl)}" alt="Post media" onerror="this.parentElement.innerHTML='<div class=\\'media-placeholder\\'><span class=\\'icon\\'>⚠️</span><span>Failed to load</span></div>'" />`;
		} else {
			const mediaIcons: Record<string, string> = {
				image: "🖼",
				video: "🎬",
				carousel: "📸",
				reel: "🎬",
				short: "🎬",
				story: "📱",
			};
			const icon = mediaIcons[this.#postType] || "🖼";
			const label =
				this.#postType === "text" ? "No media" : `${this.#postType} media`;
			this.#mediaPreviewEl.innerHTML = `<div class="media-placeholder"><span class="icon">${icon}</span><span>${label}</span></div>`;
		}
	}

	#renderHashtags() {
		if (!this.#hashtagsEl) return;

		if (this.#hashtags.length === 0) {
			this.#hashtagsEl.innerHTML = "";
			return;
		}

		this.#hashtagsEl.innerHTML = this.#hashtags
			.map((tag) => {
				const t = tag.startsWith("#") ? tag : `#${tag}`;
				return `<span class="hashtag">${this.#escapeHtml(t)}</span>`;
			})
			.join("");
	}

	#formatSchedule(dateStr: string): string {
		if (!dateStr) return "Not scheduled";
		try {
			const date = new Date(dateStr);
			if (isNaN(date.getTime())) return dateStr;
			const opts: Intl.DateTimeFormatOptions = {
				month: "short",
				day: "numeric",
				hour: "2-digit",
				minute: "2-digit",
			};
			return date.toLocaleDateString("en-US", opts);
		} catch {
			return dateStr;
		}
	}

	#escapeHtml(text: string): string {
		const div = document.createElement("div");
		div.textContent = text;
		return div.innerHTML;
	}

	static override fromData(data: Record<string, any>): FolkSocialPost {
		const shape = FolkShape.fromData(data) as FolkSocialPost;
		if (data.platform) shape.platform = data.platform;
		if (data.postType) shape.postType = data.postType;
		if (data.content !== undefined) shape.content = data.content;
		if (data.mediaUrl !== undefined) shape.mediaUrl = data.mediaUrl;
		if (data.mediaType !== undefined) shape.mediaType = data.mediaType;
		if (data.scheduledAt !== undefined) shape.scheduledAt = data.scheduledAt;
		if (data.status) shape.status = data.status;
		if (Array.isArray(data.hashtags)) shape.hashtags = data.hashtags;
		if (typeof data.stepNumber === "number") shape.stepNumber = data.stepNumber;
		return shape;
	}

	override applyData(data: Record<string, any>): void {
		super.applyData(data);
		if (data.platform !== undefined && data.platform !== this.platform) this.platform = data.platform;
		if (data.postType !== undefined && data.postType !== this.postType) this.postType = data.postType;
		if (data.content !== undefined && data.content !== this.content) this.content = data.content;
		if (data.mediaUrl !== undefined && data.mediaUrl !== this.mediaUrl) this.mediaUrl = data.mediaUrl;
		if (data.mediaType !== undefined && data.mediaType !== this.mediaType) this.mediaType = data.mediaType;
		if (data.scheduledAt !== undefined && data.scheduledAt !== this.scheduledAt) this.scheduledAt = data.scheduledAt;
		if (data.status !== undefined && data.status !== this.status) this.status = data.status;
		if (Array.isArray(data.hashtags) && JSON.stringify(data.hashtags) !== JSON.stringify(this.hashtags)) this.hashtags = data.hashtags;
		if (typeof data.stepNumber === "number" && data.stepNumber !== this.stepNumber) this.stepNumber = data.stepNumber;
	}

	override toJSON() {
		return {
			...super.toJSON(),
			type: "folk-social-post",
			platform: this.#platform,
			postType: this.#postType,
			content: this.#content,
			mediaUrl: this.#mediaUrl,
			mediaType: this.#mediaType,
			scheduledAt: this.#scheduledAt,
			status: this.#status,
			hashtags: this.#hashtags,
			stepNumber: this.#stepNumber,
		};
	}
}
