import { useState, useEffect } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
import apiFetch from '@wordpress/api-fetch';

// ─── Helpers ─────────────────────────────────────────────────────────────────

const fetchMediaById = async ( id ) => {
  try { return await apiFetch( { path: `/wp/v2/media/${ id }` } ); } catch { return null; }
};

// Normalise an arbitrary dynamic value (ACF / meta) into a playable video URL +
// its MIME type when we can determine it.
const normalizeToVideo = async ( value ) => {
  if ( typeof value === 'number' || ( typeof value === 'string' && /^\d+$/.test( value ) ) ) {
    const media = await fetchMediaById( Number( value ) );
    return { url: media?.source_url || '', type: media?.mime_type || '' };
  }
  if ( value && typeof value === 'object' ) {
    if ( value.id || value.ID ) {
      const media = await fetchMediaById( value.id || value.ID );
      return { url: media?.source_url || value.url || '', type: media?.mime_type || value.mime_type || '' };
    }
    return { url: value.url || '', type: value.mime_type || value.type || '' };
  }
  if ( typeof value === 'string' ) return { url: value, type: '' };
  return { url: '', type: '' };
};

const getTaxRestBase = async ( slug ) => {
  try {
    const taxData = await apiFetch( { path: '/wp/v2/taxonomies' } );
    return Object.values( taxData ).find( ( x ) => x.slug === slug )?.rest_base || slug;
  } catch { return slug; }
};

// ─── Hook ─────────────────────────────────────────────────────────────────────

/**
 * Resolves the video source (and poster + link) for the Video block editor
 * preview. Handles: media library (by ID), external URL, ACF field
 * (post/term/options), post meta and term meta dynamic sources.
 *
 * @param {object}   attributes    - Full block attributes.
 * @param {Function} setAttributes - Block setAttributes.
 */
export function useVideoResolution( attributes, setAttributes ) {
  const {
    dynamicTag, selectedTag, sourceType, sourceEntity,
    postId, postType, taxonomy, termId, metaKey, acfField,
    videoId, videoUrl, videoType,
    posterId, posterUrl,
  } = attributes;

  const [ resolvedUrl,    setResolvedUrl ]    = useState( '' );
  const [ resolvedType,   setResolvedType ]   = useState( '' );
  const [ resolvedPoster, setResolvedPoster ] = useState( '' );
  const [ isResolving,    setIsResolving ]    = useState( false );
  const [ postLink,       setPostLink ]       = useState( '#' );
  const [ termLink,       setTermLink ]       = useState( '#' );

  const { currentPostId, currentPostType } = useSelect( ( select ) => {
    const { getCurrentPostId, getCurrentPostType } = select( 'core/editor' );
    return { currentPostId: getCurrentPostId(), currentPostType: getCurrentPostType() };
  }, [] );

  const [ currentPostRestBase, setCurrentPostRestBase ] = useState( currentPostType );

  useEffect( () => {
    if ( ! currentPostType ) return;
    apiFetch( { path: '/wp/v2/types' } )
      .then( ( types ) => setCurrentPostRestBase( types[ currentPostType ]?.rest_base || currentPostType ) )
      .catch( () => setCurrentPostRestBase( currentPostType ) );
  }, [ currentPostType ] );

  useEffect( () => {
    if ( sourceType === 'current' && currentPostId && ( postId !== currentPostId.toString() || postType !== currentPostType ) ) {
      setAttributes( { postId: currentPostId.toString(), postType: currentPostType } );
    } else if ( sourceType === 'specific' && postId === ( currentPostId || '' ).toString() ) {
      setAttributes( { postId: '' } );
    }
  }, [ sourceType, currentPostId, currentPostType, postId, postType, setAttributes ] );

  // ─── Dynamic flags ─────────────────────────────────────────────────────────

  const hasDynamic        = !! dynamicTag;
  const isAcfDynamic      = hasDynamic && ( selectedTag === 'acf_field' || ( dynamicTag || '' ).includes( 'acf_field' ) );
  const isPostMetaDynamic = hasDynamic && ( selectedTag === 'post_meta' || ( dynamicTag || '' ).includes( 'post_meta' ) );
  const isTermMetaDynamic = hasDynamic && ( selectedTag === 'term_meta' || ( dynamicTag || '' ).includes( 'term_meta' ) );
  const isTermAcfDynamic  = isAcfDynamic && ( sourceEntity === 'term' || /entity:term/.test( dynamicTag || '' ) );

  const buildPostEndpoint = () =>
    sourceType === 'current' && currentPostId
      ? `/wp/v2/${ currentPostRestBase }/${ currentPostId }`
      : ( sourceType === 'specific' && postId && postType ? `/wp/v2/${ postType }/${ postId }` : null );

  // ─── Resolution functions ──────────────────────────────────────────────────

  const resolveAcfPost = async ( c ) => {
    const endpoint = buildPostEndpoint();
    if ( ! endpoint ) { if ( ! c.v ) { setResolvedUrl( '' ); setResolvedType( '' ); setIsResolving( false ); } return; }
    try {
      const post = await apiFetch( { path: `${ endpoint }?acf_format=standard&_fields=acf,link` } );
      if ( c.v ) return;
      setPostLink( post?.link || '#' );
      const { url, type } = await normalizeToVideo( post?.acf?.[ acfField ] );
      if ( ! c.v ) { setResolvedUrl( url ); setResolvedType( type ); setIsResolving( false ); }
    } catch { if ( ! c.v ) { setResolvedUrl( '' ); setResolvedType( '' ); setIsResolving( false ); } }
  };

  const resolveAcfTerm = async ( c ) => {
    if ( ! taxonomy || ! termId || ! acfField ) { if ( ! c.v ) { setResolvedUrl( '' ); setResolvedType( '' ); setTermLink( '#' ); setIsResolving( false ); } return; }
    try {
      const restBase = await getTaxRestBase( taxonomy );
      const term = await apiFetch( { path: `/wp/v2/${ restBase }/${ termId }?acf_format=standard&_fields=acf,link` } );
      if ( c.v ) return;
      setTermLink( term?.link || '#' );
      const { url, type } = await normalizeToVideo( term?.acf?.[ acfField ] );
      if ( ! c.v ) { setResolvedUrl( url ); setResolvedType( type ); setIsResolving( false ); }
    } catch { if ( ! c.v ) { setResolvedUrl( '' ); setResolvedType( '' ); setTermLink( '#' ); setIsResolving( false ); } }
  };

  const resolvePostMeta = async ( c ) => {
    const endpoint = buildPostEndpoint();
    if ( ! endpoint ) { if ( ! c.v ) { setResolvedUrl( '' ); setResolvedType( '' ); setIsResolving( false ); } return; }
    try {
      const post = await apiFetch( { path: `${ endpoint }?_fields=meta,link&context=edit` } );
      if ( c.v ) return;
      setPostLink( post?.link || '#' );
      const { url, type } = await normalizeToVideo( metaKey ? post?.meta?.[ metaKey ] : null );
      if ( ! c.v ) { setResolvedUrl( url ); setResolvedType( type ); setIsResolving( false ); }
    } catch { if ( ! c.v ) { setResolvedUrl( '' ); setResolvedType( '' ); setIsResolving( false ); } }
  };

  const resolveTermMeta = async ( c ) => {
    if ( ! taxonomy || ! termId || ! metaKey ) { if ( ! c.v ) { setResolvedUrl( '' ); setResolvedType( '' ); setTermLink( '#' ); setIsResolving( false ); } return; }
    try {
      const restBase = await getTaxRestBase( taxonomy );
      const term = await apiFetch( { path: `/wp/v2/${ restBase }/${ termId }?_fields=meta,link&context=edit` } );
      if ( c.v ) return;
      setTermLink( term?.link || '#' );
      const { url, type } = await normalizeToVideo( term?.meta?.[ metaKey ] );
      if ( ! c.v ) { setResolvedUrl( url ); setResolvedType( type ); setIsResolving( false ); }
    } catch { if ( ! c.v ) { setResolvedUrl( '' ); setResolvedType( '' ); setTermLink( '#' ); setIsResolving( false ); } }
  };

  const resolveLibrary = async ( c ) => {
    try {
      const media = await fetchMediaById( videoId );
      if ( c.v ) return;
      setResolvedUrl( media?.source_url || '' );
      setResolvedType( media?.mime_type || videoType || '' );
      setIsResolving( false );
    } catch { if ( ! c.v ) { setResolvedUrl( '' ); setResolvedType( '' ); setIsResolving( false ); } }
  };

  // ─── Main resolution effect ────────────────────────────────────────────────

  useEffect( () => {
    const c = { v: false };
    setIsResolving( true );

    if ( isTermAcfDynamic )       resolveAcfTerm( c );
    else if ( isAcfDynamic )      resolveAcfPost( c );
    else if ( isPostMetaDynamic ) resolvePostMeta( c );
    else if ( isTermMetaDynamic ) resolveTermMeta( c );
    else if ( videoId )           resolveLibrary( c );
    else { setResolvedUrl( videoUrl || '' ); setResolvedType( videoType || '' ); setIsResolving( false ); }

    return () => { c.v = true; };
  }, [ dynamicTag, selectedTag, sourceType, sourceEntity, postId, postType, currentPostId,
       currentPostRestBase, videoId, videoUrl, videoType, taxonomy, termId, metaKey, acfField,
       isAcfDynamic, isPostMetaDynamic, isTermMetaDynamic, isTermAcfDynamic ] );

  // ─── Poster resolution ─────────────────────────────────────────────────────

  useEffect( () => {
    const c = { v: false };
    if ( posterId ) {
      ( async () => {
        const media = await fetchMediaById( posterId );
        if ( ! c.v ) {
          const sizes = media?.media_details?.sizes;
          setResolvedPoster(
            sizes?.large?.source_url || sizes?.medium?.source_url || media?.source_url || ''
          );
        }
      } )();
    } else {
      setResolvedPoster( posterUrl || '' );
    }
    return () => { c.v = true; };
  }, [ posterId, posterUrl ] );

  return {
    resolvedUrl, resolvedType, resolvedPoster, isResolving,
    postLink, termLink,
    hasDynamic, isTermAcfDynamic, isTermMetaDynamic,
  };
}
