using System; using System.Collections; using AppleHills.Data.CardSystem; using Data.CardSystem; using UI.DragAndDrop.Core; using UnityEngine; namespace UI.CardSystem { /// /// Draggable card for album reveal system. /// Handles both tap and drag-hold interactions for revealing cards. /// Auto-snaps to matching album slot on release/tap. /// public class AlbumCardDraggable : DraggableObject { [Header("Album Card Settings")] [SerializeField] private FlippableCard flippableCard; [SerializeField] private float holdRevealDelay = 0.1f; private CardData _cardData; private bool _isRevealed = false; private bool _isDragRevealing = false; private bool _waitingForPlacementTap = false; private Coroutine _holdRevealCoroutine; private bool _isHolding = false; // Track if pointer is currently down // Events public event Action OnCardRevealed; public event Action OnCardPlacedInAlbum; public CardData CardData => _cardData; public bool IsRevealed => _isRevealed; public CardZone Zone => _cardData?.Zone ?? CardZone.AppleHills; protected override void Initialize() { base.Initialize(); // Auto-find FlippableCard if not assigned if (flippableCard == null) { flippableCard = GetComponent(); } } /// /// Setup the card data (stores it but doesn't reveal until tapped/dragged) /// public void SetupCard(CardData data) { _cardData = data; if (flippableCard != null) { flippableCard.SetupCard(data); } } /// /// Reveal the card (flip to show front) /// public void RevealCard() { if (_isRevealed) return; _isRevealed = true; if (flippableCard != null) { flippableCard.FlipToReveal(); } OnCardRevealed?.Invoke(this, _cardData); } /// /// Snap to the matching album slot /// public void SnapToAlbumSlot() { if (_cardData == null) { Debug.LogWarning("[AlbumCardDraggable] Cannot snap to slot - no card data assigned."); return; } // Find all album card slots in the scene AlbumCardSlot[] allSlots = FindObjectsByType(FindObjectsSortMode.None); AlbumCardSlot matchingSlot = null; foreach (var slot in allSlots) { if (slot.CanAcceptCard(_cardData)) { matchingSlot = slot; break; } } if (matchingSlot != null) { // Assign to slot with animation AssignToSlot(matchingSlot, true); // Mark slot as permanently occupied matchingSlot.OnCardPlaced(); // Disable dragging - card is now static in album SetDraggingEnabled(false); // Notify that card was placed // Note: Card already moved from pending to inventory in OnCardRevealed OnCardPlacedInAlbum?.Invoke(this, _cardData); } else { Debug.LogWarning($"[AlbumCardDraggable] Could not find matching slot for card '{_cardData.Name}' (Zone: {_cardData.Zone}, Index: {_cardData.CollectionIndex})"); } } protected override void OnPointerDownHook() { base.OnPointerDownHook(); _isHolding = true; // Start hold-reveal timer if card not yet revealed if (!_isRevealed && _holdRevealCoroutine == null) { _holdRevealCoroutine = StartCoroutine(HoldRevealTimer()); } } protected override void OnPointerUpHook(bool longPress) { base.OnPointerUpHook(longPress); _isHolding = false; // Cancel hold timer if running if (_holdRevealCoroutine != null) { StopCoroutine(_holdRevealCoroutine); _holdRevealCoroutine = null; } // Handle tap (not dragged) if (!_wasDragged) { if (!_isRevealed) { // First tap: reveal the card RevealCard(); _waitingForPlacementTap = true; } else if (_waitingForPlacementTap) { // Second tap: snap to slot _waitingForPlacementTap = false; SnapToAlbumSlot(); } } else if (_isDragRevealing) { // Was drag-revealed, auto-snap on release _isDragRevealing = false; SnapToAlbumSlot(); } } /// /// Coroutine to reveal card after holding for specified duration /// private IEnumerator HoldRevealTimer() { yield return new WaitForSeconds(holdRevealDelay); // If still holding after delay, reveal the card if (!_isRevealed && _isHolding) { RevealCard(); _isDragRevealing = true; Debug.Log("[AlbumCardDraggable] Card revealed via hold"); } _holdRevealCoroutine = null; } } }