// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/BoxComponent.h"
#include "Components/BillboardComponent.h"

#include "MapEndTrigger.generated.h"

class UShapeComponent;

/**
 * Mapper-facing proxy for the game's Map End Trigger -- the non-lap finish line.
 *
 * This is NOT the game's ALevelDoor. That class is AngelScript
 * (/Script/Angelscript.LevelDoor, itself just an empty subclass of ANewInteractable) and
 * every component, mesh and event lives in BP_LevelDoor, so neither is reachable from a
 * vanilla-UE mapping project.
 *
 * Place this actor instead. At map load the shipped game swaps it for the real
 * BP_LevelDoor at this same transform, copies these properties across, and destroys the
 * proxy. Interacting with the real Map End Trigger stops the timer and completes the map.
 * See Docs/SYNC.md for the swap contract, and the game's Docs/CodeNotes.md [MODPROXY-01]
 * for the rationale.
 *
 * A map needs exactly one Map End Trigger unless it is a lap map, where the final checkpoint
 * closes the run instead.
 */
UCLASS(Blueprintable, meta = (DisplayName = "Map End Trigger"))
class VHOLUME_API AMapEndTrigger : public AActor
{
    GENERATED_BODY()

public:
    AMapEndTrigger();

    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Map End Trigger")
    USceneComponent *Root;

    // The proximity trigger: how close the player must be to interact. The swap copies
    // this extent and relative transform onto BP_LevelDoor's own "Box" component, so
    // sizing it here is the only way a mapper controls interaction range. The Map End Trigger's
    // mesh and visuals still come from BP_LevelDoor.
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Map End Trigger")
    UBoxComponent *TriggerVolume;

    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Map End Trigger")
    UBillboardComponent *Billboard;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Map End Trigger",
              meta = (ToolTip = "Allow interaction regardless of how far away the player is"))
    bool IgnoreInteractionDistance;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Map End Trigger",
              meta = (ToolTip = "Only allow this Map End Trigger to be interacted with once per run"))
    bool bShouldDoOnce;

    // Deliberately NOT mirrored from the game's ANewInteractable:
    //   bLockUntilOwnerInteracts / bOwnerHasInteracted - require an owning NPC to
    //                        unlock the interactable; there are no NPCs in a mod map.
    //   bDidOnce           - runtime state, not authored.
    //   OnInteracted       - a multicast delegate; nothing in a mod map can bind to it
    //                        since mod Blueprints are banned.

private:
    void ApplyCollisionSetup(UShapeComponent *ShapeComp) const;
};
