import React, { MouseEvent, useEffect, useState } from 'react';
import { Box, Spinner, Text, as } from 'folds';
import * as css from './TikTokEmbed.css';
import { openExternalUrl } from '../../utils/tauri';

/**
 * Regex patterns to match TikTok URLs
 */
const TIKTOK_URL_PATTERNS = [
  // Standard tiktok.com/@username/video/VIDEO_ID
  /(?:https?:\/\/)?(?:www\.)?tiktok\.com\/@[\w.-]+\/video\/(\d+)/i,
  // Short vm.tiktok.com/VIDEO_CODE
  /(?:https?:\/\/)?(?:www\.)?vm\.tiktok\.com\/([\w]+)/i,
  // Short vt.tiktok.com/VIDEO_CODE
  /(?:https?:\/\/)?(?:www\.)?vt\.tiktok\.com\/([\w]+)/i,
  // Mobile m.tiktok.com
  /(?:https?:\/\/)?(?:www\.)?m\.tiktok\.com\/v\/(\d+)/i,
];

/**
 * TikTok oEmbed API base
 */
const TIKTOK_OEMBED_API = 'https://www.tiktok.com/oembed';

/**
 * Click handler for external links - uses Tauri shell on desktop/mobile
 */
const handleExternalLinkClick = (e: MouseEvent<HTMLAnchorElement>) => {
  const { href } = e.currentTarget;
  if (href && (href.startsWith('http://') || href.startsWith('https://'))) {
    e.preventDefault();
    openExternalUrl(href);
  }
};

/**
 * Checks if a URL is a TikTok URL
 * @param url The URL to check
 * @returns True if the URL is a TikTok URL
 */
export function isTikTokUrl(url: string): boolean {
  return TIKTOK_URL_PATTERNS.some((pattern) => pattern.test(url));
}

/**
 * Fetches TikTok video metadata using oEmbed API
 * @param url The TikTok video URL
 * @returns Video metadata including title, author, and thumbnail
 */
async function fetchTikTokOEmbed(url: string): Promise<{
  title: string;
  authorName: string;
  authorUrl: string;
  thumbnailUrl: string;
  embedHtml: string;
} | null> {
  try {
    const oembedUrl = `${TIKTOK_OEMBED_API}?url=${encodeURIComponent(url)}`;
    const response = await fetch(oembedUrl);
    if (!response.ok) return null;
    
    const data = await response.json();
    
    return {
      title: data.title || 'TikTok Video',
      authorName: data.author_name || 'Unknown',
      authorUrl: data.author_url || url,
      thumbnailUrl: data.thumbnail_url || '',
      embedHtml: data.html || '',
    };
  } catch {
    return null;
  }
}

type TikTokEmbedState = 
  | { status: 'loading' }
  | { status: 'loaded'; title: string; authorName: string; authorUrl: string; thumbnailUrl: string; embedHtml: string }
  | { status: 'error' };

type TikTokEmbedProps = {
  /** The original TikTok URL */
  url: string;
};

/**
 * TikTok embed component that shows video preview with metadata
 */
export const TikTokEmbed = as<'div', TikTokEmbedProps>(({ url, ...props }, ref) => {
  const [state, setState] = useState<TikTokEmbedState>({ status: 'loading' });
  const [showEmbed, setShowEmbed] = useState(false);

  // Fetch video info on mount
  useEffect(() => {
    let cancelled = false;

    fetchTikTokOEmbed(url).then((info) => {
      if (cancelled) return;
      
      if (info) {
        setState({
          status: 'loaded',
          title: info.title,
          authorName: info.authorName,
          authorUrl: info.authorUrl,
          thumbnailUrl: info.thumbnailUrl,
          embedHtml: info.embedHtml,
        });
      } else {
        setState({ status: 'error' });
      }
    });

    return () => {
      cancelled = true;
    };
  }, [url]);

  // Loading state
  if (state.status === 'loading') {
    return (
      <Box shrink="No" className={css.TikTokEmbed} direction="Column" {...props} ref={ref}>
        <div className={css.TikTokEmbedHeader}>
          <Text
            as="a"
            href={url}
            target="_blank"
            rel="noopener noreferrer"
            size="T200"
            className={css.TikTokEmbedLink}
            onClick={handleExternalLinkClick}
            truncate
          >
            TikTok - Loading...
          </Text>
        </div>
        <Box 
          className={css.TikTokThumbnailContainer} 
          alignItems="Center" 
          justifyContent="Center"
          style={{ background: '#000', display: 'flex' }}
        >
          <Spinner variant="Secondary" size="600" />
        </Box>
      </Box>
    );
  }

  // Error state - show basic link
  if (state.status === 'error') {
    return (
      <Box shrink="No" className={css.TikTokEmbed} direction="Column" {...props} ref={ref}>
        <div className={css.TikTokEmbedHeader}>
          <Text
            as="a"
            href={url}
            target="_blank"
            rel="noopener noreferrer"
            size="T200"
            className={css.TikTokEmbedLink}
            onClick={handleExternalLinkClick}
            truncate
          >
            TikTok Video
          </Text>
        </div>
      </Box>
    );
  }

  // Loaded state - show thumbnail or embed
  if (!showEmbed) {
    return (
      <Box shrink="No" className={css.TikTokEmbed} direction="Column" {...props} ref={ref}>
        <div className={css.TikTokEmbedHeader}>
          <div className={css.TikTokEmbedInfo}>
            <Text
              as="a"
              href={url}
              target="_blank"
              rel="noopener noreferrer"
              size="T300"
              className={css.TikTokEmbedTitle}
              onClick={handleExternalLinkClick}
              truncate
            >
              {state.title}
            </Text>
            <Text
              as="a"
              href={state.authorUrl}
              target="_blank"
              rel="noopener noreferrer"
              size="T200"
              className={css.TikTokEmbedAuthor}
              onClick={handleExternalLinkClick}
              truncate
            >
              {state.authorName}
            </Text>
          </div>
        </div>
        <button
          type="button"
          className={css.TikTokThumbnailButton}
          onClick={() => setShowEmbed(true)}
          aria-label="Load TikTok video"
        >
          {state.thumbnailUrl && (
            <img 
              src={state.thumbnailUrl} 
              alt={state.title}
              className={css.TikTokThumbnail}
              crossOrigin="anonymous"
            />
          )}
        </button>
      </Box>
    );
  }

  // Show embed (using dangerouslySetInnerHTML for TikTok's oEmbed HTML)
  return (
    <Box shrink="No" className={css.TikTokEmbed} direction="Column" {...props} ref={ref}>
      <div className={css.TikTokEmbedHeader}>
        <Text
          as="a"
          href={url}
          target="_blank"
          rel="noopener noreferrer"
          size="T200"
          className={css.TikTokEmbedLink}
          onClick={handleExternalLinkClick}
          truncate
        >
          {state.title}
        </Text>
      </div>
      <div 
        className={css.TikTokEmbedContainer}
        dangerouslySetInnerHTML={{ __html: state.embedHtml }}
      />
    </Box>
  );
});
