'use client';

import React, { useState, useEffect, useMemo } from 'react';
import Image from 'next/image';
import { getGradientUrl } from '../../../utils/gradient-placeholder';
import type { WebsitePhotos } from '../../../types/api/website-photos';
import type { CompanyInformation } from '../../../types/api/company-information';

interface PhotoWithFallbackProps {
  // Generic object with photo_attachments (service, location, team member, blog post, etc.)
  item?: {
    id?: number;
    name?: string;
    title?: string;
    photo_attachments?: Array<{
      id: number;
      featured: boolean;
      photo?: {
        id: number;
        title: string;
        thumbnail_url?: string;
        medium_url?: string;
        large_url?: string;
        original_url?: string;
      };
    }>;
  };
  // Generic photo props (for direct photo URLs; null/undefined = use gradient fallback)
  photoUrl?: string | null;
  photoAlt?: string;
  // Fallback props
  fallbackId?: number | string;
  // Image props
  className?: string;
  alt?: string;
  // SSR data props (optional)
  websitePhotos?: WebsitePhotos | null;
  companyInformation?: CompanyInformation | null;
}

/**
 * Reusable component that displays a photo with automatic fallback to gradient.
 * Supports photo_attachments from any object (services, locations, team members, blog posts, etc.),
 * direct photo URLs, or gradient fallback.
 */
export default function PhotoWithFallback({
  item,
  photoUrl,
  photoAlt,
  fallbackId,
  className = '',
  alt,
  websitePhotos,
  companyInformation,
}: PhotoWithFallbackProps) {
  // Determine the image URL synchronously to avoid gradient flash
  const { imageUrl, imageAlt } = useMemo(() => {
    // Use data from props (SSR) - moved inside useMemo to fix dependency issues
    const isStubMode = companyInformation?.account_status === 'stub';
    const stockPhotos = websitePhotos?.stock_photos || [];

    // Priority 1: Direct photoUrl prop
    if (photoUrl) {
      return { imageUrl: photoUrl, imageAlt: photoAlt || alt || "" };
    }

    // Priority 2: Photo from photo_attachments
    if (item?.photo_attachments && item.photo_attachments.length > 0) {
      const photoAttachments = item.photo_attachments;
      const featuredPhoto = photoAttachments.find((pa) => pa.featured) || photoAttachments[0];
      const photo = featuredPhoto?.photo;
      
      if (photo) {
        const url = photo.large_url || photo.medium_url || photo.thumbnail_url || photo.original_url;
        if (url) {
          return {
            imageUrl: url,
            imageAlt: photo.title || item.name || item.title || alt || "Image"
          };
        }
      }
    }

    // Priority 3: In stub mode, use deterministic stock photo selection based on item id
    if (isStubMode && stockPhotos.length > 0) {
      // Use item id to deterministically select a stock photo (avoid Math.random in render)
      const itemId = item?.id || fallbackId || 1;
      const numericId = typeof itemId === 'number' ? itemId : typeof itemId === 'string' ? parseInt(itemId, 10) || 1 : 1;
      const stockPhotoIndex = numericId % stockPhotos.length;
      const stockPhoto = stockPhotos[stockPhotoIndex];
      if (stockPhoto?.url) {
        return {
          imageUrl: stockPhoto.url,
          imageAlt: stockPhoto.alt || item?.name || item?.title || alt || "Image"
        };
      }
    }

    // Priority 4: Fallback to gradient
    const id = fallbackId || item?.id || 1;
    return {
      imageUrl: getGradientUrl(id),
      imageAlt: item?.name || item?.title || alt || "Image"
    };
  }, [item, photoUrl, photoAlt, fallbackId, alt, websitePhotos, companyInformation]);

  const [isLoaded, setIsLoaded] = useState(false);
  const imgRef = React.useRef<HTMLImageElement>(null);

  // Reset loaded state when image URL changes
  useEffect(() => {
    // Reset loaded state asynchronously to avoid cascading renders
    const resetTimer = setTimeout(() => {
      setIsLoaded(false);
    }, 0);
    
    // Check if image is already loaded (cached)
    const checkTimer = setTimeout(() => {
      if (imgRef.current?.complete && imgRef.current.naturalWidth > 0) {
        setIsLoaded(true);
      }
    }, 0);
    
    return () => {
      clearTimeout(resetTimer);
      clearTimeout(checkTimer);
    };
  }, [imageUrl]);

  // Callback ref to check if image is already loaded (cached images)
  const setImgRef = React.useCallback((img: HTMLImageElement | null) => {
    imgRef.current = img;
    if (img && img.complete && img.naturalWidth > 0) {
      setIsLoaded(true);
    }
  }, []);

  if (!imageUrl) {
    return null;
  }

  return (
    <Image
      ref={setImgRef}
      src={imageUrl}
      alt={imageAlt}
      width={800}
      height={600}
      className={`${className} transition-opacity duration-500 ease-in-out ${
        isLoaded ? 'opacity-100' : 'opacity-0'
      }`}
      onLoad={() => setIsLoaded(true)}
      onError={() => setIsLoaded(true)}
    />
  );
}
