//
//  SqueezeCardView.swift
//  Baccarat
//
//  A premium card view that allows for a gestural "squeeze" or "peel" reveal,
//  mimicking a real-world page flip from the corners.
//

import SwiftUI
import CasinoKit

enum SqueezeCorner {
    case bottomLeft
    case bottomRight
}

struct SqueezeCardView: View {
    let card: Card
    let width: CGFloat
    let progress: Double // 0.0 to 1.0
    let corner: SqueezeCorner
    
    private var height: CGFloat {
        width * CasinoDesign.Size.cardAspectRatio
    }
    
    var body: some View {
        ZStack {
            // 1. The front is always at the bottom
            CardFrontView(card: card, width: width, height: height)
            
            // 2. The back is on top, masked by the "unpeeled" area
            CardBackView(width: width, height: height)
                .mask(
                    SqueezeMask(progress: progress, corner: corner)
                        .fill(Style.maskFill)
                )
            
            // 3. The "Fold" - visual affordance of the peeled corner
            if progress > 0 && progress < 1.0 {
                FoldEffect(progress: progress, corner: corner, width: width, height: height)
            }
        }
        .frame(width: width, height: height)
        .clipShape(RoundedRectangle(cornerRadius: width * 0.05))
    }
    
    private enum Style {
        static let maskFill = Color.black
    }
}

/// A mask that represents the part of the card back that is NOT yet peeled.
struct SqueezeMask: Shape {
    var progress: Double
    var corner: SqueezeCorner
    
    var animatableData: Double {
        get { progress }
        set { progress = newValue }
    }
    
    func path(in rect: CGRect) -> Path {
        var path = Path()
        let p = CGFloat(progress)
        
        // Initial state: Full rectangle
        path.addRect(rect)
        
        // Subtraction: The "peeled away" triangle
        var peelPath = Path()
        let size = rect.width * p * 2.0 // Scaling factor for the peel area
        
        switch corner {
        case .bottomRight:
            peelPath.move(to: CGPoint(x: rect.width, y: rect.height))
            peelPath.addLine(to: CGPoint(x: rect.width - size, y: rect.height))
            peelPath.addLine(to: CGPoint(x: rect.width, y: rect.height - size))
            peelPath.closeSubpath()
        case .bottomLeft:
            peelPath.move(to: CGPoint(x: 0, y: rect.height))
            peelPath.addLine(to: CGPoint(x: size, y: rect.height))
            peelPath.addLine(to: CGPoint(x: 0, y: rect.height - size))
            peelPath.closeSubpath()
        }
        
        // We use a "subtract" logic by drawing the full rect then "erasing" the peel
        // In SwiftUI Shape, we just return the "remaining" area.
        // For simplicity, we'll construct the remaining polygon.
        
        var remainingPath = Path()
        switch corner {
        case .bottomRight:
            remainingPath.move(to: .zero)
            remainingPath.addLine(to: CGPoint(x: rect.width, y: 0))
            remainingPath.addLine(to: CGPoint(x: rect.width, y: max(0, rect.height - size)))
            remainingPath.addLine(to: CGPoint(x: max(0, rect.width - size), y: rect.height))
            remainingPath.addLine(to: CGPoint(x: 0, y: rect.height))
            remainingPath.closeSubpath()
        case .bottomLeft:
            remainingPath.move(to: .zero)
            remainingPath.addLine(to: CGPoint(x: rect.width, y: 0))
            remainingPath.addLine(to: CGPoint(x: rect.width, y: rect.height))
            remainingPath.addLine(to: CGPoint(x: min(rect.width, size), y: rect.height))
            remainingPath.addLine(to: CGPoint(x: 0, y: max(0, rect.height - size)))
            remainingPath.closeSubpath()
        }
        
        return remainingPath
    }
}

/// The visual effect of the folded corner, including shadows and highlight.
struct FoldEffect: View {
    let progress: Double
    let corner: SqueezeCorner
    let width: CGFloat
    let height: CGFloat
    
    var body: some View {
        let size = width * CGFloat(progress) * 2.0
        let foldWidth = size * 0.5
        
        ZStack {
            // Fold shadow cast on the front of the card
            FoldShadow(size: size, corner: corner)
                .opacity(0.3 * (1.0 - progress))
            
            // The fold itself (the "back" of the peel)
            FoldShape(size: size, corner: corner)
                .fill(
                    LinearGradient(
                        colors: [.white.opacity(0.8), .gray.opacity(0.3)],
                        startPoint: corner == .bottomRight ? .bottomTrailing : .bottomLeading,
                        endPoint: corner == .bottomRight ? .topLeading : .topTrailing
                    )
                )
                .overlay(
                    FoldShape(size: size, corner: corner)
                        .stroke(Color.white.opacity(0.5), lineWidth: 0.5)
                )
        }
    }
}

struct FoldShape: Shape {
    let size: CGFloat
    let corner: SqueezeCorner
    
    func path(in rect: CGRect) -> Path {
        var path = Path()
        // A triangle representing the folded over piece
        switch corner {
        case .bottomRight:
            path.move(to: CGPoint(x: rect.width - size/2, y: rect.height - size/2))
            path.addLine(to: CGPoint(x: rect.width - size, y: rect.height))
            path.addLine(to: CGPoint(x: rect.width, y: rect.height - size))
            path.closeSubpath()
        case .bottomLeft:
            path.move(to: CGPoint(x: size/2, y: rect.height - size/2))
            path.addLine(to: CGPoint(x: size, y: rect.height))
            path.addLine(to: CGPoint(x: 0, y: rect.height - size))
            path.closeSubpath()
        }
        return path
    }
}

struct FoldShadow: View {
    let size: CGFloat
    let corner: SqueezeCorner
    
    var body: some View {
        FoldShape(size: size * 1.1, corner: corner)
            .fill(Color.black)
            .blur(radius: 4)
            .offset(x: corner == .bottomRight ? -2 : 2, y: -2)
    }
}

#Preview {
    ZStack {
        Color.CasinoTable.backgroundDark.ignoresSafeArea()
        
        VStack(spacing: 60) {
            SqueezeCardView(card: Card(suit: .spades, rank: .ace), width: 140, progress: 0.1, corner: .bottomRight)
            SqueezeCardView(card: Card(suit: .hearts, rank: .king), width: 140, progress: 0.3, corner: .bottomRight)
            SqueezeCardView(card: Card(suit: .diamonds, rank: .seven), width: 140, progress: 0.5, corner: .bottomLeft)
        }
    }
}
