import { useEffect, useRef, useState } from 'react';
import { api, type SpaceEmoji } from '../../../api/client';
import { useExpressionStore } from '../../../stores/expressionStore';
import { useTransferStore } from '../../../stores/transferStore';
import { waitForTransferAttachment } from '../../../utils/waitForTransfer';
import { useT } from '../../../i18n';

interface ExpressionsPanelProps {
  spaceId: string;
}

/** Emoji e figurinha são carregados a cada mensagem: têm de ser leves. */
const MAX_BYTES = 512 * 1024;

type Kind = 'emoji' | 'sticker';

export function ExpressionsPanel({ spaceId }: ExpressionsPanelProps) {
  const t = useT();
  const emojis = useExpressionStore((s) => s.emojisBySpace.get(spaceId)) ?? [];
  const stickers = useExpressionStore((s) => s.stickersBySpace.get(spaceId)) ?? [];
  const setEmojis = useExpressionStore((s) => s.setEmojis);
  const setStickers = useExpressionStore((s) => s.setStickers);

  const [kind, setKind] = useState<Kind>('emoji');
  const [pending, setPending] = useState<File | null>(null);
  const [name, setName] = useState('');
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState('');
  const fileRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    let cancelled = false;
    Promise.all([api.expressions.emojis(spaceId), api.expressions.stickers(spaceId)])
      .then(([e, s]) => {
        if (cancelled) return;
        setEmojis(spaceId, e.emojis);
        setStickers(spaceId, s.stickers);
      })
      .catch(() => { /* lista vazia é o fallback honesto */ });
    return () => { cancelled = true; };
  }, [spaceId, setEmojis, setStickers]);

  const pickFile = (file: File) => {
    setError('');
    if (file.size > MAX_BYTES) {
      setError(t('expressions.tooLarge'));
      return;
    }
    setPending(file);
    // Sugere o nome do arquivo já no formato aceito, para o caso comum não
    // exigir digitação nenhuma.
    const base = file.name.replace(/\.[^.]+$/, '');
    setName(kind === 'emoji' ? base.toLowerCase().replace(/[^a-z0-9_]+/g, '_').slice(0, 32) : base.slice(0, 32));
  };

  const cancel = () => {
    setPending(null);
    setName('');
    if (fileRef.current) fileRef.current.value = '';
  };

  const confirm = async () => {
    const file = pending;
    const trimmed = name.trim();
    if (!file || !trimmed) return;

    setBusy(true);
    setError('');
    try {
      const tid = await useTransferStore.getState().startUpload(file, { tray: false });
      const { filename } = await waitForTransferAttachment(tid);
      if (kind === 'emoji') {
        const created = await api.expressions.addEmoji(spaceId, trimmed, filename);
        setEmojis(spaceId, [...emojis, created]);
      } else {
        const created = await api.expressions.addSticker(spaceId, trimmed, filename);
        setStickers(spaceId, [...stickers, created]);
      }
      cancel();
    } catch (err) {
      // 409 é nome repetido — mensagem específica, porque a ação corretiva é
      // outra: mudar o nome, não trocar a imagem.
      const conflict = (err as { statusCode?: number } | undefined)?.statusCode === 409;
      setError(conflict ? t('expressions.nameTaken') : t('expressions.uploadFailed'));
    } finally {
      setBusy(false);
    }
  };

  const remove = async (item: SpaceEmoji) => {
    const isEmoji = kind === 'emoji';
    const previous = isEmoji ? emojis : stickers;
    const next = previous.filter((x) => x.id !== item.id);
    if (isEmoji) setEmojis(spaceId, next); else setStickers(spaceId, next);
    try {
      await (isEmoji ? api.expressions.removeEmoji(item.id) : api.expressions.removeSticker(item.id));
    } catch {
      if (isEmoji) setEmojis(spaceId, previous); else setStickers(spaceId, previous);
    }
  };

  const items = kind === 'emoji' ? emojis : stickers;

  return (
    <div className="max-w-2xl">
      <h2 className="text-lg font-semibold text-txt-primary mb-4">{t('expressions.title')}</h2>

      <div className="flex gap-1.5 mb-5">
        {(['emoji', 'sticker'] as Kind[]).map((k) => (
          <button
            key={k}
            type="button"
            onClick={() => { setKind(k); cancel(); }}
            className={`px-2.5 py-1 rounded-full text-[12px] font-medium transition-colors ${
              kind === k ? 'bg-accent-primary text-white' : 'bg-surface-elevated text-txt-secondary hover:text-txt-primary'
            }`}
          >
            {k === 'emoji' ? t('expressions.emojis') : t('expressions.stickers')}
          </button>
        ))}
      </div>

      <button
        type="button"
        onClick={() => fileRef.current?.click()}
        disabled={busy}
        className="px-3 py-1.5 rounded-md text-[13px] font-medium bg-accent-primary text-white hover:brightness-110 disabled:opacity-50"
      >
        {kind === 'emoji' ? t('expressions.addEmoji') : t('expressions.addSticker')}
      </button>
      <input
        ref={fileRef}
        type="file"
        accept="image/*"
        className="hidden"
        onChange={(e) => { const f = e.target.files?.[0]; if (f) pickFile(f); }}
      />

      {error && <p className="text-[12px] text-txt-danger mt-2">{error}</p>}

      {pending && (
        <div className="mt-3 p-3 rounded-lg bg-surface-elevated/60">
          <label className="block text-[11px] text-txt-tertiary mb-1">{t('expressions.namePrompt')}</label>
          <input
            type="text"
            value={name}
            maxLength={32}
            autoFocus
            onChange={(e) => setName(e.target.value)}
            onKeyDown={(e) => {
              e.stopPropagation();
              if (e.key === 'Enter' && name.trim()) void confirm();
              if (e.key === 'Escape') cancel();
            }}
            className="input-search w-full mb-1"
          />
          {kind === 'emoji' && (
            <p className="text-[11px] text-txt-tertiary mb-2">{t('expressions.nameHintEmoji')}</p>
          )}
          <div className="flex gap-2 mt-2">
            <button
              type="button"
              onClick={() => void confirm()}
              disabled={busy || !name.trim()}
              className="px-2.5 py-1 rounded-md text-[12px] font-medium bg-accent-primary text-white disabled:opacity-50"
            >
              {busy ? t('expressions.uploading') : t('expressions.confirm')}
            </button>
            <button
              type="button"
              onClick={cancel}
              disabled={busy}
              className="px-2.5 py-1 rounded-md text-[12px] font-medium bg-interactive-muted text-txt-secondary disabled:opacity-50"
            >
              {t('expressions.cancel')}
            </button>
          </div>
        </div>
      )}

      <div className="mt-5">
        {items.length === 0 ? (
          <p className="text-[13px] text-txt-tertiary">
            {kind === 'emoji' ? t('expressions.emptyEmojis') : t('expressions.emptyStickers')}
          </p>
        ) : (
          <div className="grid grid-cols-6 gap-2">
            {items.map((item) => (
              <div key={item.id} className="relative group">
                <div className="aspect-square rounded-lg bg-surface-elevated flex items-center justify-center p-1.5">
                  <img
                    src={api.uploads.url(item.filename)}
                    alt={item.name}
                    title={kind === 'emoji' ? `:${item.name}:` : item.name}
                    className="max-w-full max-h-full object-contain"
                    loading="lazy"
                  />
                </div>
                <div className="text-[10px] text-txt-tertiary truncate text-center mt-0.5">
                  {kind === 'emoji' ? `:${item.name}:` : item.name}
                </div>
                <button
                  type="button"
                  onClick={() => void remove(item)}
                  title={t('expressions.remove')}
                  aria-label={t('expressions.remove')}
                  className="absolute -top-1 -right-1 w-4 h-4 rounded-full bg-accent-rose text-white text-[10px] leading-none opacity-0 group-hover:opacity-100 transition-opacity"
                >
                  ×
                </button>
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}
