using System.Collections.Generic;
using System.Linq;
using CardSystem.UI.Component;
using Core;
using Minigames.StatueDressup.Controllers;
using Minigames.StatueDressup.PhotoGallery;
using UnityEngine;
using Utils;
namespace CardSystem.Controllers
{
///
/// Controller for managing photo slots across album pages.
/// Discovers all AlbumPhotoSlot prefabs in scene, groups by CaptureType,
/// and populates with latest photos from PhotoManager.
///
public class AlbumPhotoPageController
{
private readonly GameObject _backdrop;
private readonly Transform _enlargedContainer;
private readonly float _animationDuration;
private Dictionary> _slotsByType;
private Dictionary _photoAssignments; // Maps each slot to its assigned photoId
private PhotoEnlargeController _enlargeController;
private bool _isInitialized;
public bool IsInitialized => _isInitialized;
///
/// Constructor
///
/// Backdrop for photo enlargement
/// Container for enlarged photos
/// Duration for enlarge/shrink animations
public AlbumPhotoPageController(GameObject backdrop, Transform enlargedContainer, float animationDuration = 0.3f)
{
_backdrop = backdrop;
_enlargedContainer = enlargedContainer;
_animationDuration = animationDuration;
// Initialize data structures
_photoAssignments = new Dictionary();
// Initialize enlarge controller
_enlargeController = new PhotoEnlargeController(backdrop, enlargedContainer, animationDuration);
Logging.Debug("[AlbumPhotoPageController] Controller created");
}
///
/// Discover all photo slots in scene and populate them with latest photos
///
public void Initialize()
{
Logging.Debug("[AlbumPhotoPageController] Initialize() called");
if (_isInitialized)
{
Logging.Warning("[AlbumPhotoPageController] Already initialized");
return;
}
// Find all photo slots in scene
AlbumPhotoSlot[] allSlots = Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None);
Logging.Debug($"[AlbumPhotoPageController] Found {(allSlots != null ? allSlots.Length : 0)} AlbumPhotoSlot components in scene");
if (allSlots == null || allSlots.Length == 0)
{
Logging.Warning("[AlbumPhotoPageController] No AlbumPhotoSlot components found in scene");
_isInitialized = true;
return;
}
// Group slots by CaptureType
_slotsByType = new Dictionary>();
foreach (var slot in allSlots)
{
Logging.Debug($"[AlbumPhotoPageController] Processing slot: {slot.name}, CaptureType: {slot.CaptureType}");
if (!_slotsByType.ContainsKey(slot.CaptureType))
{
_slotsByType[slot.CaptureType] = new List();
}
_slotsByType[slot.CaptureType].Add(slot);
// Initialize the slot with this controller
slot.Initialize(this);
}
Logging.Debug($"[AlbumPhotoPageController] Found {allSlots.Length} photo slots across {_slotsByType.Count} capture types");
// Log slot counts per type
foreach (var kvp in _slotsByType)
{
Logging.Debug($"[AlbumPhotoPageController] {kvp.Key}: {kvp.Value.Count} slots");
}
// Prepare photo assignments (but don't populate yet - slots will request when they become active)
Logging.Debug("[AlbumPhotoPageController] Starting PreparePhotoAssignments()");
PreparePhotoAssignments();
_isInitialized = true;
Logging.Debug("[AlbumPhotoPageController] Initialize() complete");
}
///
/// Prepare photo assignments for all discovered slots.
/// Slots will request their assigned photo when they become active.
///
private void PreparePhotoAssignments()
{
_photoAssignments.Clear();
foreach (var kvp in _slotsByType)
{
CaptureType captureType = kvp.Key;
List slots = kvp.Value;
// Get latest photos for this capture type
int slotCount = slots.Count;
List photoIds = PhotoManager.GetPhotoIds(captureType, slotCount);
Logging.Debug($"[AlbumPhotoPageController] Preparing assignments for {slotCount} slots of {captureType} with {photoIds.Count} photos");
// Build assignment map
for (int i = 0; i < slots.Count; i++)
{
string photoId = (i < photoIds.Count) ? photoIds[i] : null;
_photoAssignments[slots[i]] = photoId;
if (photoId != null)
{
Logging.Debug($"[AlbumPhotoPageController] Slot {i} ({slots[i].name}) -> {photoId}");
}
else
{
Logging.Debug($"[AlbumPhotoPageController] Slot {i} ({slots[i].name}) -> (no photo)");
}
}
}
Logging.Debug($"[AlbumPhotoPageController] Prepared {_photoAssignments.Count} photo assignments");
}
///
/// Get the assigned photo ID for a specific slot.
/// Called by slots when they become active.
///
public string GetAssignedPhotoId(AlbumPhotoSlot slot)
{
if (slot == null || _photoAssignments == null)
{
return null;
}
if (_photoAssignments.TryGetValue(slot, out string photoId))
{
return photoId;
}
Logging.Warning($"[AlbumPhotoPageController] Slot {slot.name} not found in assignments");
return null;
}
///
/// Refresh photos for a specific capture type (call after new photo is taken)
///
public void RefreshPhotosForType(CaptureType captureType)
{
if (!_isInitialized || !_slotsByType.ContainsKey(captureType))
{
return;
}
List slots = _slotsByType[captureType];
// Clear existing slots
foreach (var slot in slots)
{
slot.Clear();
}
// Get latest photos and rebuild assignments
int slotCount = slots.Count;
List photoIds = PhotoManager.GetPhotoIds(captureType, slotCount);
Logging.Debug($"[AlbumPhotoPageController] Refreshing assignments for {slotCount} slots of {captureType} with {photoIds.Count} photos");
// Update assignments
for (int i = 0; i < slots.Count; i++)
{
string photoId = (i < photoIds.Count) ? photoIds[i] : null;
_photoAssignments[slots[i]] = photoId;
}
// Trigger slots to reload (they will request their new assignment when they become active)
foreach (var slot in slots)
{
if (slot.gameObject.activeInHierarchy)
{
// If slot is currently active, immediately populate with new assignment
slot.PopulateWithPhoto(GetAssignedPhotoId(slot));
}
}
}
///
/// Refresh all photo slots (call after album is opened to show latest photos)
///
public void RefreshAllPhotos()
{
if (!_isInitialized)
{
return;
}
foreach (var captureType in _slotsByType.Keys.ToList())
{
RefreshPhotosForType(captureType);
}
Logging.Debug("[AlbumPhotoPageController] All photos refreshed");
}
///
/// Enlarge a photo (called by AlbumPhotoSlot)
///
public void EnlargePhoto(AlbumPhotoSlot slot, Texture2D fullSizeTexture)
{
if (_enlargeController == null)
{
Logging.Error("[AlbumPhotoPageController] Enlarge controller not initialized");
return;
}
// If already enlarged, shrink it
if (_enlargeController.IsPhotoEnlarged)
{
_enlargeController.ShrinkPhoto();
return;
}
if (fullSizeTexture == null)
{
Logging.Error($"[AlbumPhotoPageController] Cannot enlarge null texture for slot {slot.PhotoId}");
return;
}
Logging.Debug($"[AlbumPhotoPageController] Enlarging photo: {slot.PhotoId} from {slot.CaptureType}");
// Default enlarged scale (can be made configurable)
float enlargedScale = 2.5f;
// Enlarge using the controller
_enlargeController.EnlargePhoto(slot, slot.gameObject, fullSizeTexture, enlargedScale);
}
///
/// Get photo count for a specific capture type
///
public int GetPhotoCount(CaptureType captureType)
{
return PhotoManager.GetPhotoCount(captureType);
}
///
/// Get slot count for a specific capture type
///
public int GetSlotCount(CaptureType captureType)
{
if (!_isInitialized || !_slotsByType.ContainsKey(captureType))
{
return 0;
}
return _slotsByType[captureType].Count;
}
///
/// Cleanup when album is closed
///
public void Cleanup()
{
if (_enlargeController != null)
{
_enlargeController.Cleanup();
}
// Clear all slots
if (_slotsByType != null)
{
foreach (var slots in _slotsByType.Values)
{
foreach (var slot in slots)
{
if (slot != null)
{
slot.Clear();
}
}
}
}
Logging.Debug("[AlbumPhotoPageController] Cleanup complete");
}
}
}