"use client";

import { YouTubeMark, InstagramMark, FacebookMark } from "./BrandMarks";

/**
 * The emoji people actually reach for.
 *
 * The full picker didn't fit this panel — it cut off and showed only its
 * heading. A short grid is quicker to pick from anyway.
 */
const QUICK_EMOJI = [
  "😀", "😂", "🥰", "😍", "😎", "🤔", "😅", "😭", "😡", "🥳",
  "👍", "👎", "🙏", "👏", "💪", "🤝", "✌️", "🫶", "🔥", "✨",
  "❤️", "💔", "💯", "🎉", "🎂", "🍕", "☕", "⚽", "🚀", "🌟",
];

/** How someone might be feeling, as Facebook offers it. */
const FEELINGS = [
  { emoji: "😊", word: "happy" },
  { emoji: "🥰", word: "loved" },
  { emoji: "😢", word: "sad" },
  { emoji: "😡", word: "angry" },
  { emoji: "😴", word: "tired" },
  { emoji: "🤩", word: "excited" },
  { emoji: "😌", word: "relaxed" },
  { emoji: "🤔", word: "thoughtful" },
  { emoji: "🥳", word: "celebrating" },
  { emoji: "😅", word: "relieved" },
  { emoji: "🙏", word: "grateful" },
  { emoji: "💪", word: "motivated" },
];

/** Backgrounds a short post can be written on. */
const POST_BACKGROUNDS = [
  { id: "plain", name: "None", css: "#ffffff" },
  { id: "sunset", name: "Sunset", css: "linear-gradient(135deg,#f97316,#ec4899)" },
  { id: "ocean", name: "Ocean", css: "linear-gradient(135deg,#0ea5e9,#6366f1)" },
  { id: "forest", name: "Forest", css: "linear-gradient(135deg,#10b981,#0d9488)" },
  { id: "berry", name: "Berry", css: "linear-gradient(135deg,#8b5cf6,#d946ef)" },
  { id: "ember", name: "Ember", css: "linear-gradient(135deg,#dc2626,#f59e0b)" },
  { id: "slate", name: "Slate", css: "linear-gradient(135deg,#334155,#0f172a)" },
];


import { PhotoEditor, type EditState } from "./PhotoEditor";

import { usePostSettings } from "@/lib/site-context";

import { useEffect, useRef, useState } from "react";
import { Image as ImageIcon, Paperclip, Music2, Smile, BarChart3, Crown, Clapperboard, Flame, TriangleAlert, X, Plus, Loader2, Send, Pencil, Trash2, Palette, Hash, Sticker, Video, BarChart2, Calendar, Store, PlaySquare, MapPin, Music, Camera } from "lucide-react";
import { useConnectionWords } from "@/lib/site-context";
import clsx from "clsx";
import { sfx } from "@/lib/sfx";
import { useCreatePost } from "@/lib/create-post-context";
import { shrinkImage } from "@/lib/image";
import { uploadFile } from "@/lib/upload";
import { useEscapeKey } from "@/lib/use-escape-key";
import { EmojiPickerPopover } from "./EmojiPickerPopover";

// Icons that are genuinely wired below: Image, Emoji, Poll, Hot Take, Spoiler,
// Premium. Attachment/Audio/GIF need real file storage (non-image) which is
// out of scope for this local build — they stay visible (so the toolbar
// matches XRcoin) but show a short note instead of pretending to do something.
const NOT_YET_WIRED = new Set(["Attachment", "Audio", "GIF"]);

const POLL_ICON_CHOICES = [
  // Reactions & faces
  "❤️","😂","😮","😍","🥳","😎","🤔","😢","😡","🙌","👍","👎",
  // Energy & symbols
  "⚡","🔥","✨","💡","🎉","💥","⭐","🌈","💎","🏆","🥇","🎯",
  // Tech & work
  "🚀","🤖","🧠","💻","📱","🛠️","📈","📊","💰","🔒","🌍","📚",
  // Media & play
  "🎵","🎬","🎮","📷","🎤","🎧","🎨","✏️","📝","🕹️","🎲","🃏",
  // Food & drink
  "🍕","🍔","🌮","🍣","🥗","☕","🍺","🍷","🍦","🍫","🍎","🥑",
  // Life & nature
  "⚽","🏀","🏃","🚴","🧘","🌙","☀️","🌸","🌊","🏔️","🐶","🐱",
  // Travel & places
  "✈️","🚗","🏠","🏝️","🗺️","🎪","🎡","⛺","🚀","🛸","🌆","🌃",
];

export function CreatePostModal({
  open,
  onClose,
  onPosted,
}: {
  open: boolean;
  onClose: () => void;
  onPosted: () => void;
}) {
  const cw = useConnectionWords();
  // What the site allows, so the composer doesn't offer something the
  // server will refuse.
  const posts = usePostSettings();
  const maxPost = posts.maxLength;

  const [text, setText] = useState("");
  const [tag, setTag] = useState("");
  const [posting, setPosting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [notice, setNotice] = useState<string | null>(null);

  const [showEmoji, setShowEmoji] = useState(false);
  const [showColours, setShowColours] = useState(false);
  /** Who can see it. Public unless someone narrows it. */
  const [audience, setAudience] = useState("everyone");
  const [place, setPlace] = useState<string | null>(null);
  const [showStickers, setShowStickers] = useState(false);
  /** A coloured background makes a short post its own thing. */
  const [background, setBackground] = useState<string | null>(null);
  const [videoUrl, setVideoUrl] = useState<string | null>(null);
  const [audioUrl, setAudioUrl] = useState<string | null>(null);
  /** Which link box is open — YouTube or TikTok. */
  const [linkKind, setLinkKind] = useState<string | null>(null);
  const [linkUrl, setLinkUrl] = useState("");
  /** A video someone pasted, kept apart from the words they typed. */
  const [videoLink, setVideoLink] = useState<
    { kind: string; url: string } | null
  >(null);
  const [showFeelings, setShowFeelings] = useState(false);
  const [feeling, setFeeling] = useState<{ emoji: string; word: string } | null>(null);
  const [showPlace, setShowPlace] = useState(false);
  const [placeQuery, setPlaceQuery] = useState("");
  const [placeResults, setPlaceResults] = useState<{ label: string }[]>([]);

  const videoInputRef = useRef<HTMLInputElement | null>(null);
  const audioInputRef = useRef<HTMLInputElement | null>(null);
  const { community } = useCreatePost();
  const [showPollBuilder, setShowPollBuilder] = useState(false);
  const [pollOptions, setPollOptions] = useState(["", ""]);
  const [pollIcons, setPollIcons] = useState<string[]>(["⚡", "🎵"]);
  const [pollLayout, setPollLayout] = useState<"vertical" | "horizontal">("vertical");
  const [iconPickerFor, setIconPickerFor] = useState<number | null>(null);
  const [hotTake, setHotTake] = useState(false);
  const [spoiler, setSpoiler] = useState(false);
  const [premium, setPremium] = useState(false);
  const [imageDataUrl, setImageDataUrl] = useState<string | null>(null);
  /** The photo being edited, before it's uploaded. */
  const [editing, setEditing] = useState<string | null>(null);

  // Which tool the feed bar asked for, so choosing "Photo" there opens the
  // picker here rather than only opening the composer.
  useEffect(() => {
    const pick = (e: Event) => {
      const tool = (e as CustomEvent).detail as string;
      if (tool === "photo") fileInputRef.current?.click();
      if (tool === "video") videoInputRef.current?.click();
      if (tool === "poll") setShowPollBuilder(true);
      if (tool === "feeling") setShowFeelings(true);
      if (tool === "music") audioInputRef.current?.click();
      if (tool === "location") setShowPlace(true);
    };
    window.addEventListener("xr-compose-tool", pick);
    return () => window.removeEventListener("xr-compose-tool", pick);
  }, []);
  /** The photo as picked, so it can be reopened and edited again. */
  const [original, setOriginal] = useState<string | null>(null);
  /** Whether the chosen photo is wide enough not to need the blurred fill. */
  const [widePreview, setWidePreview] = useState(false);
  /** What was done to it, so a second pass carries on rather than restarts. */
  const [editState, setEditState] = useState<EditState | null>(null);
  const [photoMentions, setPhotoMentions] = useState<string[]>([]);
  const [photoTrack, setPhotoTrack] = useState<{
    trackName: string;
    artistName: string;
    artworkUrl?: string;
    previewUrl: string;
  } | null>(null);
  const [imageLoading, setImageLoading] = useState(false);

  const textareaRef = useRef<HTMLTextAreaElement>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);

  useEscapeKey(() => resetAndClose(), open);

  // Town and county only. A full street address on a post is more than
  // anyone meant to share, and it's the same lookup the rest of the site
  // uses rather than a second one.
  useEffect(() => {
    if (placeQuery.trim().length < 2) {
      setPlaceResults([]);
      return;
    }

    const handle = setTimeout(() => {
      fetch(`/api/places?q=${encodeURIComponent(placeQuery)}`)
        .then((r) => (r.ok ? r.json() : []))
        .then((rows: { label: string }[]) => setPlaceResults(rows))
        .catch(() => {});
    }, 350);

    return () => clearTimeout(handle);
  }, [placeQuery]);

  if (!open) return null;


  function resetAndClose() {
    setText("");
    setTag("");
    setShowPollBuilder(false);
    setPollOptions(["", ""]);
    setHotTake(false);
    setSpoiler(false);
    setPremium(false);
    setShowEmoji(false);
    setImageDataUrl(null);
    // Everything, or the next post inherits the last one's colour.
    setBackground(null);
    setVideoUrl(null);
    setAudioUrl(null);
    setFeeling(null);
    setPlace(null);
    setLinkKind(null);
    setLinkUrl("");
    setVideoLink(null);
    setShowFeelings(false);
    setShowPlace(false);
    setShowColours(false);
    setAudience("everyone");
    setError(null);
    onClose();
  }

  function insertEmoji(emoji: string) {
    const el = textareaRef.current;
    if (!el) {
      setText((t) => t + emoji);
      return;
    }
    const start = el.selectionStart ?? text.length;
    const end = el.selectionEnd ?? text.length;
    const next = text.slice(0, start) + emoji + text.slice(end);
    setText(next);
    requestAnimationFrame(() => {
      el.focus();
      el.selectionStart = el.selectionEnd = start + emoji.length;
    });
  }

  async function handleImagePick(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    e.target.value = ""; // allow picking the same file again later
    if (!file) return;
    setError(null);

    // Shown in the editor first. Only what comes out of it is uploaded, so
    // the crop, filter and overlays are baked into the file rather than
    // being instructions the viewer has to reapply.
    const reader = new FileReader();
    reader.onload = () => {
      const dataUrl = String(reader.result);
      setOriginal(dataUrl);
      // A different photo starts fresh; editing the same one carries on.
      setEditState(null);
      setEditing(dataUrl);
    };
    reader.onerror = () => setError("Couldn't read that image");
    reader.readAsDataURL(file);
  }

  function handleToolbarClick(label: string) {
    if (label === "Image") fileInputRef.current?.click();
    if (label === "Video") videoInputRef.current?.click();
    if (label === "Audio") audioInputRef.current?.click();
    if (label === "Emoji") setShowEmoji((v) => !v);
    if (label === "Poll") setShowPollBuilder((v) => !v);
    if (label === "Feeling") setShowFeelings((v) => !v);
    if (label === "Location") setShowPlace((v) => !v);
    if (label === "Hot Take") setHotTake((v) => !v);
    if (label === "Mark as Spoiler") setSpoiler((v) => !v);
    if (label === "Premium") setPremium((v) => !v);

    // A link, rather than a file: paste it and the video plays in the post.
    if (label === "YouTube" || label === "Instagram" || label === "Facebook") {
      setLinkKind((k) => (k === label ? null : label));
    }
  }

  /** Uploads a video or a piece of audio and attaches it. */
  async function pickMedia(
    e: React.ChangeEvent<HTMLInputElement>,
    kind: "video" | "audio"
  ) {
    const file = e.target.files?.[0];
    e.target.value = "";
    if (!file) return;

    setImageLoading(true);
    setError(null);

    try {
      const up = await uploadFile(file);
      const url = "url" in up ? up.url : null;

      if (!url) throw new Error("That didn't upload");
      if (kind === "video") setVideoUrl(url);
      else setAudioUrl(url);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Couldn't attach that");
    }

    setImageLoading(false);
  }

  const toolbarIcons = [
    { icon: ImageIcon, label: "Image", active: Boolean(imageDataUrl) },
    { icon: Paperclip, label: "Attachment" },
    { icon: Music2, label: "Audio" },
    { icon: Smile, label: "Emoji", active: showEmoji },
    { icon: BarChart3, label: "Poll", active: showPollBuilder },
    { icon: Crown, label: "Premium", active: premium },
    { icon: Clapperboard, label: "GIF" },
    { icon: Flame, label: "Hot Take", active: hotTake },
    { icon: TriangleAlert, label: "Mark as Spoiler", active: spoiler },
  ].filter((tool) => {
    // Offering something the server will refuse is worse than not
    // offering it, so a switched-off feature loses its button.
    if (tool.label === "Poll") return posts.polls;
    if (tool.label === "GIF") return posts.gifPicker;
    return true;
  });

  // Post is enabled once there's text or any attachment.
  const canPost =
    text.trim().length > 0 ||
    Boolean(imageDataUrl) ||
    (showPollBuilder && pollOptions.filter((o) => o.trim()).length >= 2);

  async function submit() {
    // A photo or poll alone is a valid post — text isn't required.
    if (!canPost) return;
    const validOptions = pollOptions.map((o) => o.trim()).filter(Boolean);
    if (showPollBuilder && validOptions.length < 2) {
      setError("A poll needs at least 2 options");
      return;
    }
    setPosting(true);
    setError(null);
    sfx.fanfare();
    const res = await fetch("/api/posts", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        audience,
        place,
        feeling,
        videoUrl,
        audioUrl,
        background,
        // The link goes at the end, past whatever they wrote.
        text: videoLink ? `${text}\n\n${videoLink.url}`.trim() : text,
        tag: tag || undefined,
        hotTake,
        spoiler,
        premium,
        imageUrl: imageDataUrl || undefined,
        communityId: community?.id,
        pollOptions: showPollBuilder ? validOptions : undefined,
        pollIcons: showPollBuilder ? pollIcons.slice(0, validOptions.length) : undefined,
        pollLayout: showPollBuilder ? pollLayout : undefined,
        // Anything the photo editor attached travels with the post.
        mentions: photoMentions,
        track: photoTrack,
      }),
    });
    setPosting(false);
    if (!res.ok) {
      const data = await res.json().catch(() => ({}));
      setError(data.error || "Something went wrong");
      return;
    }
    resetAndClose();
    onPosted();
  }

  /** Uploads what the editor produced and attaches it to the post. */
  async function useEdited(result: {
    dataUrl: string;
    mentions: string[];
    track?: { trackName: string; artistName: string; artworkUrl?: string; previewUrl: string };
    state: EditState;
  }) {
    setEditing(null);
    setImageLoading(true);

    try {
      const blob = await (await fetch(result.dataUrl)).blob();
      const file = new File([blob], "photo.jpg", { type: "image/jpeg" });
      const up = await uploadFile(await shrinkImage(file));
      setImageDataUrl("url" in up ? up.url : null);
      setPhotoMentions(result.mentions);
      setPhotoTrack(result.track ?? null);
      // Kept so pressing edit reopens everything as it was.
      setEditState(result.state);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Couldn't save that image");
    }

    setImageLoading(false);
  }

  // The editor is its own full-screen layer, above the composer. Nesting it
  // inside meant every click bubbled to the backdrop and closed everything.
  if (editing) {
    return (
      <PhotoEditor
        src={editing}
        previous={editState}
        onCancel={() => setEditing(null)}
        onDone={useEdited}
      />
    );
  }

  return (
    <div
      className="fixed inset-0 z-50 bg-black/40 backdrop-blur-sm flex items-start md:items-center justify-center p-4"
      onClick={() => {
        // Clicking the backdrop shouldn't discard what someone has written.
        // Close only when the composer is empty; otherwise just dismiss any
        // open picker so the click still feels responsive.
        if (canPost) {
          setShowEmoji(false);
          return;
        }
        resetAndClose();
      }}
    >
      <div
        className="cp-modal bg-white dark:bg-neutral-950 rounded-[20px] w-full max-w-lg shadow-2xl mt-10 md:mt-0 max-h-[90vh] overflow-hidden flex flex-col border border-neutral-200 dark:border-neutral-800"
        onClick={(e) => e.stopPropagation()}
      >
        <div className="cp-header">
          <button onClick={resetAndClose} className="cp-close" aria-label="Close">
            <X size={19} />
          </button>
          <span className="cp-title">
            {community ? `Post to ${community.name}` : "Create Post"}
          </span>
          <button
            onClick={submit}
            disabled={!canPost || posting}
            className={`cp-post ${canPost && !posting ? "ready" : ""}`}
          >
            {posting ? "Posting…" : "Post"}
          </button>
        </div>

        <div className="flex-1 overflow-y-auto px-5 py-4 min-h-0">
          {error && (
            <p className="text-sm text-red-500 bg-red-50 dark:bg-red-950/40 rounded-lg px-3 py-2 mb-3">
              {error}
            </p>
          )}
          {notice && (
            <p className="text-sm text-neutral-500 bg-neutral-50 dark:bg-neutral-900 rounded-lg px-3 py-2 mb-3">
              {notice}
            </p>
          )}

          {(hotTake || spoiler || premium) && (
            <div className="flex gap-2 mb-2">
              {hotTake && (
                <span className="inline-flex items-center gap-1 text-xs font-medium px-2 py-1 rounded-full bg-orange-100 text-orange-700 dark:bg-orange-950 dark:text-orange-300">
                  <Flame size={12} /> Hot Take
                </span>
              )}
              {spoiler && (
                <span className="inline-flex items-center gap-1 text-xs font-medium px-2 py-1 rounded-full bg-neutral-200 text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300">
                  <TriangleAlert size={12} /> Spoiler
                </span>
              )}
              {premium && (
                <span className="inline-flex items-center gap-1 text-xs font-medium px-2 py-1 rounded-full bg-amber-100 text-amber-700 dark:bg-amber-950 dark:text-amber-300">
                  <Crown size={12} /> Premium-only
                </span>
              )}
            </div>
          )}


          <div
            className={clsx("cp-write", background && "on-colour")}
            data-bg={background ?? undefined}
          >
            {/* Part of the sentence, but a label rather than text — so it
                can't be half-deleted, only removed. */}
            {videoLink && (
              <span className="cp-feeling-chip">
                {videoLink.kind === "YouTube" ? (
                  <YouTubeMark size={13} />
                ) : videoLink.kind === "Instagram" ? (
                  <InstagramMark size={13} />
                ) : (
                  <FacebookMark size={13} />
                )}
                <b>{videoLink.kind} video</b>
                <button onClick={() => setVideoLink(null)} title="Remove">
                  <X size={12} />
                </button>
              </span>
            )}

            {place && (
              <span className="cp-feeling-chip">
                <MapPin size={13} /> <b>{place}</b>
                <button onClick={() => setPlace(null)} title="Remove">
                  <X size={12} />
                </button>
              </span>
            )}

            {feeling && (
              <span className="cp-feeling-chip">
                is feeling {feeling.emoji} <b>{feeling.word}</b>
                <button onClick={() => setFeeling(null)} title="Remove">
                  <X size={12} />
                </button>
              </span>
            )}

          <textarea
            ref={textareaRef}
            autoFocus
            value={text}
            onChange={(e) => setText(e.target.value)}
            placeholder="What is in your mind !"
            rows={3}
            maxLength={maxPost}
            className="w-full resize-none outline-none text-[16px] placeholder-neutral-400 bg-transparent"
          />
          <span className="cp-inbox">
            <button
              onClick={() => setShowColours((v) => !v)}
              className={clsx("cp-tool", showColours && "on")}
              title="Background colour"
            >
              <Palette size={17} />
            </button>

            <button
              onClick={() => {
                // Inserted where the cursor is, so it reads as part of the
                // sentence rather than being appended.
                setText((t) => `${t}${t.endsWith(" ") || !t ? "" : " "}#`);
              }}
              className="cp-tool"
              title="Add a hashtag"
            >
              <Hash size={17} />
            </button>

            <button
              onClick={() => setShowEmoji((v) => !v)}
              className={clsx("cp-tool", showEmoji && "on")}
              title="Emoji"
            >
              <Smile size={17} />
            </button>

            <span className="cp-who">
              <select
                value={audience}
                onChange={(e) => setAudience(e.target.value)}
                aria-label="Who can see this"
              >
                <option value="everyone">Public</option>
                {/* The stored value stays "followers" whichever model the
                    site runs -- it is the same set of people, and changing
                    it would rewrite the privacy of every existing post. */}
                <option value="followers">{cw.plural}</option>
                <option value="onlyMe">Only me</option>
              </select>
            </span>
          </span>
          </div>

          {showColours && (
            <div className="cp-colours">
              {POST_BACKGROUNDS.map((bg) => (
                <button
                  key={bg.id}
                  onClick={() =>
                    setBackground(
                      bg.id === "plain" || background === bg.id ? null : bg.id
                    )
                  }
                  className={clsx(
                    "cp-colour",
                    (background === bg.id || (bg.id === "plain" && !background)) && "on"
                  )}
                  style={{ background: bg.css }}
                  title={bg.name}
                />
              ))}
            </div>
          )}

          <input
            ref={videoInputRef}
            type="file"
            accept="video/*"
            className="hidden"
            onChange={(e) => pickMedia(e, "video")}
          />

          <input
            ref={audioInputRef}
            type="file"
            accept="audio/*"
            className="hidden"
            onChange={(e) => pickMedia(e, "audio")}
          />

          <input
            ref={fileInputRef}
            type="file"
            accept="image/*"
            className="hidden"
            onChange={handleImagePick}
          />

          {imageLoading && (
            <div className="flex items-center gap-2 text-sm text-neutral-500 mb-2">
              <Loader2 size={16} className="animate-spin" /> Processing image…
            </div>
          )}

          {imageDataUrl && (
            <div className="relative mb-2">
              <span className={clsx("pf-frame preview", widePreview && "wide")}>
                {/* Same blurred fill as the post, so the preview looks like
                    what's about to be published. */}
                <span
                  className="pf-blur"
                  style={{ backgroundImage: `url(${imageDataUrl})` }}
                  aria-hidden
                />
                {/* eslint-disable-next-line @next/next/no-img-element */}
                <img
                  src={imageDataUrl}
                  alt="Selected"
                  className="pf-photo"
                  onLoad={(e) => {
                    const img = e.currentTarget;
                    if (img.naturalHeight) {
                      setWidePreview(img.naturalWidth / img.naturalHeight > 0.8);
                    }
                  }}
                />
              </span>
              {/* Over the photo, so it can be worked on again or dropped
                  without starting the post over. */}
              <span className="cp-photo-tools">
                <button
                  onClick={() => original && setEditing(original)}
                  title="Edit this photo"
                >
                  <Pencil size={14} />
                </button>
                <button
                  onClick={() => {
                    setImageDataUrl(null);
                    setOriginal(null);
                    setPhotoMentions([]);
                    setPhotoTrack(null);
                    setEditState(null);
                  }}
                  title="Remove it"
                >
                  <Trash2 size={14} />
                </button>
              </span>
            </div>
          )}
          {/* Video and audio, once attached. */}
          {videoUrl && (
            <div className="cp-attached">
              <video src={videoUrl} controls />
              <button onClick={() => setVideoUrl(null)} title="Remove">
                <X size={15} />
              </button>
            </div>
          )}

          {audioUrl && (
            <div className="cp-attached audio">
              <audio src={audioUrl} controls />
              <button onClick={() => setAudioUrl(null)} title="Remove">
                <X size={15} />
              </button>
            </div>
          )}

          {/* A link, rather than a file: the video plays in the post and
              the raw URL never appears. */}
          {linkKind && (
            <div className="cp-linkbox">
              <input
                autoFocus
                value={linkUrl}
                onChange={(e) => setLinkUrl(e.target.value)}
                placeholder={`Paste a ${linkKind} link`}
              />
              <button
                onClick={() => {
                  // Held apart from the words: in the text, one stray
                  // keystroke breaks the link and the video stops
                  // appearing with no clue why.
                  if (linkUrl.trim()) {
                    setVideoLink({ kind: linkKind, url: linkUrl.trim() });
                  }
                  setLinkUrl("");
                  setLinkKind(null);
                }}
                disabled={!linkUrl.trim()}
              >
                Add
              </button>
            </div>
          )}

          {/* How they're feeling, the way Facebook does it. */}
          {showFeelings && (
            <div className="cp-feelings">
              {FEELINGS.map((f) => (
                <button
                  key={f.word}
                  onClick={() => {
                    setFeeling(feeling?.word === f.word ? null : f);
                    setShowFeelings(false);
                  }}
                  className={clsx(feeling?.word === f.word && "on")}
                >
                  <span>{f.emoji}</span>
                  {f.word}
                </button>
              ))}
            </div>
          )}

          {/* Where they are — shown beside their name on the post. */}
          {showPlace && (
            <div className="cp-place">
              <span className="cp-linkbox">
                <MapPin size={16} />
                <input
                  autoFocus
                  value={placeQuery}
                  onChange={(e) => setPlaceQuery(e.target.value)}
                  placeholder="Town or city"
                />
                <button
                  onClick={() => {
                    // Whatever they typed, for a place the lookup doesn't
                    // know about.
                    if (placeQuery.trim()) setPlace(placeQuery.trim());
                    setPlaceQuery("");
                    setShowPlace(false);
                  }}
                  disabled={!placeQuery.trim()}
                >
                  Add
                </button>
              </span>

              {placeResults.length > 0 && (
                <div className="cp-places">
                  {placeResults.map((row) => (
                    <button
                      key={row.label}
                      onClick={() => {
                        setPlace(row.label);
                        setPlaceQuery("");
                        setShowPlace(false);
                      }}
                    >
                      <MapPin size={14} />
                      {row.label}
                    </button>
                  ))}
                </div>
              )}
            </div>
          )}




          {showEmoji && (
            <div className="cp-emoji">
              {QUICK_EMOJI.map((emoji) => (
                <button
                  key={emoji}
                  onClick={() => insertEmoji(emoji)}
                  title={emoji}
                >
                  {emoji}
                </button>
              ))}
            </div>
          )}

          <div className="flex justify-end pb-2">
            {/* Only once it matters — a count of nothing is noise. */}
            {text.length > maxPost * 0.75 && (
              <span
                className={clsx(
                  "cp-count",
                  text.length > maxPost * 0.95 && "max",
                  text.length > maxPost * 0.85 && text.length <= maxPost * 0.95 && "warn"
                )}
              >
                {maxPost - text.length}
              </span>
            )}
          </div>

          {showPollBuilder && (
            <div className="flex flex-col gap-2 mb-2 border border-neutral-100 dark:border-neutral-800 rounded-xl p-3">
              <div className="flex items-center gap-2 mb-2.5">
                <span className="text-[11px] font-bold text-neutral-500">Layout</span>
                {(["vertical", "horizontal"] as const).map((l) => (
                  <button
                    key={l}
                    type="button"
                    onClick={() => setPollLayout(l)}
                    className={clsx(
                      "rounded-full px-3 py-1 text-[11px] font-bold capitalize transition-all",
                      pollLayout === l
                        ? "bg-black text-white dark:bg-white dark:text-black"
                        : "bg-neutral-100 dark:bg-neutral-900 hover:scale-105"
                    )}
                  >
                    {l === "vertical" ? "▍ Bars" : "▬ Rows"}
                  </button>
                ))}
              </div>
              {pollOptions.map((opt, i) => (
                <div key={i} className="flex items-center gap-2 relative">
                  <button
                    type="button"
                    onClick={() => setIconPickerFor(iconPickerFor === i ? null : i)}
                    title="Choose an icon"
                    className="w-9 h-9 shrink-0 rounded-lg bg-neutral-100 dark:bg-neutral-900 flex items-center justify-center text-lg hover:bg-neutral-200 dark:hover:bg-neutral-800 transition-colors"
                  >
                    {pollIcons[i] || "＋"}
                  </button>
                  {iconPickerFor === i && (
                    <div className="absolute left-0 top-11 z-30 w-64 bg-white dark:bg-neutral-900 border border-neutral-200 dark:border-neutral-800 rounded-xl shadow-xl p-2 grid grid-cols-8 gap-1">
                      {POLL_ICON_CHOICES.map((ic) => (
                        <button
                          key={ic}
                          type="button"
                          onClick={() => {
                            setPollIcons((all) => {
                              const next = [...all];
                              next[i] = ic;
                              return next;
                            });
                            setIconPickerFor(null);
                          }}
                          className="w-7 h-7 rounded-md flex items-center justify-center text-base hover:bg-neutral-100 dark:hover:bg-neutral-800"
                        >
                          {ic}
                        </button>
                      ))}
                    </div>
                  )}
                  <input
                    value={opt}
                    onChange={(e) =>
                      setPollOptions((opts) => opts.map((o, idx) => (idx === i ? e.target.value : o)))
                    }
                    placeholder={`Option ${i + 1}`}
                    maxLength={40}
                    className="flex-1 bg-neutral-100 dark:bg-neutral-900 rounded-lg px-3 py-2 text-sm outline-none"
                  />
                  {pollOptions.length > 2 && (
                    <button
                      onClick={() => {
                        setPollOptions((opts) => opts.filter((_, idx) => idx !== i));
                        setPollIcons((all) => all.filter((_, idx) => idx !== i));
                      }}
                      className="text-neutral-400 hover:text-neutral-700"
                    >
                      <X size={16} />
                    </button>
                  )}
                </div>
              ))}
              {pollOptions.length < 20 && (
                <button
                  onClick={() => {
                    setPollOptions((opts) => [...opts, ""]);
                    setPollIcons((all) => [...all, POLL_ICON_CHOICES[all.length % POLL_ICON_CHOICES.length]]);
                  }}
                  className="flex items-center gap-1 text-sm text-neutral-500 hover:text-neutral-800 dark:hover:text-neutral-200 self-start"
                >
                  <Plus size={14} /> Add option
                </button>
              )}
            </div>
          )}


        </div>

        {/* The row from the reference: eight tools with their names, then
            who can see it. Naming them means nobody has to guess what an
            icon does. */}
        <div className="cp-bar">
          <div className="cp-tools">
            {[
              { id: "Image", label: "Photo", icon: ImageIcon, on: Boolean(imageDataUrl) },
              { id: "Video", label: "Video", icon: Video, on: Boolean(videoUrl) },
              { id: "Audio", label: "Audio", icon: Music2, on: Boolean(audioUrl) },
              { id: "Poll", label: "Poll", icon: BarChart2, on: showPollBuilder },
              { id: "Feeling", label: "Feeling", icon: Smile, on: Boolean(feeling) },
              { id: "YouTube", label: "YouTube", icon: YouTubeMark, on: linkKind === "YouTube" },
              { id: "Instagram", label: "Instagram", icon: InstagramMark, on: linkKind === "Instagram" },
              { id: "Facebook", label: "Facebook", icon: FacebookMark, on: linkKind === "Facebook" },
              { id: "Location", label: "Location", icon: MapPin, on: Boolean(place) },
            ].map((tool) => (
              <button
                key={tool.label}
                onClick={() => {
                  sfx.click();
                  handleToolbarClick(tool.id);
                }}
                className={clsx("cp-tool-btn", tool.on && "on")}
                title={tool.label}
              >
                <tool.icon size={20} />
              </button>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}
