import { useState, useCallback, useEffect, useRef } from 'react';
import * as api from '../api';

export default function useShareUrl() {
  const [status, setStatus] = useState<'standby' | 'waiting' | 'done'>('standby');
  const [error, setError] = useState<string>('');
  const [shareUrl, setShareUrl] = useState('');
  const inputRef = useRef<HTMLInputElement | null>(null);

  const setInputRef = useCallback((input: HTMLInputElement | null) => {
    inputRef.current = input;
  }, []);
  const standby = useCallback(() => {
    setStatus('standby');
    setError('');
    setShareUrl('');
  }, []);

  const doCreatePreviewShareUrl = useCallback(async (url: string) => {
    const formData = new FormData();
    formData.append('uri', url);
    // このフックは管理画面バンドル（ACMS.events）が読み込まれない公開到達可能な画面
    // （プレビュー共有ページ等）からも使われうるため、未初期化時はハンドラ0件と同じ
    // 素通し（canceled: false）にフォールバックする
    const gateResult = (await ACMS.events?.emit('preview.share.before', { formData })) ?? {
      canceled: false,
      event: { formData },
    };
    if (gateResult.canceled) {
      return { shareUrl: null, reason: gateResult.reason };
    }
    const shareUrl = await api.createPreviewShareUrl(gateResult.event.formData);
    void ACMS.events?.emit('preview.share.success', { shareUrl });
    return { shareUrl, reason: undefined };
  }, []);

  const createShareUrl = useCallback(
    async (url: string) => {
      setStatus('waiting');
      try {
        const { shareUrl, reason } = await doCreatePreviewShareUrl(url);
        if (shareUrl === null) {
          if (reason) {
            setError(reason);
          }
          setStatus('standby');
          return;
        }
        setShareUrl(shareUrl);
        setStatus('done');
      } catch (error) {
        if (error instanceof Error) {
          setError(error.message);
        }
        setStatus('standby');
      }
    },
    [doCreatePreviewShareUrl]
  );

  useEffect(() => {
    if (status === 'done' && inputRef.current) {
      inputRef.current.focus();
    }
  }, [status]);

  return { status, error, shareUrl, createShareUrl, setInputRef, standby };
}
