import { __ } from '@wordpress/i18n';
import { useState, useEffect, useMemo } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
import apiFetch from '@wordpress/api-fetch';
import { sanitizeSvg } from '../../../components/settings/iconUtils';

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

const getMediaSizeUrl = (media, slug) => {
  if (!media) return '';
  if (slug && media.media_details?.sizes?.[slug]?.source_url) return media.media_details.sizes[slug].source_url;
  return media.source_url || '';
};

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

const normalizeToImage = async (value, size) => {
  if (typeof value === 'number' || (typeof value === 'string' && /^\d+$/.test(value))) {
    const media = await fetchMediaById(Number(value));
    return { url: getMediaSizeUrl(media, size) || media?.source_url || '', alt: media?.alt_text || media?.title?.rendered || '' };
  }
  if (value && typeof value === 'object') {
    if (value.id || value.ID) {
      const media = await fetchMediaById(value.id || value.ID);
      return { url: getMediaSizeUrl(media, size) || media?.source_url || '', alt: value.alt || media?.alt_text || media?.title?.rendered || '' };
    }
    return { url: (value.sizes && value.sizes[size]) || value.url || '', alt: value.alt || value.title || '' };
  }
  if (typeof value === 'string') return { url: value, alt: '' };
  return { url: '', alt: '' };
};

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 image source for the Image block editor preview.
 * Handles: featured image, author avatar, ACF field (post/term/options),
 *          post meta, term meta, library (by ID), external URL,
 *          responsive per-device source overrides, and inline SVG.
 *
 * @param {object}   attributes    - Full block attributes.
 * @param {Function} setAttributes - Block setAttributes.
 */
export function useImageResolution(attributes, setAttributes) {
  const {
    dynamicTag, selectedTag, sourceType, sourceEntity,
    postId, postType, taxonomy, termId, metaKey, acfField,
    imageId, imageUrl, alt, sizeSlug = 'full',
    renderInlineSvg, imageSources,
  } = attributes;

  const [resolvedUrl,       setResolvedUrl]       = useState('');
  const [resolvedAlt,       setResolvedAlt]       = useState('');
  const [inlineSvgMarkup,   setInlineSvgMarkup]   = useState('');
  const [isResolving,       setIsResolving]       = useState(false);
  const [resolvedTabletUrl, setResolvedTabletUrl] = useState('');
  const [resolvedMobileUrl, setResolvedMobileUrl] = useState('');
  const [postLink,          setPostLink]          = useState('#');
  const [termLink,          setTermLink]          = useState('#');
  const [authorLink,        setAuthorLink]        = 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 image flags ─────────────────────────────────────────────────

  const hasDynamic          = !!dynamicTag;
  // Fire featured-image resolution when an explicit dynamic tag includes 'featured_image',
  // OR in the default state where selectedTag = 'featured_image' and no other source is set.
  const isFeaturedDynamic   = (hasDynamic && (dynamicTag || '').includes('featured_image'))
    || (selectedTag === 'featured_image' && !dynamicTag && !imageId && !imageUrl);
  const isAuthorAvatar      = hasDynamic && (selectedTag === 'author_avatar'   || (dynamicTag || '').includes('author_avatar'));
  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 resolveFeaturedImage = async (isCancelled) => {
    const endpoint = buildPostEndpoint();
    if (!endpoint) { if (!isCancelled.v) { setResolvedUrl(''); setResolvedAlt(''); setPostLink('#'); setIsResolving(false); } return; }
    try {
      const post = await apiFetch({ path: endpoint });
      if (isCancelled.v) return;
      setPostLink(post?.link || '#');
      const mediaId = post?.featured_media;
      if (!mediaId) { if (!isCancelled.v) { setResolvedUrl(''); setResolvedAlt(''); setIsResolving(false); } return; }
      const media = await apiFetch({ path: `/wp/v2/media/${mediaId}` });
      if (isCancelled.v) return;
      const url = getMediaSizeUrl(media, sizeSlug) || media?.source_url || '';
      const altText = media?.alt_text || media?.title?.rendered || '';
      if (!isCancelled.v) { setResolvedUrl(url); setResolvedAlt(altText); setIsResolving(false); }
    } catch { if (!isCancelled.v) { setResolvedUrl(''); setResolvedAlt(''); setIsResolving(false); } }
  };

  const resolveAuthorAvatar = async (isCancelled) => {
    const endpoint = buildPostEndpoint();
    if (!endpoint) { if (!isCancelled.v) { setResolvedUrl(''); setResolvedAlt(''); setAuthorLink('#'); setIsResolving(false); } return; }
    try {
      const post = await apiFetch({ path: endpoint });
      if (isCancelled.v) return;
      setPostLink(post?.link || '#');
      const authorId = post?.author;
      if (!authorId) { if (!isCancelled.v) { setResolvedUrl(''); setResolvedAlt(''); setAuthorLink('#'); setIsResolving(false); } return; }
      const user = await apiFetch({ path: `/wp/v2/users/${authorId}?_fields=avatar_urls,link,name` });
      if (isCancelled.v) return;
      const avatars = user?.avatar_urls || {};
      const url     = avatars['96'] || avatars['48'] || avatars['24'] || '';
      const altText = user?.name ? `Avatar of ${user.name}` : __('Author avatar', 'axcelersblocks');
      if (!isCancelled.v) { setResolvedUrl(url); setResolvedAlt(altText); setAuthorLink(user?.link || '#'); setIsResolving(false); }
    } catch { if (!isCancelled.v) { setResolvedUrl(''); setResolvedAlt(''); setAuthorLink('#'); setIsResolving(false); } }
  };

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

  const resolveAcfTerm = async (isCancelled) => {
    if (!taxonomy || !termId || !acfField) { if (!isCancelled.v) { setResolvedUrl(''); setResolvedAlt(''); 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,name` });
      if (isCancelled.v) return;
      setTermLink(term?.link || '#');
      const { url, alt: altText } = await normalizeToImage(term?.acf?.[acfField], sizeSlug);
      if (!isCancelled.v) { setResolvedUrl(url); setResolvedAlt(altText || term?.name || ''); setIsResolving(false); }
    } catch { if (!isCancelled.v) { setResolvedUrl(''); setResolvedAlt(''); setTermLink('#'); setIsResolving(false); } }
  };

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

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

  const resolveLibrary = async (isCancelled) => {
    try {
      const media = await apiFetch({ path: `/wp/v2/media/${imageId}` });
      if (isCancelled.v) return;
      const url = getMediaSizeUrl(media, sizeSlug) || media?.source_url || '';
      if (!isCancelled.v) { setResolvedUrl(url); setResolvedAlt(media?.alt_text || media?.title?.rendered || ''); setIsResolving(false); }
    } catch { if (!isCancelled.v) { setResolvedUrl(''); setResolvedAlt(''); setIsResolving(false); } }
  };

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

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

    if (isFeaturedDynamic)        resolveFeaturedImage(c);
    else if (isAuthorAvatar)      resolveAuthorAvatar(c);
    else if (isTermAcfDynamic)    resolveAcfTerm(c);
    else if (isAcfDynamic)        resolveAcfPost(c);
    else if (isPostMetaDynamic)   resolvePostMeta(c);
    else if (isTermMetaDynamic)   resolveTermMeta(c);
    else if (imageId)             resolveLibrary(c);
    else { setResolvedUrl(imageUrl || ''); setResolvedAlt(alt || ''); setIsResolving(false); }

    return () => { c.v = true; };
  }, [dynamicTag, selectedTag, sourceType, sourceEntity, postId, postType, currentPostId,
      currentPostRestBase, imageId, imageUrl, alt, sizeSlug, taxonomy, termId, metaKey, acfField,
      isFeaturedDynamic, isAuthorAvatar, isAcfDynamic, isPostMetaDynamic, isTermMetaDynamic, isTermAcfDynamic]);

  // ─── Per-device source override resolution ────────────────────────────────

  useEffect(() => {
    const c = { v: false };
    const resolveOverride = async (override) => {
      if (!override || typeof override !== 'object') return '';
      const { imageId: oId, imageUrl: oUrl } = override;
      if (oId) {
        try { const m = await apiFetch({ path: `/wp/v2/media/${oId}` }); return getMediaSizeUrl(m, sizeSlug) || m?.source_url || ''; }
        catch { return ''; }
      }
      return (typeof oUrl === 'string' && oUrl) || '';
    };
    (async () => {
      const [tabletUrl, mobileUrl] = await Promise.all([
        resolveOverride(imageSources?.tablet),
        resolveOverride(imageSources?.mobile),
      ]);
      if (!c.v) { setResolvedTabletUrl(tabletUrl); setResolvedMobileUrl(mobileUrl); }
    })();
    return () => { c.v = true; };
  }, [imageSources?.tablet?.imageId, imageSources?.tablet?.imageUrl, imageSources?.mobile?.imageId, imageSources?.mobile?.imageUrl, sizeSlug]);

  // ─── Inline SVG resolution ────────────────────────────────────────────────

  const isResolvedSvg = useMemo(() => /\.svg(?:[?#].*)?$/i.test(resolvedUrl || ''), [resolvedUrl]);

  useEffect(() => {
    const c = { v: false };
    setInlineSvgMarkup('');
    if (!renderInlineSvg || !isResolvedSvg || !resolvedUrl) return () => { c.v = true; };
    (async () => {
      try {
        const res = await window.fetch(resolvedUrl, { credentials: 'same-origin' });
        if (!res.ok) return;
        const safeSvg = sanitizeSvg(await res.text());
        if (!c.v) { setInlineSvgMarkup(safeSvg); }
      } catch { if (!c.v) { setInlineSvgMarkup(''); } }
    })();
    return () => { c.v = true; };
  }, [renderInlineSvg, isResolvedSvg, resolvedUrl]);

  // ─── Dynamic token label ─────────────────────────────────────────────────

  const dynamicToken = useMemo(() => {
    if (dynamicTag) return dynamicTag;
    if (!hasDynamic) return '';
    switch (selectedTag) {
      case 'featured_image': return '{featured_image}';
      case 'author_avatar':  return '{author_avatar}';
      case 'acf_field':      return `{acf_field:${acfField || 'field'}}`;
      case 'post_meta':      return `{post_meta:${metaKey || 'meta_key'}}`;
      case 'term_meta':      return `{term_meta:${metaKey || 'meta_key'}}`;
      default:               return '{dynamic_image}';
    }
  }, [dynamicTag, hasDynamic, selectedTag, acfField, metaKey]);

  return {
    resolvedUrl, resolvedAlt, isResolving,
    resolvedTabletUrl, resolvedMobileUrl,
    inlineSvgMarkup, isResolvedSvg,
    postLink, termLink, authorLink,
    hasDynamic, isAuthorAvatar, isTermAcfDynamic, isTermMetaDynamic,
    dynamicToken,
  };
}
