"use client";

// R15 E.8: chat input enhancements — saved-replies picker (💬) and image
// attachment button (📎). The room page passes setNewMessage so a chosen
// reply lands in the textarea, and onAttachmentReady so an uploaded
// image becomes the next message's attachment_url.

import { useEffect, useRef, useState } from "react";
import { useToastStore } from "@/lib/stores/toast-store";

interface SavedReply {
  id: number;
  label: string;
  body: string;
}

export interface ChatExtrasProps {
  onInsertReply: (text: string) => void;
  onAttachmentReady: (url: string) => void;
  disabled?: boolean;
}

export default function ChatExtras({
  onInsertReply,
  onAttachmentReady,
  disabled,
}: ChatExtrasProps) {
  const [open, setOpen] = useState(false);
  const [replies, setReplies] = useState<SavedReply[] | null>(null);
  const [uploading, setUploading] = useState(false);
  const fileRef = useRef<HTMLInputElement>(null);
  const addToast = useToastStore((s) => s.addToast);

  useEffect(() => {
    if (open && replies === null) {
      fetch("/api/messaging/replies")
        .then((r) => r.json())
        .then((data) => setReplies(Array.isArray(data?.data) ? data.data : []))
        .catch(() => setReplies([]));
    }
  }, [open, replies]);

  async function handleFile(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    e.target.value = ""; // allow re-selecting the same file
    if (!file) return;
    if (!file.type.startsWith("image/")) {
      addToast("error", "Only image files can be attached");
      return;
    }
    setUploading(true);
    try {
      const fd = new FormData();
      fd.append("file", file);
      const res = await fetch("/api/upload/photos", { method: "POST", body: fd });
      if (!res.ok) {
        // R16 D.2: surface failures so the user knows the attachment didn't
        // ship — silent fail used to leave them sending text-only with the
        // attachment lost.
        const errBody = await res.json().catch(() => null);
        addToast("error", errBody?.error || "Upload failed");
        return;
      }
      const data = await res.json();
      // /api/upload/photos returns { data: { photo: "/path/..." }, sizes: [...] }
      const url: string | undefined =
        data?.data?.photo ||
        data?.sizes?.find((s: { name: string; path: string }) => s.name === "original")?.path ||
        data?.url ||
        data?.path;
      if (url) {
        onAttachmentReady(url);
      } else {
        addToast("error", "Upload succeeded but no URL was returned");
      }
    } catch {
      addToast("error", "Upload failed — network error");
    } finally {
      setUploading(false);
    }
  }

  return (
    <div className="relative flex items-center gap-1">
      <input
        ref={fileRef}
        type="file"
        accept="image/jpeg,image/png,image/webp"
        onChange={handleFile}
        className="hidden"
      />
      <button
        type="button"
        onClick={() => fileRef.current?.click()}
        disabled={disabled || uploading}
        title="Attach image"
        className="p-2 rounded-lg text-text-muted hover:text-text hover:bg-surface-light transition-colors disabled:opacity-40"
        aria-label="Attach image"
      >
        {uploading ? (
          <svg className="w-5 h-5 animate-spin" fill="none" viewBox="0 0 24 24">
            <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
            <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
          </svg>
        ) : (
          <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
              d="M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13" />
          </svg>
        )}
      </button>
      <button
        type="button"
        onClick={() => setOpen((v) => !v)}
        disabled={disabled}
        title="Saved replies"
        className="p-2 rounded-lg text-text-muted hover:text-text hover:bg-surface-light transition-colors disabled:opacity-40"
        aria-label="Saved replies"
      >
        <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
            d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
        </svg>
      </button>
      {open && (
        <div className="absolute bottom-full mb-2 left-0 w-72 bg-surface border border-surface-light rounded-lg shadow-lg overflow-hidden z-30">
          <div className="px-3 py-2 border-b border-surface-light flex items-center justify-between">
            <span className="text-xs font-semibold text-text-muted uppercase tracking-wide">
              Saved replies
            </span>
            <a
              href="/manage/messaging/replies"
              className="text-xs text-primary hover:text-primary-dark"
            >
              Manage
            </a>
          </div>
          <ul className="max-h-72 overflow-y-auto">
            {replies === null ? (
              <li className="px-3 py-3 text-text-muted text-sm">Loading…</li>
            ) : replies.length === 0 ? (
              <li className="px-3 py-3 text-text-muted text-sm">
                None yet.{" "}
                <a href="/manage/messaging/replies" className="text-primary hover:underline">
                  Add one
                </a>
                .
              </li>
            ) : (
              replies.map((reply) => (
                <li key={reply.id}>
                  <button
                    type="button"
                    onClick={() => {
                      onInsertReply(reply.body);
                      setOpen(false);
                    }}
                    className="w-full text-left px-3 py-2 hover:bg-surface-light transition-colors"
                  >
                    <p className="text-sm font-medium text-text truncate">
                      {reply.label}
                    </p>
                    <p className="text-xs text-text-muted truncate">{reply.body}</p>
                  </button>
                </li>
              ))
            )}
          </ul>
        </div>
      )}
    </div>
  );
}
