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

/**
 * Resolves the button's href from dynamic attributes.
 * The button block uses dynamic tags purely for URL resolution (not text display).
 *
 * @param {object}   attributes    - Full block attributes.
 * @param {Function} setAttributes - Block setAttributes.
 * @returns {{ resolvedHref: string }}
 */
export function useButtonLink(attributes, setAttributes) {
  const {
    dynamicTag, selectedTag = 'post_permalink',
    sourceEntity = 'post', sourceType = 'current',
    postId, postType, taxonomy, termId,
    linkOption = 'none', metaKey = '', acfField = '', acfScope = 'entity',
    customLink,
  } = attributes;

  const [postLink,      setPostLink]      = useState('#');
  const [authorLink,    setAuthorLink]    = useState('#');
  const [termLink,      setTermLink]      = useState('#');
  const [metaBasedLink, setMetaBasedLink] = useState('#');

  const taxonomiesRef = useRef(null);

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

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

  // Map current post type to its REST base
  useEffect(() => {
    if (!currentPostType) return;
    apiFetch({ path: '/wp/v2/types' })
      .then((types) => setCurrentPostRestBase(types[currentPostType]?.rest_base || currentPostType))
      .catch(() => setCurrentPostRestBase(currentPostType));
  }, [currentPostType]);

  // Keep postId / postType attributes in sync with editor's current post
  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]);

  // ─── Resolve post / author link ───────────────────────────────────────────

  useEffect(() => {
    if (!dynamicTag || sourceEntity !== 'post') { setPostLink('#'); setAuthorLink('#'); return; }

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

    if (!endpoint) { setPostLink('#'); setAuthorLink('#'); return; }

    apiFetch({ path: endpoint })
      .then((data) => {
        setPostLink(data?.link || '#');
        if (selectedTag === 'post_author' && data?.author) {
          apiFetch({ path: `/wp/v2/users/${data.author}` })
            .then((author) => setAuthorLink(author?.link || '#'))
            .catch(() => setAuthorLink('#'));
        }
      })
      .catch(() => { setPostLink('#'); setAuthorLink('#'); });
  }, [dynamicTag, selectedTag, sourceType, postId, postType, currentPostId, currentPostRestBase]);

  // ─── Resolve term link ────────────────────────────────────────────────────

  const loadTaxonomies = () => {
    if (taxonomiesRef.current) return Promise.resolve(taxonomiesRef.current);
    return apiFetch({ path: '/wp/v2/taxonomies' })
      .then((data) => {
        const list = Object.values(data)
          .filter((t) => t?.rest_base)
          .map((t) => ({ slug: t.slug, restBase: t.rest_base }));
        taxonomiesRef.current = list;
        return list;
      })
      .catch(() => { taxonomiesRef.current = []; return []; });
  };

  useEffect(() => {
    if (!dynamicTag || linkOption !== 'term' || sourceEntity !== 'term' || !taxonomy || !termId) {
      setTermLink('#');
      return;
    }
    loadTaxonomies().then((list) => {
      const tax = list.find((t) => t.slug === taxonomy);
      if (!tax?.restBase) { setTermLink('#'); return; }
      apiFetch({ path: `/wp/v2/${tax.restBase}/${termId}` })
        .then((term) => setTermLink(term?.link || '#'))
        .catch(() => setTermLink('#'));
    });
  }, [dynamicTag, linkOption, sourceEntity, taxonomy, termId]);

  // ─── Resolve meta / ACF URL ───────────────────────────────────────────────

  useEffect(() => {
    const isACFEntity = selectedTag === 'acf_field' && (acfScope || 'entity') === 'entity' && acfField;
    const isPostMeta  = selectedTag === 'post_meta'  && metaKey;
    if (!dynamicTag || (!isACFEntity && !isPostMeta)) { setMetaBasedLink('#'); return; }

    const resolveForPost = () => {
      const endpoint = sourceType === 'current' && currentPostId
        ? `/wp/v2/${currentPostRestBase}/${currentPostId}`
        : (sourceType === 'specific' && postId && postType)
          ? `/wp/v2/${postType}/${postId}`
          : null;
      if (!endpoint) { setMetaBasedLink('#'); return; }
      apiFetch({ path: endpoint })
        .then((data) => {
          const url = isPostMeta
            ? (data?.meta?.[metaKey] || '#')
            : (data?.acf?.[acfField] || '#');
          setMetaBasedLink(typeof url === 'string' ? url : '#');
        })
        .catch(() => setMetaBasedLink('#'));
    };

    const resolveForTerm = () => {
      if (!taxonomy || !termId) { setMetaBasedLink('#'); return; }
      loadTaxonomies().then((list) => {
        const tax = list.find((t) => t.slug === taxonomy);
        if (!tax?.restBase) { setMetaBasedLink('#'); return; }
        apiFetch({ path: `/wp/v2/${tax.restBase}/${termId}` })
          .then((data) => {
            const url = isPostMeta
              ? (data?.meta?.[metaKey] || '#')
              : (data?.acf?.[acfField] || '#');
            setMetaBasedLink(typeof url === 'string' ? url : '#');
          })
          .catch(() => setMetaBasedLink('#'));
      });
    };

    if (sourceEntity === 'term') resolveForTerm(); else resolveForPost();
  }, [dynamicTag, selectedTag, metaKey, acfField, acfScope, sourceEntity,
      sourceType, currentPostId, currentPostRestBase, postId, postType, taxonomy, termId]);

  // ─── Compute final href ───────────────────────────────────────────────────

  let resolvedHref = customLink || '#';
  if (dynamicTag) {
    if (selectedTag === 'post_author' && linkOption === 'author') {
      resolvedHref = authorLink || '#';
    } else if (linkOption === 'term') {
      resolvedHref = termLink || '#';
    } else if (selectedTag === 'post_meta' || (selectedTag === 'acf_field' && (acfScope || 'entity') === 'entity')) {
      resolvedHref = metaBasedLink || '#';
    } else if (linkOption === 'post' || selectedTag === 'post_permalink') {
      resolvedHref = postLink || '#';
    }
  }

  return { resolvedHref };
}
