// Create Post page — matches the dark reference

function PlatformPill({ id, selected, onClick, integration, issueCount }) {
  const p = Platforms[id];
  const stateColor = !integration?.connected ? "var(--text-3)" : issueCount ? "var(--warn)" : "var(--accent)";
  return (
    <button
      className="tb-chip"
      onClick={onClick}
      title={!integration?.connected ? `${p.name} is not connected` : issueCount ? `${p.name} has readiness issues` : `${p.name} is ready`}
      style={{
        background: selected ? "var(--card-2)" : "var(--card)",
        borderColor: selected && issueCount ? "rgba(245,158,11,0.45)" : selected ? "var(--border-2)" : "var(--border)",
        padding: "8px 12px 8px 8px",
        gap: 10,
      }}
    >
      <PlatformIcon id={id} size={22} />
      <span style={{ fontSize: 13 }}>{p.name}</span>
      <span style={{ width: 7, height: 7, borderRadius: 999, background: stateColor, marginLeft: 2 }} />
    </button>
  );
}

function MediaTile({ ph, bg, duration, active, src, type, name }) {
  return (
    <div
      style={{
        position: "relative",
        width: 92, height: 92,
        borderRadius: 12,
        overflow: "hidden",
        border: active ? "1.5px solid var(--accent)" : "1px solid var(--border)",
        cursor: "pointer",
        background: bg || "var(--elev)",
      }}
    >
      {src && type === "image"
        ? <img src={src} alt={name || ph} style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }} />
        : <div className="imgph" style={{ width: "100%", height: "100%", background: bg }}>
          {ph || name}
        </div>}
      {active && (
        <div style={{ position: "absolute", left: 6, bottom: 6, background: "rgba(0,0,0,0.55)", padding: 4, borderRadius: 6 }}>
          <Icon.Crop width="12" height="12" />
        </div>
      )}
      {duration && (
        <div style={{ position: "absolute", right: 6, bottom: 6, background: "rgba(0,0,0,0.65)", padding: "2px 6px", borderRadius: 5, fontSize: 11, fontWeight: 600 }}>
          {duration}
        </div>
      )}
    </div>
  );
}

function ContentTypeTab({ icon, label, active, onClick, disabled }) {
  const Ico = icon;
  return (
    <button
      onClick={onClick}
      disabled={disabled}
      style={{
        display: "flex", alignItems: "center", gap: 8,
        padding: "9px 16px",
        borderRadius: 10,
        background: active ? "transparent" : "transparent",
        border: active ? "1.5px solid var(--accent)" : "1px solid var(--border)",
        color: active ? "var(--accent-2)" : "var(--text-2)",
        fontSize: 13, fontWeight: 500,
        opacity: disabled ? 0.42 : 1,
        cursor: disabled ? "not-allowed" : "pointer",
      }}
    >
      <Ico width="15" height="15" />
      {label}
    </button>
  );
}

function createLifecycleLabel(status) {
  return ({
    draft: "draft",
    needs_approval: "approval request",
    changes_requested: "changes request",
    scheduled: "scheduled post",
    published: "published post",
    failed: "failed post",
    blocked: "blocked post",
    rejected: "rejected post"
  }[status] || "post");
}

const PlatformLimits = {
  instagram: 2200,
  facebook: 63206,
  x: 280,
  linkedin: 3000,
  tiktok: 2200,
  youtube: 5000,
  pinterest: 500
};

const MediaFitOptions = [
  { id: "original", label: "Original", ratio: "Default", w: 28, h: 28 },
  { id: "square", label: "Square", ratio: "1:1", w: 22, h: 22 },
  { id: "portrait", label: "Portrait", ratio: "4:5", w: 18, h: 22 },
  { id: "vertical", label: "Vertical", ratio: "9:16", w: 14, h: 24 }
];

const PlatformMediaDefaults = {
  instagram: { feed: "portrait", reel: "vertical", story: "vertical", short: "vertical" },
  facebook: { feed: "square", reel: "vertical", story: "vertical", short: "vertical" },
  x: { feed: "original", reel: "vertical", story: "vertical", short: "vertical" },
  linkedin: { feed: "square", reel: "vertical", story: "vertical", short: "vertical" },
  tiktok: { feed: "vertical", reel: "vertical", story: "vertical", short: "vertical" },
  youtube: { feed: "original", reel: "vertical", story: "vertical", short: "vertical" },
  pinterest: { feed: "portrait", reel: "vertical", story: "vertical", short: "vertical" }
};

function recommendedMediaFit(platform, contentType) {
  return PlatformMediaDefaults[platform]?.[contentType] || "original";
}

function composerCaptionTokens(text) {
  return String(text || "")
    .toLowerCase()
    .replace(/https?:\/\/\S+/g, " ")
    .replace(/[^\p{L}\p{N}#_]+/gu, " ")
    .split(/\s+/)
    .filter((token) => token.length > 2);
}

function composerCaptionSimilarity(a, b) {
  const aTokens = new Set(composerCaptionTokens(a));
  const bTokens = new Set(composerCaptionTokens(b));
  if (!aTokens.size || !bTokens.size) return 0;
  const intersection = [...aTokens].filter((token) => bTokens.has(token)).length;
  const union = new Set([...aTokens, ...bTokens]).size;
  return union ? intersection / union : 0;
}

/* --- Phone preview components --- */

function PhoneFrame({ children, device = "ios" }) {
  const isAndroid = device === "android";
  return (
    <div style={{
      width: 240, height: 480,
      borderRadius: isAndroid ? 28 : 36,
      background: "#0a0a0a",
      border: "1.5px solid #1a1a1a",
      padding: isAndroid ? 5 : 6,
      boxShadow: "0 30px 60px -20px rgba(0,0,0,0.6), inset 0 0 0 1px rgba(255,255,255,0.04)",
      position: "relative",
    }}>
      <div style={{ width: "100%", height: "100%", borderRadius: isAndroid ? 23 : 30, overflow: "hidden", background: "#fff", position: "relative" }}>
        {/* Notch */}
        <div style={{ position: "absolute", top: isAndroid ? 9 : 6, left: "50%", transform: "translateX(-50%)", width: isAndroid ? 18 : 80, height: isAndroid ? 18 : 22, borderRadius: 14, background: "#0a0a0a", zIndex: 10 }} />
        {children}
      </div>
    </div>
  );
}

function StatusBar({ dark }) {
  return (
    <div style={{
      display: "flex", justifyContent: "space-between", alignItems: "center",
      padding: "10px 18px 4px",
      fontSize: 11, fontWeight: 600,
      color: dark ? "white" : "#0a0a0a",
      position: "relative", zIndex: 5,
    }}>
      <span>9:41</span>
      <span style={{ display: "inline-flex", gap: 4, alignItems: "center" }}>
        <svg width="13" height="9" viewBox="0 0 13 9" fill="currentColor"><rect x="0" y="6" width="2" height="3" rx="0.5"/><rect x="3" y="4" width="2" height="5" rx="0.5"/><rect x="6" y="2" width="2" height="7" rx="0.5"/><rect x="9" y="0" width="2" height="9" rx="0.5"/></svg>
        <svg width="11" height="9" viewBox="0 0 11 9" fill="none" stroke="currentColor" strokeWidth="1"><path d="M1 4.5 A6 6 0 0 1 10 4.5 M2.5 6 A4 4 0 0 1 8.5 6 M4.5 7.5 A1 1 0 0 1 6.5 7.5"/></svg>
        <svg width="16" height="8" viewBox="0 0 16 8" fill="none"><rect x="0.5" y="0.5" width="13" height="7" rx="1.5" stroke="currentColor" opacity="0.5"/><rect x="2" y="2" width="9" height="4" rx="0.5" fill="currentColor"/><rect x="14" y="2.5" width="1.5" height="3" rx="0.5" fill="currentColor" opacity="0.5"/></svg>
      </span>
    </div>
  );
}

function PreviewMedia({ media, fit = "original", dark = false }) {
  const objectFit = fit === "original" ? "contain" : "cover";
  const padding = fit === "original" ? 12 : 0;
  const fallback = (
    <div className="imgph" style={{ width: "100%", height: "100%", background: media?.bg || "linear-gradient(135deg, #d8c2a0, #7e6442)" }}>
      <div style={{ textAlign: "center", color: dark ? "rgba(255,255,255,0.72)" : "rgba(255,255,255,0.82)" }}>
        <Icon.Image width="32" height="32" /><br />
        <span style={{ fontSize: 9 }}>{media?.name || media?.ph || "clearcast-media"}</span>
      </div>
    </div>
  );
  return (
    <div style={{ position: "absolute", inset: padding, overflow: "hidden", borderRadius: fit === "original" ? 10 : 0, background: media?.bg || "linear-gradient(135deg, #d8c2a0, #7e6442)" }}>
      {media?.src && media.type === "image"
        ? <img src={media.src} alt={media.name || media.ph || "Preview media"} style={{ width: "100%", height: "100%", objectFit, display: "block" }} />
        : fallback}
    </div>
  );
}

function fitAspect(fit) {
  return ({
    square: "1 / 1",
    portrait: "4 / 5",
    vertical: "9 / 16"
  }[fit] || "1 / 1");
}

function truncatePreview(text, max = 96) {
  const clean = String(text || "").replace(/\s+/g, " ").trim();
  return clean.length > max ? `${clean.slice(0, max - 1)}…` : clean;
}

function FeedPreview({ platform, caption, media, fit }) {
  const platformName = Platforms[platform]?.name || "Instagram";
  const aspect = fitAspect(fit);
  return (
    <div style={{ background: "white", color: "#0a0a0a", height: "100%", display: "flex", flexDirection: "column" }}>
      <StatusBar />
      {/* Post header */}
      <div style={{ padding: "8px 14px", display: "flex", alignItems: "center", gap: 8 }}>
        <div className="brand-mark" style={{ width: 28, height: 28, fontSize: 10 }}>CC</div>
        <div style={{ flex: 1, lineHeight: 1.15 }}>
          <div style={{ fontWeight: 700, fontSize: 12 }}>clearcast.co</div>
          <div style={{ fontSize: 10, color: "#666" }}>{platformName} preview</div>
        </div>
        <Icon.Dots width="16" height="16" />
      </div>
      {/* Image */}
      <div style={{ position: "relative", width: "100%", aspectRatio: aspect, maxHeight: 286, background: "#f0ede8", overflow: "hidden" }}>
        <PreviewMedia media={media} fit={fit} />
        <div style={{ position: "absolute", right: 8, bottom: 8, borderRadius: 999, padding: "3px 7px", fontSize: 9.5, fontWeight: 700, background: "rgba(0,0,0,0.58)", color: "white" }}>{fit}</div>
      </div>
      {/* Actions */}
      <div style={{ padding: "8px 14px", display: "flex", gap: 14, fontSize: 13 }}>
        <Icon.Heart width="20" height="20" />
        <Icon.Message width="20" height="20" />
        <Icon.Share width="20" height="20" />
        <div style={{ marginLeft: "auto" }}><Icon.Bookmark width="20" height="20" /></div>
      </div>
      <div style={{ padding: "0 14px 6px", fontSize: 10.5, display: "flex", alignItems: "center", gap: 4 }}>
        <div className="avatar sz-28" style={{ width: 14, height: 14, fontSize: 7, background: "#ddd" }} />
        <span>Liked by <b>jessica</b> and <b>1,234 others</b></span>
      </div>
      <div style={{ padding: "0 14px 4px", fontSize: 11, lineHeight: 1.4 }}>
        <b>clearcast.co</b> {truncatePreview(caption)}
      </div>
      <div style={{ padding: "0 14px 4px", fontSize: 10, color: "#666" }}>View all 28 comments</div>
      <div style={{ padding: "0 14px 10px", fontSize: 9.5, color: "#999", letterSpacing: 0.5 }}>2 HOURS AGO</div>
    </div>
  );
}

function StoryPreview({ platform, caption, media, fit }) {
  const platformName = Platforms[platform]?.name || "Instagram";
  return (
    <div style={{
      height: "100%",
      background: "linear-gradient(180deg, rgba(0,0,0,0.05), rgba(0,0,0,0.4)), linear-gradient(135deg, #d8c4a0, #8a6f4a)",
      color: "white",
      display: "flex", flexDirection: "column",
      position: "relative",
    }}>
      <PreviewMedia media={media} fit={fit === "original" ? "vertical" : fit} dark />
      <div style={{ position: "absolute", inset: 0, background: "linear-gradient(180deg, rgba(0,0,0,0.18), rgba(0,0,0,0.52))" }} />
      <div style={{ position: "relative", zIndex: 2, padding: "10px 14px 0", display: "flex", alignItems: "center", gap: 8 }}>
        <div className="brand-mark" style={{ width: 28, height: 28, fontSize: 10 }}>CC</div>
        <span style={{ fontSize: 12, fontWeight: 600 }}>clearcast.co</span>
        <span style={{ fontSize: 11, opacity: 0.7 }}>{platformName}</span>
        <Icon.X width="18" height="18" style={{ marginLeft: "auto" }} />
      </div>
      <div style={{ position: "relative", zIndex: 2, padding: "0 14px", margin: "auto 0", textAlign: "left" }}>
        <div style={{ fontFamily: "'Playfair Display', Georgia, serif", fontSize: 38, lineHeight: 1, fontWeight: 400 }}>New<br />Collection</div>
        <div style={{ fontSize: 12, marginTop: 12, opacity: 0.9, textAlign: "center" }}>{truncatePreview(caption, 46)}</div>
      </div>
      <div style={{ position: "relative", zIndex: 2, padding: "12px 14px", display: "flex", alignItems: "center", gap: 8 }}>
        <div style={{ flex: 1, padding: "8px 14px", border: "1.5px solid rgba(255,255,255,0.5)", borderRadius: 999, fontSize: 11 }}>Send message</div>
        <Icon.Heart width="20" height="20" />
        <Icon.Share width="20" height="20" />
      </div>
    </div>
  );
}

function CreatePostPage() {
  const hub = window.useClearCast();
  const [editPostId, setEditPostId] = React.useState(() => new URLSearchParams(window.location.search).get("edit") || sessionStorage.getItem("clearcast-edit-post-id") || sessionStorage.getItem("sharehub-edit-post-id") || "");
  const [platforms, setPlatforms] = React.useState({ facebook: false, instagram: false, x: false, linkedin: false, tiktok: false, youtube: false, pinterest: false });
  const [contentType, setContentType] = React.useState("feed");
  const [caption, setCaption] = React.useState("");
  const platformInitRef = React.useRef(false);
  const [activeVariantPlatform, setActiveVariantPlatform] = React.useState("instagram");
  const [variants, setVariants] = React.useState({});
  const [activeMedia, setActiveMedia] = React.useState(0);
  const [globalMediaOverridden, setGlobalMediaOverridden] = React.useState(false);
  const [previewMode, setPreviewMode] = React.useState("feed");
  const [previewDevice, setPreviewDevice] = React.useState("ios");
  const [uploadingMedia, setUploadingMedia] = React.useState(false);
  const [date, setDate] = React.useState(() => new Date().toISOString().slice(0, 10));
  const [time, setTime] = React.useState("09:30");
  const [bestTime, setBestTime] = React.useState("09:15");
  const [bestTimeRecommendations, setBestTimeRecommendations] = React.useState([]);
  const [activeHashtagGroup, setActiveHashtagGroup] = React.useState("");
  const [suggestedHashtags, setSuggestedHashtags] = React.useState([]);
  const [showExtraTones, setShowExtraTones] = React.useState(false);
  const [submitState, setSubmitState] = React.useState("");
  const [aiMediaPrompt, setAiMediaPrompt] = React.useState("");
  const [aiMediaBusy, setAiMediaBusy] = React.useState("");
  const [approvalOverride, setApprovalOverride] = React.useState(null);
  const [variantBusy, setVariantBusy] = React.useState(false);
  const [firstComment, setFirstComment] = React.useState("");
  const editPost = (hub.data.posts || []).find((post) => post.id === editPostId);
  const isEditing = Boolean(editPost);
  const editModeLabel = !isEditing ? "New post" : editPost.status === "draft" ? "Editing draft" : `Editing ${createLifecycleLabel(editPost.status)}`;
  const hashtagGroups = hub.data.hashtagGroups || [];
  const selectedHashtagGroup = hashtagGroups.find((group) => group.id === activeHashtagGroup) || hashtagGroups[0] || null;

  React.useEffect(() => {
    const id = new URLSearchParams(window.location.search).get("edit") || sessionStorage.getItem("clearcast-edit-post-id") || sessionStorage.getItem("sharehub-edit-post-id") || "";
    setEditPostId(id);
  }, []);

  React.useEffect(() => {
    if (!editPost) return;
    const current = new Set(editPost.platforms || []);
    setPlatforms(Object.keys(Platforms).slice(0, 7).reduce((acc, id) => ({ ...acc, [id]: current.has(id) }), {}));
    setContentType(editPost.contentType || "feed");
    setCaption(editPost.caption || "");
    setVariants(editPost.variants || {});
    setActiveVariantPlatform((editPost.platforms || [])[0] || "instagram");
    setDate(editPost.date || "2026-05-18");
    setTime(editPost.time || "09:30");
    setBestTime(editPost.bestTime || "09:15");
    setActiveMedia(0);
    setGlobalMediaOverridden(false);
    setFirstComment(editPost.firstComment || "");
  }, [editPost?.id]);

  React.useEffect(() => {
    if (!hashtagGroups.length || activeHashtagGroup) return;
    setActiveHashtagGroup(hashtagGroups[0].id);
  }, [hashtagGroups.length, activeHashtagGroup]);

  // For a new post, default the selected channels to the ones actually connected
  // (run once when data first arrives). New/empty businesses start with none selected.
  React.useEffect(() => {
    if (isEditing || platformInitRef.current) return;
    const integrations = hub.data.integrations || [];
    if (!integrations.length) return;
    platformInitRef.current = true;
    const connected = new Set(integrations.filter((integration) => integration.connected).map((integration) => integration.id));
    if (!connected.size) return;
    setPlatforms(Object.keys(Platforms).slice(0, 7).reduce((acc, id) => ({ ...acc, [id]: connected.has(id) }), {}));
    const firstConnected = Object.keys(Platforms).slice(0, 7).find((id) => connected.has(id));
    if (firstConnected) setActiveVariantPlatform(firstConnected);
  }, [hub.data.integrations, isEditing]);

  const clearEditMode = () => {
    sessionStorage.removeItem("clearcast-edit-post-id");
    sessionStorage.removeItem("sharehub-edit-post-id");
    setEditPostId("");
    setPlatforms({ facebook: true, instagram: true, x: false, linkedin: true, tiktok: true, youtube: true, pinterest: true });
    setContentType("feed");
    setCaption("Summer launch is almost here. Meet the new collection designed\nfor sunny commutes, weekend markets, and late dinners outside. ☀️👜");
    setVariants({});
    setActiveVariantPlatform("instagram");
    setDate("2026-05-18");
    setTime("09:30");
    setBestTime("09:15");
    setActiveMedia(0);
    setGlobalMediaOverridden(false);
  };

  const selectAllPlatforms = () => {
    setPlatforms(Object.keys(Platforms).slice(0, 7).reduce((acc, id) => ({ ...acc, [id]: true }), {}));
    hub.toast("All supported channels selected");
  };

  const goBackToCalendar = () => {
    sessionStorage.removeItem("clearcast-edit-post-id");
    sessionStorage.removeItem("sharehub-edit-post-id");
    window.location.hash = "calendar";
  };

  const toggle = (id) => setPlatforms({ ...platforms, [id]: !platforms[id] });
  const selectedPlatforms = Object.keys(platforms).filter((id) => platforms[id]);
  React.useEffect(() => {
    if (selectedPlatforms.length && !selectedPlatforms.includes(activeVariantPlatform)) {
      setActiveVariantPlatform(selectedPlatforms[0]);
    }
  }, [selectedPlatforms.join("|"), activeVariantPlatform]);
  const integrationMap = Object.fromEntries((hub.data.integrations || []).map((item) => [item.id, item]));
  const workspaceRules = hub.data.workspace?.publishingRules || {};
  const anyChannelConnected = (hub.data.integrations || []).some((integration) => integration.connected);
  const approvalRequired = approvalOverride != null ? approvalOverride : (workspaceRules.approvalRequired !== false);
  const queueStatus = approvalRequired ? "needs_approval" : "scheduled";
  const approvalRouteLabel = approvalRequired ? "Approval required" : "Direct scheduling";
  const approvalRouteDescription = approvalRequired ? "Posts route to Approvals before publishing." : "Ready posts go straight onto the scheduled calendar.";
  const hashtagCount = (caption.match(/#[\p{L}\p{N}_]+/gu) || []).length;
  const quietHourIssue = (() => {
    if (!workspaceRules.quietStart || !workspaceRules.quietEnd || !time) return "";
    const start = String(workspaceRules.quietStart).slice(0, 5);
    const end = String(workspaceRules.quietEnd).slice(0, 5);
    const current = String(time).slice(0, 5);
    const inQuietHours = start < end ? current >= start && current < end : current >= start || current < end;
    return inQuietHours ? `Scheduled time ${current} falls inside workspace quiet hours (${start}-${end})` : "";
  })();
  const duplicateMatch = workspaceRules.duplicateDetection && caption.trim()
    ? (hub.data.posts || [])
      .filter((post) => post.id !== editPost?.id && post.caption)
      .map((post) => ({ post, score: composerCaptionSimilarity(caption, post.caption) }))
      .filter((item) => item.score >= 0.9)
      .sort((a, b) => b.score - a.score)[0]
    : null;
  const ruleIssues = [
    Number(workspaceRules.hashtagLimit || 0) && hashtagCount > Number(workspaceRules.hashtagLimit) ? `Hashtag limit exceeded: ${hashtagCount}/${workspaceRules.hashtagLimit}` : "",
    workspaceRules.profanityFilter && /\b(damn|hell)\b/i.test(caption) ? "Caption contains restricted language" : "",
    duplicateMatch ? `Possible duplicate of ${duplicateMatch.post.id} (${Math.round(duplicateMatch.score * 100)}% match)` : "",
    quietHourIssue
  ].filter(Boolean);
  const platformIssues = (id, type = contentType) => {
    const integration = integrationMap[id];
    const name = Platforms[id]?.name || id;
    const issues = [];
    if (!integration || !integration.connected) issues.push(`${name} is not connected`);
    if (integration?.status === "reauth") issues.push(`${name} needs re-authorization`);
    if (integration?.status === "limited") issues.push(`${name} has limited permissions`);
    if (integration && !(integration.supportedTypes || []).includes(type)) issues.push(`${name} does not support ${type} posts`);
    if (integration?.issues?.length) issues.push(...integration.issues.map((issue) => `${name}: ${issue}`));
    return issues;
  };
  const variantIssues = selectedPlatforms.flatMap((id) => {
    const current = variants[id] || {};
    const variantCaption = current.useGlobalCaption === false ? current.caption || "" : caption;
    const limit = PlatformLimits[id] || 2200;
    return variantCaption.length > limit ? [`${Platforms[id]?.name || id} caption is over ${limit.toLocaleString()} characters`] : [];
  });
  const readinessIssues = [...selectedPlatforms.flatMap((id) => platformIssues(id)), ...variantIssues, ...ruleIssues];
  const readyPlatforms = selectedPlatforms.filter((id) => platformIssues(id).length === 0);
  const availableTypes = ["feed", "reel", "story", "short"].map((type) => ({
    id: type,
    supported: selectedPlatforms.length > 0 && selectedPlatforms.some((id) => platformIssues(id, type).length === 0)
  }));
  const canQueue = selectedPlatforms.length > 0 && readinessIssues.length === 0;
  const activeVariant = variants[activeVariantPlatform] || {};
  const activeUsesGlobal = activeVariant.useGlobalCaption !== false;
  const activeVariantCaption = activeUsesGlobal ? caption : activeVariant.caption || "";
  const activeLimit = PlatformLimits[activeVariantPlatform] || 2200;
  const variantCount = selectedPlatforms.filter((id) => variants[id]?.useGlobalCaption === false && variants[id]?.caption?.trim()).length;
  const mediaVariantCount = selectedPlatforms.filter((id) => (variants[id]?.useGlobalMedia === false && (variants[id]?.media?.length || variants[id]?.mediaFit)) || Object.keys(variants[id]?.mediaEdits || {}).length).length;
  const setVariant = (platform, patch) => {
    setVariants((current) => ({
      ...current,
      [platform]: {
        platform,
        useGlobalCaption: current[platform]?.useGlobalCaption !== false,
        useGlobalMedia: current[platform]?.useGlobalMedia !== false,
        caption: current[platform]?.caption || "",
        contentType,
        media: current[platform]?.media || [],
        mediaFit: current[platform]?.mediaFit || recommendedMediaFit(platform, contentType),
        mediaEdits: current[platform]?.mediaEdits || {},
        notes: current[platform]?.notes || "",
        ...patch
      }
    }));
  };
  const currentMediaId = () => {
    if (isEditing && !globalMediaOverridden && editPost.media?.length) return editPost.media[0];
    return mediaThumbs[activeMedia]?.id || mediaThumbs[activeMedia]?.url || mediaThumbs[activeMedia]?.ph || "clearcast-media";
  };
  const buildVariantsPayload = () => selectedPlatforms.reduce((acc, id) => {
    const current = variants[id] || {};
    const useGlobalCaption = current.useGlobalCaption !== false;
    const useGlobalMedia = current.useGlobalMedia !== false;
    acc[id] = {
      platform: id,
      useGlobalCaption,
      useGlobalMedia,
      caption: useGlobalCaption ? caption : current.caption || caption,
      contentType,
      media: useGlobalMedia ? [currentMediaId()] : current.media?.length ? current.media : [currentMediaId()],
      mediaFit: current.mediaFit || recommendedMediaFit(id, contentType),
      mediaEdits: current.mediaEdits || {},
      notes: current.notes || ""
    };
    return acc;
  }, {});
  const selectReadyPlatforms = () => {
    const next = Object.fromEntries(Object.keys(platforms).map((id) => [id, platformIssues(id).length === 0]));
    setPlatforms(next);
  };

  const applyCaption = async (tone) => {
    try {
      console.log(`ClearCast: AI caption ${tone}`);
      const next = await hub.actions.aiCaption(caption, tone, hub.data.workspace?.aiSettings?.voice || hub.data.workspace?.brandVoice || "");
      setCaption(next);
    } catch (error) {
      console.error(error);
      hub.toast("AI caption failed");
    }
  };

  const appendHashtag = (tag) => {
    const normalized = String(tag || "").trim();
    if (!normalized || caption.toLowerCase().includes(normalized.toLowerCase())) return;
    setCaption((current) => `${current.trim()} ${normalized}`.trim());
  };

  const refreshHashtagSuggestions = async () => {
    try {
      const suggestions = await hub.actions.hashtagSuggestions({ caption, platforms: selectedPlatforms, contentType });
      setSuggestedHashtags(suggestions);
    } catch (error) {
      console.error(error);
      hub.toast("Could not suggest hashtags");
    }
  };

  const refreshBestTimes = async () => {
    try {
      const recommendations = await hub.actions.bestTimes({ platforms: selectedPlatforms, contentType, timezone: hub.data.workspace?.timezone });
      setBestTimeRecommendations(recommendations);
      if (recommendations[0]?.time) setBestTime(recommendations[0].time);
    } catch (error) {
      console.error(error);
      hub.toast("Could not refresh best times");
    }
  };

  const applyBestTime = (recommendation) => {
    if (!recommendation?.time) return;
    setBestTime(recommendation.time);
    setTime(recommendation.time);
  };

  const applyMediaEdit = (type) => {
    const patchByType = {
      crop: { crop: activeMediaFit === "vertical" ? "9:16 center" : activeMediaFit === "portrait" ? "4:5 center" : activeMediaFit === "square" ? "1:1 center" : "smart crop" },
      resize: { resize: `${activeMediaFit === "vertical" ? "1080x1920" : activeMediaFit === "portrait" ? "1080x1350" : activeMediaFit === "square" ? "1080x1080" : "native"} ${Platforms[activeVariantPlatform]?.name || activeVariantPlatform}` },
      trim: { trim: contentType === "short" || contentType === "reel" ? "0:00-0:30" : "not required" }
    }[type];
    setVariants((current) => {
      const existing = current[activeVariantPlatform] || {};
      const notes = new Set(String(existing.notes || "").split(" · ").filter(Boolean));
      notes.add(`${type} applied`);
      return {
        ...current,
        [activeVariantPlatform]: {
          platform: activeVariantPlatform,
          useGlobalCaption: existing.useGlobalCaption !== false,
          useGlobalMedia: existing.useGlobalMedia !== false,
          caption: existing.caption || "",
          contentType,
          media: existing.media || [],
          mediaFit: existing.mediaFit || recommendedMediaFit(activeVariantPlatform, contentType),
          mediaEdits: { ...(existing.mediaEdits || {}), ...patchByType },
          notes: [...notes].join(" · ")
        }
      };
    });
    hub.toast(`${type[0].toUpperCase()}${type.slice(1)} applied to ${Platforms[activeVariantPlatform]?.name || activeVariantPlatform}`);
  };

  const saveCurrentHashtag = async () => {
    const tag = suggestedHashtags.find((item) => !selectedHashtagGroup?.tags?.includes(item)) || "#clearcast";
    if (!selectedHashtagGroup) {
      const group = await hub.actions.createHashtagGroup({ name: "Saved hashtags", tags: [tag] });
      setActiveHashtagGroup(group.id);
      return;
    }
    const nextTags = [...new Set([...(selectedHashtagGroup.tags || []), tag])];
    await hub.actions.updateHashtagGroup(selectedHashtagGroup.id, { ...selectedHashtagGroup, tags: nextTags, topTag: selectedHashtagGroup.topTag || tag });
  };

  const addToQueue = async () => {
    if (submitState) return;
    if (!canQueue) {
      hub.toast(readinessIssues[0] || "Choose at least one ready channel");
      return;
    }
    setSubmitState("queue");
    try {
      console.log("ClearCast: add to queue");
      const payload = {
        caption,
        platforms: selectedPlatforms,
        date,
        time,
        timezone: hub.data.workspace.timezone,
        bestTime,
        contentType,
        media: [currentMediaId()],
        variants: buildVariantsPayload(),
        firstComment,
        status: queueStatus,
        requireApproval: approvalRequired
      };
      if (isEditing) {
        await hub.actions.updatePost(editPost.id, payload);
        goBackToCalendar();
      } else {
        await hub.actions.createPost(payload);
      }
    } catch (error) {
      console.error(error);
      hub.toast("Could not add post to queue");
    } finally {
      setSubmitState("");
    }
  };

  const saveDraft = async () => {
    if (submitState) return;
    setSubmitState("draft");
    try {
      const payload = {
        caption,
        platforms: selectedPlatforms.length ? selectedPlatforms : ["instagram"],
        date,
        time,
        timezone: hub.data.workspace.timezone,
        bestTime,
        contentType,
        media: [currentMediaId()],
        variants: buildVariantsPayload(),
        firstComment,
        status: "draft",
        saveAsDraft: true,
        requireApproval: approvalRequired
      };
      if (isEditing) {
        await hub.actions.updatePost(editPost.id, payload);
        goBackToCalendar();
      } else {
        await hub.actions.createPost(payload);
      }
    } catch (error) {
      console.error(error);
      hub.toast("Could not save draft");
    } finally {
      setSubmitState("");
    }
  };

  const duplicateFromComposer = async () => {
    if (!isEditing) return;
    try {
      const post = await hub.actions.duplicatePost(editPost.id);
      sessionStorage.setItem("clearcast-edit-post-id", post.id);
      setEditPostId(post.id);
    } catch (error) {
      console.error(error);
      hub.toast("Could not duplicate post");
    }
  };

  const mediaThumbs = (hub.data.media || []).slice(0, 8).map((asset) => ({
    id: asset.id,
    src: asset.url,
    type: asset.type,
    ph: asset.name,
    name: asset.name,
    duration: asset.type === "video" ? "video" : null
  }));

  const uploadComposerMedia = async (event) => {
    const file = event.target.files?.[0];
    if (!file) return;
    try {
      setUploadingMedia(true);
      await hub.actions.uploadMedia(file, "summer");
      setActiveMedia(0);
    } catch (error) {
      console.error(error);
      hub.toast("Media upload failed");
    } finally {
      setUploadingMedia(false);
      event.target.value = "";
    }
  };

  const tailorPerPlatform = async () => {
    if (!selectedPlatforms.length) { hub.toast("Select at least one channel first"); return; }
    if (!caption.trim()) { hub.toast("Write a caption to tailor first"); return; }
    setVariantBusy(true);
    try {
      const out = await hub.actions.generateVariants({ caption, platforms: selectedPlatforms, voice: hub.data.workspace?.brandVoice || "" });
      Object.entries(out).forEach(([platform, text]) => setVariant(platform, { useGlobalCaption: false, caption: text }));
    } catch (error) {
      console.error(error);
    } finally {
      setVariantBusy(false);
    }
  };

  const addStockPhoto = async () => {
    const query = aiMediaPrompt.trim() || caption.replace(/[#@].*/g, "").split(/\s+/).slice(0, 3).join(" ").trim() || "lifestyle";
    try {
      setAiMediaBusy("stock");
      await hub.actions.addStock({ query });
      setActiveMedia(0);
      setGlobalMediaOverridden(true);
    } catch (error) { console.error(error); } finally { setAiMediaBusy(""); }
  };

  const addGif = async () => {
    const q = window.prompt("Search GIPHY for a GIF:", aiMediaPrompt.trim() || "celebrate");
    if (!q) return;
    try {
      setAiMediaBusy("gif");
      const res = await hub.actions.searchGiphy(q);
      if (!res.gifs || !res.gifs.length) { hub.toast(res.note || "No GIFs found"); return; }
      await hub.actions.addMediaLink({ url: res.gifs[0].url, name: q, type: "image", source: "giphy" });
      setActiveMedia(0);
      setGlobalMediaOverridden(true);
    } catch (error) { console.error(error); } finally { setAiMediaBusy(""); }
  };

  const generateAiMedia = async (kind) => {
    const prompt = aiMediaPrompt.trim() || caption.replace(/\s+/g, " ").trim().slice(0, 200);
    if (!prompt) { hub.toast("Add a prompt or caption first"); return; }
    const aspect = contentType === "feed" ? "square" : "portrait";
    try {
      setAiMediaBusy(kind);
      if (kind === "video") {
        await hub.actions.generateVideo({ prompt, aspect });
      } else {
        await hub.actions.generateImage({ prompt, aspect });
      }
      setActiveMedia(0);
      setGlobalMediaOverridden(true);
      setAiMediaPrompt("");
    } catch (error) {
      console.error(error);
      hub.toast("AI generation failed");
    } finally {
      setAiMediaBusy("");
    }
  };

  const activeMediaVariant = variants[activeVariantPlatform] || {};
  const activeUsesGlobalMedia = activeMediaVariant.useGlobalMedia !== false;
  const activeMediaFit = activeMediaVariant.mediaFit || recommendedMediaFit(activeVariantPlatform, contentType);
  const activeRecommendedFit = recommendedMediaFit(activeVariantPlatform, contentType);
  const activePlatformMedia = activeUsesGlobalMedia
    ? currentMediaId()
    : activeMediaVariant.media?.[0] || currentMediaId();
  const selectedMediaName = (id) => mediaThumbs.find((item) => (item.id || item.url || item.ph) === id)?.name || mediaThumbs.find((item) => (item.id || item.url || item.ph) === id)?.ph || id;
  const previewMedia = mediaThumbs.find((item) => (item.id || item.url || item.ph) === activePlatformMedia) || { ph: activePlatformMedia, name: activePlatformMedia };
  const previewCaption = activeUsesGlobal ? caption : activeVariant.caption || caption;
  const previewFit = previewMode === "feed" ? activeMediaFit : activeMediaFit === "original" ? "vertical" : activeMediaFit;

  return (
    <div className="page mobile-create-page">
      <div className="card" style={{ padding: "14px 18px", marginBottom: 18, display: "flex", alignItems: "center", justifyContent: "space-between", gap: 14 }}>
        <div style={{ minWidth: 0 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <span className={`pill ${isEditing && editPost.status !== "draft" ? "warn" : ""}`}>{editModeLabel}</span>
            {isEditing && <span className="muted" style={{ fontSize: 12 }}>{editPost.id}</span>}
          </div>
          <div style={{ marginTop: 4, fontSize: 13, color: "var(--text-2)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
            {isEditing ? "Changes here update the existing post and return you to Calendar after saving." : approvalRequired ? "Create a new post, save it as a draft, or submit it into the approval queue." : "Create a new post, save it as a draft, or schedule it directly from the composer."}
          </div>
        </div>
        <div style={{ display: "flex", gap: 8, flexShrink: 0 }}>
          {isEditing && <button className="btn" onClick={duplicateFromComposer}>Duplicate</button>}
          {isEditing && <button className="btn" onClick={goBackToCalendar}>Back to Calendar</button>}
          {isEditing && <button className="btn btn-primary" onClick={clearEditMode}>New Post</button>}
        </div>
      </div>
      <div className="composer-split" style={{ display: "grid", gridTemplateColumns: "minmax(0, 1fr) 400px", gap: 24, alignItems: "start" }}>
        {/* LEFT — composer */}
        <div style={{ display: "flex", flexDirection: "column", gap: 20 }}>
          {/* All platforms */}
          <div className="card" style={{ padding: 20 }}>
            <div style={{ fontSize: 13.5, color: "var(--text-2)", marginBottom: 12, fontWeight: 500 }}>All Platforms</div>
            {!anyChannelConnected && (
              <div style={{ marginBottom: 14, padding: 16, borderRadius: 12, background: "var(--accent-softer)", border: "1px solid rgba(20,184,138,0.25)" }}>
                <div style={{ fontWeight: 650, fontSize: 14, marginBottom: 4 }}>Connect a channel to get started</div>
                <div className="muted" style={{ fontSize: 12.5, marginBottom: 12 }}>Link a social account and your posts will publish straight from here. You can still draft a post in the meantime.</div>
                <button className="btn btn-primary btn-sm" onClick={() => { window.location.hash = "integrations"; }}>
                  <Icon.Plug width="14" height="14" /> Connect a channel
                </button>
              </div>
            )}
            <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
              {Object.keys(Platforms).slice(0, 7).map(id => (
                <PlatformPill key={id} id={id} selected={platforms[id]} integration={integrationMap[id]} issueCount={platformIssues(id).length} onClick={() => toggle(id)} />
              ))}
              <button className="tb-chip" onClick={selectAllPlatforms} title="Select all supported channels" style={{ width: 38, padding: 0, justifyContent: "center" }}>
                <Icon.Plus width="16" height="16" />
              </button>
            </div>
            <div style={{ marginTop: 14, display: "grid", gridTemplateColumns: "repeat(3, minmax(0, 1fr))", gap: 10 }}>
              <div style={{ padding: 10, borderRadius: 10, background: "var(--bg-2)", border: "1px solid var(--border)" }}>
                <div className="muted" style={{ fontSize: 11 }}>Selected</div>
                <div style={{ fontSize: 18, fontWeight: 650 }}>{selectedPlatforms.length}</div>
              </div>
              <div style={{ padding: 10, borderRadius: 10, background: "var(--bg-2)", border: "1px solid var(--border)" }}>
                <div className="muted" style={{ fontSize: 11 }}>Ready</div>
                <div style={{ fontSize: 18, fontWeight: 650, color: readyPlatforms.length ? "var(--accent)" : "var(--text)" }}>{readyPlatforms.length}</div>
              </div>
              <div style={{ padding: 10, borderRadius: 10, background: "var(--bg-2)", border: "1px solid var(--border)" }}>
                <div className="muted" style={{ fontSize: 11 }}>Issues</div>
                <div style={{ fontSize: 18, fontWeight: 650, color: readinessIssues.length ? "var(--warn)" : "var(--text)" }}>{readinessIssues.length}</div>
              </div>
            </div>
            {readinessIssues.length > 0 && (
              <div style={{ marginTop: 12, padding: 12, borderRadius: 12, background: "rgba(245,158,11,0.08)", border: "1px solid rgba(245,158,11,0.25)" }}>
                <div style={{ display: "flex", alignItems: "center", gap: 8, color: "var(--warn)", fontSize: 13, fontWeight: 650 }}>
                  <Icon.Bell width="14" height="14" /> Publishing readiness needs attention
                </div>
                <div style={{ marginTop: 8, display: "grid", gap: 5 }}>
                  {[...new Set(readinessIssues)].slice(0, 4).map((issue) => <div key={issue} className="muted" style={{ fontSize: 12 }}>{issue}</div>)}
                  {readinessIssues.length > 4 && <div className="muted" style={{ fontSize: 12 }}>+{readinessIssues.length - 4} more checks</div>}
                </div>
                <div style={{ display: "flex", gap: 8, marginTop: 10 }}>
                  <button className="btn btn-sm" onClick={selectReadyPlatforms}>Use ready channels</button>
                  <button className="btn btn-sm" onClick={() => { window.location.hash = "integrations"; }}>Open integrations</button>
                </div>
              </div>
            )}
            {(hub.data.connectionHealth || []).some((c) => c.level !== "ok") && (
              <div style={{ marginTop: 12, padding: 12, borderRadius: 12, background: "var(--bg-2)", border: "1px solid var(--border)" }}>
                <div style={{ fontSize: 12.5, fontWeight: 650, marginBottom: 8, color: "var(--text-2)" }}>Channel health · we'll warn you before a post fails</div>
                <div style={{ display: "grid", gap: 6 }}>
                  {(hub.data.connectionHealth || []).filter((c) => c.level !== "ok").map((c) => (
                    <div key={c.id} style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 12 }}>
                      <span className="ai-mode-dot" style={{ background: c.level === "critical" ? "var(--danger)" : "var(--warn)" }} />
                      <b>{Platforms[c.id]?.name || c.name}</b>
                      <span className="muted">{c.reasons[0]}</span>
                      {c.reconnect && <button className="btn btn-sm" style={{ marginLeft: "auto", padding: "2px 8px" }} onClick={() => { window.location.hash = "integrations"; }}>Reconnect</button>}
                    </div>
                  ))}
                </div>
              </div>
            )}
          </div>

          {/* Caption */}
          <div className="card" style={{ padding: 20 }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 10 }}>
              <div style={{ fontSize: 13.5, color: "var(--text-2)", fontWeight: 500 }}>Caption</div>
              <div style={{ display: "flex", gap: 14, alignItems: "center" }}>
                <button onClick={tailorPerPlatform} disabled={variantBusy} style={{ display: "inline-flex", alignItems: "center", gap: 6, color: "var(--accent-2)", fontSize: 13, fontWeight: 500 }} title="Generate a platform-native version for each selected channel">
                  <Icon.Sparkles width="14" height="14" /> {variantBusy ? "Tailoring…" : "Tailor per platform"}
                </button>
                <button onClick={() => applyCaption("friendly")} style={{ display: "inline-flex", alignItems: "center", gap: 6, color: "var(--accent-2)", fontSize: 13, fontWeight: 500 }}>
                  <Icon.Sparkles width="14" height="14" /> AI Caption
                </button>
              </div>
            </div>
            <div style={{ background: "var(--bg-2)", border: "1px solid var(--border)", borderRadius: 12, padding: 14 }}>
              <textarea
                className="textarea"
                value={caption}
                onChange={(e) => setCaption(e.target.value)}
                placeholder="Write your post here… or tap AI Caption to draft one for you."
                style={{ background: "transparent", border: "none", padding: 0, minHeight: 64, resize: "none", lineHeight: 1.6 }}
              />
              <div style={{ display: "flex", alignItems: "center", marginTop: 6 }}>
                <div style={{ marginLeft: "auto", fontSize: 12, color: "var(--text-3)" }}>{caption.length} / 2,200</div>
              </div>
            </div>
            <div style={{ display: "flex", gap: 8, marginTop: 12, flexWrap: "wrap" }}>
              {["Shorter", "Longer", "Friendly", "Professional", "Witty"].map(t => (
                <button key={t} onClick={() => applyCaption(t.toLowerCase())} className="tb-chip" style={{ padding: "7px 14px", fontSize: 12.5 }}>{t}</button>
              ))}
              <button className={`tb-chip ${showExtraTones ? "active" : ""}`} onClick={() => setShowExtraTones((value) => !value)} title="Show more tone options" style={{ padding: "7px 12px" }}><Icon.Dots width="14" height="14" /></button>
              {showExtraTones && ["Punchy", "Luxury", "Casual", "Direct"].map(t => (
                <button key={t} onClick={() => applyCaption(t.toLowerCase())} className="tb-chip" style={{ padding: "7px 14px", fontSize: 12.5 }}>{t}</button>
              ))}
            </div>
          </div>

          {/* Platform variants */}
          <div className="card" style={{ padding: 20 }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 12 }}>
              <div>
                <div style={{ fontSize: 13.5, color: "var(--text-2)", fontWeight: 500 }}>Platform Variants</div>
                <div className="muted" style={{ fontSize: 12, marginTop: 3 }}>{variantCount} customized · {selectedPlatforms.length || 0} selected channels</div>
              </div>
              <span className="pill info">Per-platform captions</span>
            </div>
            {selectedPlatforms.length ? (
              <>
                <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginBottom: 14 }}>
                  {selectedPlatforms.map((id) => {
                    const custom = variants[id]?.useGlobalCaption === false && variants[id]?.caption?.trim();
                    const overLimit = ((variants[id]?.useGlobalCaption === false ? variants[id]?.caption || "" : caption).length > (PlatformLimits[id] || 2200));
                    return (
                      <button key={id} className={`tb-chip ${activeVariantPlatform === id ? "active" : ""}`} onClick={() => setActiveVariantPlatform(id)} style={{ borderColor: activeVariantPlatform === id ? "var(--accent)" : overLimit ? "rgba(239,68,68,0.35)" : "var(--border)" }}>
                        <PlatformIcon id={id} size={18} />
                        <span>{Platforms[id]?.name || id}</span>
                        {custom && <span className="pill green" style={{ padding: "1px 6px", fontSize: 10 }}>Custom</span>}
                      </button>
                    );
                  })}
                </div>
                <div style={{ display: "grid", gridTemplateColumns: "minmax(0, 1fr) 180px", gap: 14, alignItems: "start" }}>
                  <div>
                    <label style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 12.5, color: "var(--text-2)", marginBottom: 10 }}>
                      <input
                        type="checkbox"
                        checked={activeUsesGlobal}
                        onChange={(event) => setVariant(activeVariantPlatform, { useGlobalCaption: event.target.checked })}
                        style={{ accentColor: "var(--accent)" }}
                      />
                      Use global caption for {Platforms[activeVariantPlatform]?.name || activeVariantPlatform}
                    </label>
                    <textarea
                      className="textarea"
                      disabled={activeUsesGlobal}
                      value={activeUsesGlobal ? caption : activeVariant.caption || ""}
                      onChange={(event) => setVariant(activeVariantPlatform, { useGlobalCaption: false, caption: event.target.value })}
                      placeholder={`Custom ${Platforms[activeVariantPlatform]?.name || activeVariantPlatform} caption`}
                      style={{ minHeight: 96, opacity: activeUsesGlobal ? 0.55 : 1 }}
                    />
                    <div style={{ display: "flex", justifyContent: "space-between", marginTop: 8, fontSize: 12 }}>
                      <span className="muted">{activeUsesGlobal ? "Using the global caption above" : "This platform will use its custom caption"}</span>
                      <span style={{ color: activeVariantCaption.length > activeLimit ? "var(--danger)" : "var(--text-3)" }}>
                        {activeVariantCaption.length.toLocaleString()} / {activeLimit.toLocaleString()}
                      </span>
                    </div>
                  </div>
                  <div className="card" style={{ background: "var(--bg-2)", padding: 12 }}>
                    <div className="field-label">Variant readiness</div>
                    <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                      <div style={{ display: "flex", justifyContent: "space-between", fontSize: 12 }}><span className="muted">Caption source</span><b>{activeUsesGlobal ? "Global" : "Custom"}</b></div>
                      <div style={{ display: "flex", justifyContent: "space-between", fontSize: 12 }}><span className="muted">Limit</span><b>{activeLimit.toLocaleString()}</b></div>
                      <div style={{ display: "flex", justifyContent: "space-between", fontSize: 12 }}><span className="muted">Status</span><b style={{ color: activeVariantCaption.length > activeLimit ? "var(--danger)" : "var(--accent)" }}>{activeVariantCaption.length > activeLimit ? "Over limit" : "Ready"}</b></div>
                    </div>
                  </div>
                </div>
              </>
            ) : (
              <div className="empty-note">Select at least one platform to customize variants.</div>
            )}
          </div>

          <div className="card" style={{ padding: 20 }}>
            <div style={{ display: "flex", justifyContent: "space-between", gap: 12, alignItems: "center", marginBottom: 12 }}>
              <div>
                <div style={{ fontSize: 13.5, color: "var(--text-2)", fontWeight: 500 }}>Workspace Rules</div>
                <div className="muted" style={{ fontSize: 12, marginTop: 3 }}>Settings-driven publishing guardrails</div>
              </div>
              <span className={`pill ${ruleIssues.length ? "warn" : "green"}`}>{ruleIssues.length ? `${ruleIssues.length} issue${ruleIssues.length === 1 ? "" : "s"}` : "Ready"}</span>
            </div>
            <div style={{ display: "grid", gridTemplateColumns: "repeat(5, 1fr)", gap: 10 }}>
              <div style={{ padding: 12, borderRadius: 12, background: "var(--bg-2)", border: "1px solid var(--border)" }}>
                <div className="muted" style={{ fontSize: 11 }}>Approval route</div>
                <div style={{ marginTop: 4, fontWeight: 700 }}>{approvalRequired ? "Required" : "Direct"}</div>
              </div>
              <div style={{ padding: 12, borderRadius: 12, background: "var(--bg-2)", border: "1px solid var(--border)" }}>
                <div className="muted" style={{ fontSize: 11 }}>Hashtags</div>
                <div style={{ marginTop: 4, fontWeight: 700 }}>{hashtagCount} / {workspaceRules.hashtagLimit || "∞"}</div>
              </div>
              <div style={{ padding: 12, borderRadius: 12, background: "var(--bg-2)", border: "1px solid var(--border)" }}>
                <div className="muted" style={{ fontSize: 11 }}>Quiet hours</div>
                <div style={{ marginTop: 4, fontWeight: 700 }}>{workspaceRules.quietStart || "Off"} - {workspaceRules.quietEnd || "Off"}</div>
              </div>
              <div style={{ padding: 12, borderRadius: 12, background: "var(--bg-2)", border: "1px solid var(--border)" }}>
                <div className="muted" style={{ fontSize: 11 }}>Profanity filter</div>
                <div style={{ marginTop: 4, fontWeight: 700 }}>{workspaceRules.profanityFilter === false ? "Off" : "On"}</div>
              </div>
              <div style={{ padding: 12, borderRadius: 12, background: "var(--bg-2)", border: "1px solid var(--border)" }}>
                <div className="muted" style={{ fontSize: 11 }}>Duplicate check</div>
                <div style={{ marginTop: 4, fontWeight: 700 }}>{workspaceRules.duplicateDetection ? "On" : "Off"}</div>
              </div>
            </div>
            {ruleIssues.length > 0 && (
              <div style={{ marginTop: 12, display: "grid", gap: 6 }}>
                {ruleIssues.map((issue) => <div key={issue} className="muted" style={{ color: "var(--warn)", fontSize: 12 }}>{issue}</div>)}
              </div>
            )}
            <div className="muted" style={{ marginTop: 12, fontSize: 12 }}>{approvalRouteDescription}</div>
          </div>

          {/* First comment */}
          <div className="card" style={{ padding: 20 }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 8 }}>
              <div style={{ fontSize: 13.5, color: "var(--text-2)", fontWeight: 500 }}>First comment <span className="muted" style={{ fontWeight: 400 }}>(optional)</span></div>
              <span className="muted" style={{ fontSize: 11.5 }}>Auto-posted as the first comment — great for hashtags or links</span>
            </div>
            <input className="input" value={firstComment} onChange={(e) => setFirstComment(e.target.value)} placeholder="e.g. #springdrop #handmade · link in bio" />
          </div>

          {/* Media + Edit */}
          <div className="card" style={{ padding: 20 }}>
            <div style={{ display: "grid", gridTemplateColumns: "1fr auto", gap: 24 }}>
              <div>
                <div style={{ fontSize: 13.5, color: "var(--text-2)", marginBottom: 12, fontWeight: 500 }}>Add media</div>
                <div style={{ display: "flex", gap: 12 }}>
                  {mediaThumbs.map((m, i) => (
                    <div key={i} onClick={() => { setActiveMedia(i); setGlobalMediaOverridden(true); }}>
                      <MediaTile {...m} active={activeMedia === i} />
                    </div>
                  ))}
                  <label style={{
                    width: 92, height: 92, borderRadius: 12,
                    border: "1.5px dashed var(--border-2)",
                    display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 5,
                    color: "var(--text-3)", cursor: "pointer", textAlign: "center",
                  }} title="Upload an image or video from your device">
                    {uploadingMedia ? <span style={{ fontSize: 11 }}>Uploading…</span> : <><Icon.Upload width="20" height="20" /><span style={{ fontSize: 10.5, fontWeight: 500 }}>Upload</span></>}
                    <input type="file" accept="image/*,video/*,.heic,.heif" onChange={uploadComposerMedia} style={{ display: "none" }} />
                  </label>
                </div>
                <div className="ai-media-row">
                  <input className="input" value={aiMediaPrompt} onChange={(e) => setAiMediaPrompt(e.target.value)} placeholder="Describe an image or video to generate…" style={{ flex: 1, minWidth: 160, height: 36, fontSize: 12.5 }} />
                  <button className="btn btn-sm" disabled={!!aiMediaBusy} onClick={() => generateAiMedia("image")}><Icon.Sparkles width="14" height="14" /> {aiMediaBusy === "image" ? "Generating…" : "AI image"}</button>
                  <button className="btn btn-sm" disabled={!!aiMediaBusy} onClick={() => generateAiMedia("video")}><Icon.Play width="14" height="14" /> {aiMediaBusy === "video" ? "Generating…" : "AI video"}</button>
                  <button className="btn btn-sm" disabled={!!aiMediaBusy} onClick={addStockPhoto}><Icon.Image width="14" height="14" /> {aiMediaBusy === "stock" ? "Adding…" : "Stock"}</button>
                  <button className="btn btn-sm" disabled={!!aiMediaBusy} onClick={addGif}><Icon.Smile width="14" height="14" /> GIF</button>
                </div>
                {hub.data?.aiUsageSummary && (
                  <div className="ai-usage-note">
                    <span className={`ai-mode-dot ${(hub.data.aiStatus?.image?.live || hub.data.aiStatus?.video?.live) ? "live" : "preview"}`} />
                    {(hub.data.aiStatus?.image?.live || hub.data.aiStatus?.video?.live) ? "Live AI" : "Preview mode (no API keys yet)"}
                    {" · "}${hub.data.aiUsageSummary.spentThisMonth.toFixed(2)} used this month
                    {hub.data.aiUsageSummary.monthlyBudgetUsd != null && ` of $${hub.data.aiUsageSummary.monthlyBudgetUsd.toFixed(2)} budget`}
                  </div>
                )}
              </div>
              <div style={{ borderLeft: "1px solid var(--border)", paddingLeft: 24 }}>
                <div style={{ fontSize: 13.5, color: "var(--text-2)", marginBottom: 12, fontWeight: 500 }}>Edit media</div>
                <div onClick={(event) => {
                  const type = event.target.closest("[data-media-edit]")?.getAttribute("data-media-edit");
                  if (type) applyMediaEdit(type);
                }} style={{ display: "flex", gap: 10 }}>
                  <div style={{ textAlign: "center", width: 64 }}>
                    <button data-media-edit="crop" aria-label="Crop" title={`${"Crop"} ${Platforms[activeVariantPlatform]?.name || activeVariantPlatform} media`} style={{ width: 64, height: 64, borderRadius: 12, background: "var(--bg-2)", border: "1px solid var(--border)", display: "grid", placeItems: "center", color: "var(--text)" }}>
                      <Icon.Crop width="20" height="20" />
                    </button>
                    <div style={{ fontSize: 12, marginTop: 6, color: "var(--text-2)" }}>Crop</div>
                  </div>
                  <div style={{ textAlign: "center", width: 64 }}>
                    <button data-media-edit="resize" aria-label="Resize" title={`${"Resize"} ${Platforms[activeVariantPlatform]?.name || activeVariantPlatform} media`} style={{ width: 64, height: 64, borderRadius: 12, background: "var(--bg-2)", border: "1px solid var(--border)", display: "grid", placeItems: "center", color: "var(--text)" }}>
                      <Icon.Resize width="20" height="20" />
                    </button>
                    <div style={{ fontSize: 12, marginTop: 6, color: "var(--text-2)" }}>Resize</div>
                  </div>
                  <div style={{ textAlign: "center", width: 64 }}>
                    <button data-media-edit="trim" aria-label="Trim" title={`${"Trim"} ${Platforms[activeVariantPlatform]?.name || activeVariantPlatform} media`} style={{ width: 64, height: 64, borderRadius: 12, background: "var(--bg-2)", border: "1px solid var(--border)", display: "grid", placeItems: "center", color: "var(--text)" }}>
                      <Icon.Scissors width="20" height="20" />
                    </button>
                    <div style={{ fontSize: 12, marginTop: 6, color: "var(--text-2)" }}>Trim</div>
                  </div>
                </div>
                {!!Object.keys(activeMediaVariant.mediaEdits || {}).length && (
                  <div style={{ marginTop: 10, display: "grid", gap: 4 }}>
                    {Object.entries(activeMediaVariant.mediaEdits || {}).map(([key, value]) => (
                      <div key={key} className="muted" style={{ fontSize: 11, display: "flex", justifyContent: "space-between", gap: 8 }}>
                        <span>{key}</span><b style={{ color: "var(--text-2)", textAlign: "right" }}>{value}</b>
                      </div>
                    ))}
                  </div>
                )}
                <select className="input" value="" onChange={(event) => { if (event.target.value) applyMediaEdit(event.target.value); }} style={{ height: 34, fontSize: 12, marginTop: 10 }}>
                  <option value="">Quick edit action</option>
                  <option value="crop">Apply crop</option>
                  <option value="resize">Apply resize</option>
                  <option value="trim">Apply trim</option>
                  <option value="filter-warm">Filter: warm</option>
                  <option value="filter-cool">Filter: cool</option>
                  <option value="filter-mono">Filter: mono</option>
                  <option value="filter-bright">Filter: bright</option>
                </select>
              </div>
            </div>
            <div style={{ marginTop: 18, paddingTop: 18, borderTop: "1px solid var(--border)" }}>
              <div style={{ display: "flex", justifyContent: "space-between", gap: 12, alignItems: "center", marginBottom: 12 }}>
                <div>
                  <div style={{ fontSize: 13.5, color: "var(--text-2)", fontWeight: 500 }}>Platform Media</div>
                  <div className="muted" style={{ fontSize: 12, marginTop: 3 }}>{mediaVariantCount} media variants · {selectedPlatforms.length || 0} selected channels</div>
                </div>
                <span className="pill info">Per-platform crops</span>
              </div>
              {selectedPlatforms.length ? (
                <div style={{ display: "grid", gridTemplateColumns: "minmax(0, 1fr) 220px", gap: 16, alignItems: "start" }}>
                  <div>
                    <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginBottom: 12 }}>
                      {selectedPlatforms.map((id) => {
                        const customMedia = variants[id]?.useGlobalMedia === false;
                        return (
                          <button key={id} className={`tb-chip ${activeVariantPlatform === id ? "active" : ""}`} onClick={() => setActiveVariantPlatform(id)}>
                            <PlatformIcon id={id} size={18} />
                            <span>{Platforms[id]?.name || id}</span>
                            {customMedia && <span className="pill green" style={{ padding: "1px 6px", fontSize: 10 }}>Media</span>}
                          </button>
                        );
                      })}
                    </div>
                    <label style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 12.5, color: "var(--text-2)", marginBottom: 10 }}>
                      <input
                        type="checkbox"
                        checked={activeUsesGlobalMedia}
                        onChange={(event) => setVariant(activeVariantPlatform, { useGlobalMedia: event.target.checked })}
                        style={{ accentColor: "var(--accent)" }}
                      />
                      Use global media for {Platforms[activeVariantPlatform]?.name || activeVariantPlatform}
                    </label>
                    <div style={{ display: "flex", gap: 8, flexWrap: "wrap", opacity: activeUsesGlobalMedia ? 0.5 : 1 }}>
                      {mediaThumbs.slice(0, 8).map((item) => {
                        const mediaId = item.id || item.url || item.ph;
                        const selected = activePlatformMedia === mediaId;
                        return (
                          <button
                            key={mediaId}
                            className="tb-chip"
                            disabled={activeUsesGlobalMedia}
                            onClick={() => setVariant(activeVariantPlatform, { useGlobalMedia: false, media: [mediaId] })}
                            style={{ borderColor: selected ? "var(--accent)" : "var(--border)", padding: 6 }}
                            title={item.name || item.ph}
                          >
                            <span style={{ width: 28, height: 28, borderRadius: 8, overflow: "hidden", background: item.bg || "var(--elev)", display: "grid", placeItems: "center", fontSize: 9 }}>
                              {item.src && item.type === "image" ? <img src={item.src} alt="" style={{ width: "100%", height: "100%", objectFit: "cover" }} /> : (item.ph || item.name || "Media").slice(0, 2)}
                            </span>
                            <span style={{ maxWidth: 88, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{item.name || item.ph}</span>
                          </button>
                        );
                      })}
                    </div>
                  </div>
                  <div className="card" style={{ padding: 12, background: "var(--bg-2)" }}>
                    <div className="field-label">Fit preset</div>
                    <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 7 }}>
                      {MediaFitOptions.map((fit) => (
                        <button
                          key={fit.id}
                          className="btn btn-sm"
                          onClick={() => setVariant(activeVariantPlatform, { mediaFit: fit.id })}
                          style={{
                            height: "auto",
                            padding: 8,
                            borderColor: activeMediaFit === fit.id ? "var(--accent)" : "var(--border)",
                            background: activeMediaFit === fit.id ? "var(--accent-soft)" : "var(--card)"
                          }}
                        >
                          <div style={{ display: "grid", placeItems: "center", gap: 4 }}>
                            <span style={{ width: fit.w, height: fit.h, border: "1px solid var(--border-2)", borderRadius: 3, background: "var(--elev)" }} />
                            <span>{fit.label}</span>
                            <span className="muted" style={{ fontSize: 10 }}>{fit.ratio}</span>
                          </div>
                        </button>
                      ))}
                    </div>
                    <div style={{ marginTop: 10, display: "grid", gap: 6, fontSize: 12 }}>
                      <div style={{ display: "flex", justifyContent: "space-between" }}><span className="muted">Recommended</span><b>{MediaFitOptions.find((fit) => fit.id === activeRecommendedFit)?.label}</b></div>
                      <div style={{ display: "flex", justifyContent: "space-between" }}><span className="muted">Asset</span><b style={{ maxWidth: 110, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{selectedMediaName(activePlatformMedia)}</b></div>
                      <div style={{ display: "flex", justifyContent: "space-between" }}><span className="muted">Status</span><b style={{ color: activeMediaFit === activeRecommendedFit ? "var(--accent)" : "var(--warn)" }}>{activeMediaFit === activeRecommendedFit ? "Ready" : "Review fit"}</b></div>
                    </div>
                  </div>
                </div>
              ) : (
                <div className="empty-note">Select at least one platform to customize media variants.</div>
              )}
            </div>
          </div>

          {/* Schedule */}
          <div className="card" style={{ padding: 20 }}>
            <div style={{ fontSize: 13.5, color: "var(--text-2)", marginBottom: 12, fontWeight: 500 }}>Schedule</div>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr 1.4fr", gap: 12 }}>
              <div>
                <label className="field-label">Date</label>
                <div style={{ position: "relative" }}>
                  <input className="input" type="date" value={date} onChange={(e) => setDate(e.target.value)} style={{ paddingRight: 36 }}/>
                  <Icon.Calendar width="14" height="14" style={{ position: "absolute", right: 12, top: "50%", transform: "translateY(-50%)", color: "var(--text-3)" }}/>
                </div>
              </div>
              <div>
                <label className="field-label">Time</label>
                <div style={{ position: "relative" }}>
                  <input className="input" type="time" value={time} onChange={(e) => setTime(e.target.value)} style={{ paddingRight: 36 }}/>
                  <Icon.Clock width="14" height="14" style={{ position: "absolute", right: 12, top: "50%", transform: "translateY(-50%)", color: "var(--text-3)" }}/>
                </div>
              </div>
              <div>
                <label className="field-label">Best Time</label>
                <div style={{ position: "relative" }}>
                  <input className="input" value={bestTime} onChange={(event) => setBestTime(event.target.value)} style={{ paddingRight: 36, color: "var(--accent-2)", fontWeight: 500 }}/>
                  <Icon.Star width="14" height="14" style={{ position: "absolute", right: 12, top: "50%", transform: "translateY(-50%)", color: "var(--accent-2)", fill: "currentColor" }}/>
                </div>
              </div>
              <div>
                <label className="field-label">Time zone</label>
                <div style={{ position: "relative" }}>
                  <input className="input" defaultValue="America/New_York (EDT)" style={{ paddingRight: 36 }}/>
                  <Icon.ChevronDown width="14" height="14" style={{ position: "absolute", right: 12, top: "50%", transform: "translateY(-50%)", color: "var(--text-3)" }}/>
                </div>
              </div>
            </div>
            <div style={{ marginTop: 12, display: "flex", gap: 8, flexWrap: "wrap", alignItems: "center" }}>
              <button className="btn btn-sm" onClick={refreshBestTimes}><Icon.Star width="12" height="12" /> Refresh best times</button>
              {bestTimeRecommendations.slice(0, 4).map((item) => (
                <button key={`${item.platform}-${item.time}`} className="tb-chip" onClick={() => applyBestTime(item)} style={{ padding: "6px 9px", borderColor: bestTime === item.time ? "var(--accent)" : "var(--border)" }} title={item.reason}>
                  <PlatformIcon id={item.platform} size={15} />
                  <span>{item.time}</span>
                  <span className="muted" style={{ fontSize: 10 }}>{Math.round(item.score)}%</span>
                </button>
              ))}
            </div>

            <div className="create-schedule-actions" style={{ marginTop: 18 }}>
              <div style={{ fontSize: 13.5, color: "var(--text-2)", marginBottom: 10, fontWeight: 500 }}>Content type</div>
              <div className="create-content-row" style={{ display: "flex", alignItems: "center", gap: 12 }}>
                <ContentTypeTab icon={Icon.Calendar} label="Feed" active={contentType === "feed"} disabled={!availableTypes.find((item) => item.id === "feed")?.supported} onClick={() => setContentType("feed")} />
                <ContentTypeTab icon={Icon.Play} label="Reel" active={contentType === "reel"} disabled={!availableTypes.find((item) => item.id === "reel")?.supported} onClick={() => setContentType("reel")} />
                <ContentTypeTab icon={Icon.Eye} label="Story" active={contentType === "story"} disabled={!availableTypes.find((item) => item.id === "story")?.supported} onClick={() => setContentType("story")} />
                <ContentTypeTab icon={Icon.Play} label="Short" active={contentType === "short"} disabled={!availableTypes.find((item) => item.id === "short")?.supported} onClick={() => setContentType("short")} />
                <div className="create-action-row" style={{ marginLeft: "auto", display: "flex", gap: 12 }}>
                  <button onClick={saveDraft} disabled={!!submitState} className="btn" style={{ padding: "10px 16px", fontSize: 14, fontWeight: 600, opacity: submitState && submitState !== "draft" ? 0.55 : 1 }}>
                    {submitState === "draft" ? "Saving..." : isEditing ? "Update Draft" : "Save Draft"}
                  </button>
                  <button
                    className="tb-chip"
                    onClick={() => setApprovalOverride(!approvalRequired)}
                    title={approvalRequired ? "Approval required — click to post directly without approval" : "Posting directly — click to require approval first"}
                    style={{ background: approvalRequired ? "var(--warn-soft)" : "rgba(20,184,138,0.1)", color: approvalRequired ? "var(--warn)" : "var(--accent-2)", borderColor: approvalRequired ? "rgba(245,158,11,0.25)" : "rgba(20,184,138,0.25)", padding: "10px 14px" }}
                  >
                    <Icon.Check width="15" height="15" style={{ opacity: approvalRequired ? 1 : 0.6 }} />
                    <span style={{ fontWeight: 600 }}>{approvalRouteLabel}</span>
                    <Icon.ChevronDown width="13" height="13" style={{ opacity: 0.7 }} />
                  </button>
                  <button onClick={addToQueue} disabled={!canQueue || !!submitState} className="btn btn-primary" title={canQueue ? "Add to Queue" : readinessIssues[0] || "Choose a ready channel"} style={{ padding: "10px 20px", fontSize: 14, fontWeight: 600, opacity: canQueue && (!submitState || submitState === "queue") ? 1 : 0.5, cursor: canQueue && !submitState ? "pointer" : "not-allowed" }}>
                    {submitState === "queue" ? "Saving..." : isEditing ? (approvalRequired ? "Submit Update" : "Schedule Update") : (approvalRequired ? "Add to Queue" : "Schedule Post")}
                    <Icon.ChevronDown width="14" height="14" style={{ marginLeft: 4 }}/>
                  </button>
                </div>
              </div>
            </div>
          </div>

          {/* Bottom mini panels: Hashtags, Media Fit, Approval, Link in Bio, Reports */}
          <div className="create-mini-panels" style={{ display: "grid", gridTemplateColumns: "minmax(0, 460px)", gap: 12 }}>
            {/* Hashtags */}
            <div className="card" style={{ padding: 16 }}>
              <div className="card-h" style={{ marginBottom: 10 }}>
                <h3>Hashtags</h3>
                <button className="sub" onClick={refreshHashtagSuggestions} style={{ color: "var(--accent-2)", cursor: "pointer", fontSize: 12 }}>Suggest</button>
              </div>
              <select className="input" value={selectedHashtagGroup?.id || ""} onChange={(event) => setActiveHashtagGroup(event.target.value)} style={{ height: 34, fontSize: 12, marginBottom: 8 }}>
                {hashtagGroups.map((group) => <option key={group.id} value={group.id}>{group.name}</option>)}
              </select>
              <div style={{ display: "flex", flexWrap: "wrap", gap: 6, minHeight: 52 }}>
                {(selectedHashtagGroup?.tags || []).map(t => (
                  <button key={t} onClick={() => appendHashtag(t)} className="pill" style={{ padding: "3px 9px", fontSize: 11 }}>{t}</button>
                ))}
                <button onClick={saveCurrentHashtag} className="pill" style={{ color: "var(--accent-2)", borderColor: "rgba(20,184,138,0.25)", padding: "3px 9px", fontSize: 11 }}><Icon.Plus width="10" height="10" /> Save suggestion</button>
              </div>
              {!!suggestedHashtags.length && (
                <div style={{ marginTop: 10, display: "flex", flexWrap: "wrap", gap: 6 }}>
                  {suggestedHashtags.slice(0, 5).map((tag) => <button key={tag} onClick={() => appendHashtag(tag)} className="pill info" style={{ padding: "3px 8px", fontSize: 10.5 }}>{tag}</button>)}
                </div>
              )}
              <div style={{ marginTop: 14, fontSize: 11, display: "flex", justifyContent: "space-between", gap: 8 }}>
                <div>
                  <div style={{ fontWeight: 600 }}>{selectedHashtagGroup?.topTag || selectedHashtagGroup?.tags?.[0] || "#clearcast"}</div>
                  <div style={{ color: "var(--accent-2)", fontSize: 10.5 }}>{Number(selectedHashtagGroup?.engagementRate || 0).toFixed(1)}% engagement</div>
                </div>
                <div style={{ color: "var(--text-3)" }}>{selectedHashtagGroup?.uses || 0} uses</div>
              </div>
            </div>
          </div>
        </div>

        {/* RIGHT — preview */}
        <div className="composer-preview" style={{ display: "flex", flexDirection: "column", gap: 16, position: "sticky", top: 88, maxHeight: "calc(100vh - 104px)", overflowY: "auto" }}>
          <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12 }}>
            <div style={{ fontSize: 13.5, color: "var(--text-2)", fontWeight: 500 }}>Preview</div>
            <div style={{ display: "flex", gap: 8 }}>
              <div className="tabs">
                <button className={`tab ${previewMode === "feed" ? "active" : ""}`} onClick={() => setPreviewMode("feed")}>Feed</button>
                <button className={`tab ${previewMode === "story" ? "active" : ""}`} onClick={() => setPreviewMode("story")}>Story / Reel</button>
                <button className={`tab ${previewMode === "short" ? "active" : ""}`} onClick={() => setPreviewMode("short")}>Short</button>
              </div>
              <div className="tabs">
                <button className={`tab ${previewDevice === "ios" ? "active" : ""}`} onClick={() => setPreviewDevice("ios")}>iOS</button>
                <button className={`tab ${previewDevice === "android" ? "active" : ""}`} onClick={() => setPreviewDevice("android")}>Android</button>
              </div>
            </div>
          </div>

          <div style={{ display: "flex", gap: 16, justifyContent: "center" }}>
            <PhoneFrame device={previewDevice}>
              {previewMode === "feed"
                ? <FeedPreview platform={activeVariantPlatform} caption={previewCaption} media={previewMedia} fit={previewFit} />
                : <StoryPreview platform={activeVariantPlatform} caption={previewCaption} media={previewMedia} fit={previewFit} />}
            </PhoneFrame>
          </div>
          <div className="card" style={{ padding: 12, display: "grid", gap: 8, background: "var(--bg-2)" }}>
            <div style={{ display: "flex", justifyContent: "space-between", fontSize: 12 }}><span className="muted">Channel</span><b>{Platforms[activeVariantPlatform]?.name || activeVariantPlatform}</b></div>
            <div style={{ display: "flex", justifyContent: "space-between", fontSize: 12 }}><span className="muted">Caption</span><b>{activeUsesGlobal ? "Global" : "Custom"}</b></div>
            <div style={{ display: "flex", justifyContent: "space-between", fontSize: 12 }}><span className="muted">Media</span><b>{activeUsesGlobalMedia ? "Global" : "Custom"}</b></div>
            <div style={{ display: "flex", justifyContent: "space-between", fontSize: 12 }}><span className="muted">Fit</span><b>{MediaFitOptions.find((item) => item.id === previewFit)?.label || previewFit}</b></div>
            <div style={{ display: "flex", justifyContent: "space-between", fontSize: 12 }}><span className="muted">Device</span><b>{previewDevice === "ios" ? "iOS" : "Android"}</b></div>
          </div>
        </div>
      </div>
    </div>
  );
}

window.CreatePostPage = CreatePostPage;
