import { useState, useEffect } from 'react';
import { Spin } from 'antd';
import type { CSSProperties } from 'react';
import { getAccessToken } from '../auth/oidc';

export function useAuthUrl(url: string | null | undefined): string | null {
  const [blobUrl, setBlobUrl] = useState<string | null>(null);

  useEffect(() => {
    if (!url) {
      setBlobUrl(null);
      return;
    }
    let cancelled = false;
    let objectUrl: string | undefined;

    (async () => {
      try {
        const token = await getAccessToken();
        if (cancelled) return;
        const res = await fetch(url, { headers: { Authorization: `Bearer ${token}` } });
        if (cancelled || !res.ok) return;
        const blob = await res.blob();
        if (cancelled) return;
        objectUrl = URL.createObjectURL(blob);
        setBlobUrl(objectUrl);
      } catch {
        // image/resource just won't show
      }
    })();

    return () => {
      cancelled = true;
      setBlobUrl(null);
      if (objectUrl) URL.revokeObjectURL(objectUrl);
    };
  }, [url]);

  return blobUrl;
}

interface AuthImageProps {
  src: string;
  width?: number | string;
  height?: number | string;
  style?: CSSProperties;
  alt?: string;
}

export function AuthImage({ src, width, height, style, alt = '' }: AuthImageProps) {
  const blobUrl = useAuthUrl(src);
  if (!blobUrl) {
    return (
      <div
        style={{
          width,
          height: height ?? width,
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          background: '#f5f5f5',
          borderRadius: style?.borderRadius ?? 0,
        }}
      >
        <Spin size="small" />
      </div>
    );
  }
  return <img src={blobUrl} width={width} height={height} style={style} alt={alt} />;
}

interface AuthIframeProps {
  src: string;
  style?: CSSProperties;
  title?: string;
}

export function AuthIframe({ src, style, title }: AuthIframeProps) {
  const hashIdx = src.indexOf('#');
  const cleanUrl = hashIdx >= 0 ? src.slice(0, hashIdx) : src;
  const hash = hashIdx >= 0 ? src.slice(hashIdx) : '';

  const blobUrl = useAuthUrl(cleanUrl);

  if (!blobUrl) {
    return (
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', ...style }}>
        <Spin />
      </div>
    );
  }
  return <iframe src={`${blobUrl}${hash}`} style={{ border: 'none', ...style }} title={title} />;
}

export async function openAuthUrl(url: string): Promise<void> {
  try {
    const token = await getAccessToken();
    const res = await fetch(url, { headers: { Authorization: `Bearer ${token}` } });
    if (!res.ok) return;
    const blob = await res.blob();
    const blobUrl = URL.createObjectURL(blob);
    window.open(blobUrl, '_blank');
    setTimeout(() => URL.revokeObjectURL(blobUrl), 60_000);
  } catch {
    // silently fail
  }
}
