using Manager.DTOs; using ManagerService.DTOs; using ManagerService.Helpers; using NetTopologySuite.Geometries; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; namespace ManagerService.Data.SubSection { /// /// Section map /// public class SectionMap : Section { public int MapZoom { get; set; } // Default = 18 public MapTypeApp? MapMapType { get; set; } // Default = Hybrid for Google public MapTypeMapBox? MapTypeMapbox { get; set; } // Default = standard for MapBox public MapProvider? MapMapProvider { get; set; } // Default = Google public List MapPoints { get; set; } public string MapResourceId { get; set; } public Resource MapResource { get; set; } // Icon [Required] [Column(TypeName = "jsonb")] public List MapCategories { get; set; } public string MapCenterLatitude { get; set; } // Center on public string MapCenterLongitude { get; set; } // Center on public MapDTO ToDTO() { return new MapDTO() { id = Id, label = Label, title = Title.ToList(), description = Description.ToList(), order = Order, type = Type, imageId = ImageId, imageSource = ImageSource, configurationId = ConfigurationId, isSubSection = IsSubSection, parentId = ParentId, dateCreation = DateCreation, instanceId = InstanceId, isBeacon = IsBeacon, beaconId = BeaconId, latitude = Latitude, longitude = Longitude, meterZoneGPS = MeterZoneGPS, zoom = MapZoom, mapType = MapMapType, mapTypeMapbox = MapTypeMapbox, mapProvider = MapMapProvider, iconResourceId = MapResourceId, categories = MapCategories, centerLatitude = MapCenterLatitude, centerLongitude = MapCenterLongitude }; } } public class GeoPoint { [Required] public int? Id { get; set; } [Required] [Column(TypeName = "jsonb")] public List Title { get; set; } [Required] [Column(TypeName = "jsonb")] public List Description { get; set; } [Required] [Column(TypeName = "jsonb")] public List Contents { get; set; } public int? CategorieId { get; set; } public Geometry Geometry { get; set; } public string PolyColor { get; set; } // color of the polyline or polygon public string ImageResourceId { get; set; } public string ImageUrl { get; set; } [Required] [Column(TypeName = "jsonb")] public List Schedules { get; set; } [Required] [Column(TypeName = "jsonb")] public List Prices { get; set; } [Required] [Column(TypeName = "jsonb")] public List Phone { get; set; } [Required] [Column(TypeName = "jsonb")] public List Email { get; set; } [Required] [Column(TypeName = "jsonb")] public List Site { get; set; } public string? SectionMapId { get; set; } [ForeignKey(nameof(SectionMapId))] public SectionMap? SectionMap { get; set; } public string? SectionEventId { get; set; } [ForeignKey(nameof(SectionEventId))] public SectionEvent? SectionEvent { get; set; } public GeoPointDTO ToDTO() { return new GeoPointDTO { id = Id, title = Title, description = Description, contents = Contents, categorieId = CategorieId, geometry = Geometry != null ? new GeometryDTO { type = Geometry.GeometryType, coordinates = Geometry.Coordinates, } : null, polyColor = PolyColor, imageResourceId = ImageResourceId, imageUrl = ImageUrl, schedules = Schedules, prices = Prices, phone = Phone, email = Email, site = Site, sectionMapId = SectionMapId, sectionEventId = SectionEventId }; } } public class GuidedPath // Parcours { [Key] public string Id { get; set; } [Required] public string InstanceId { get; set; } [Required] [Column(TypeName = "jsonb")] public List Title { get; set; } [Column(TypeName = "jsonb")] public List Description { get; set; } // Lié à une carte (optionnel) public string? SectionMapId { get; set; } [ForeignKey("SectionMapId")] public SectionMap? SectionMap { get; set; } // Lié à un événement (optionnel) public string? SectionEventId { get; set; } [ForeignKey("SectionEventId")] public SectionEvent? SectionEvent { get; set; } // Type de parcours public bool IsLinear { get; set; } = true; // Avancer dans l’ordre - Ordre obligatoire public bool RequireSuccessToAdvance { get; set; } = false; // Par exemple: résoudre une énigme public bool HideNextStepsUntilComplete { get; set; } = false; // Étapes cachées tant que non terminées public int Order { get; set; } public List Steps { get; set; } = new(); public GuidedPathDTO ToDTO() { return new GuidedPathDTO { id = Id, instanceId = InstanceId, title = Title, description = Description, sectionMapId = SectionMapId, sectionEventId = SectionEventId, isLinear = IsLinear, requireSuccessToAdvance = RequireSuccessToAdvance, hideNextStepsUntilComplete = HideNextStepsUntilComplete, order = Order, steps = Steps?.Select(s => s.ToDTO()).ToList() }; } public GuidedPath FromDTO(GuidedPathDTO dto) { if (dto == null) return null; InstanceId = dto.instanceId; Title = dto.title ?? new List(); Description = dto.description ?? new List(); SectionMapId = dto.sectionMapId; SectionEventId = dto.sectionEventId; IsLinear = dto.isLinear; RequireSuccessToAdvance = dto.requireSuccessToAdvance; HideNextStepsUntilComplete = dto.hideNextStepsUntilComplete; Order = dto.order; //Steps = dto.Steps?.Select(s => s.FromDTO()).ToList() ?? new List() // Other method return this; } } public class GuidedStep // Étape d’un parcours { [Key] public string Id { get; set; } [Required] public string GuidedPathId { get; set; } [ForeignKey("GuidedPathId")] public GuidedPath GuidedPath { get; set; } public int Order { get; set; } [Required] [Column(TypeName = "jsonb")] public List Title { get; set; } [Column(TypeName = "jsonb")] public List Description { get; set; } public Geometry Geometry { get; set; } // Polygon ou centre du cercle public double? ZoneRadiusMeters { get; set; } // Optionnel, utile si zone cercle ou point public string ImageUrl { get; set; } public int? TriggerGeoPointId { get; set; } // Lieu lié à l'étape et genre si on veut plus d'info ou pourrait afficher les infos du geopoint. [ForeignKey("TriggerGeoPointId")] public GeoPoint TriggerGeoPoint { get; set; } public bool IsHiddenInitially { get; set; } = false; // Exemple pour escape game public List? QuizQuestions { get; set; } // One or multiple question // Option : si true, cette étape a un compte à rebourds, false sinon public bool IsStepTimer { get; set; } = false; // Option : si true, cette étape doit être validée avant de passer à la suivante public bool IsStepLocked { get; set; } = true; // Timer en secondes (durée max pour valider cette étape, optionnel) public int? TimerSeconds { get; set; } // Option : message ou action à effectuer si timer expire (ex: afficher aide, fin du jeu...) [Column(TypeName = "jsonb")] public List TimerExpiredMessage { get; set; } public GuidedStepDTO ToDTO() { return new GuidedStepDTO { id = Id, guidedPathId = GuidedPathId, order = Order, title = Title, description = Description, geometry = Geometry.ToDto(), zoneRadiusMeters = ZoneRadiusMeters, imageUrl = ImageUrl, triggerGeoPointId = TriggerGeoPointId, triggerGeoPoint = TriggerGeoPoint.ToDTO(), isHiddenInitially = IsHiddenInitially, isStepTimer = IsStepTimer, isStepLocked = IsStepLocked, timerSeconds = TimerSeconds, timerExpiredMessage = TimerExpiredMessage, quizQuestions = QuizQuestions }; } public GuidedStep FromDTO(GuidedStepDTO dto) { if (dto == null) return null; GuidedPathId = dto.guidedPathId; Title = dto.title ?? new List(); Description = dto.description ?? new List(); Geometry = dto.geometry.FromDto(); ZoneRadiusMeters = dto.zoneRadiusMeters; ImageUrl = dto.imageUrl; TriggerGeoPointId = dto.triggerGeoPointId; IsHiddenInitially = dto.isHiddenInitially; IsStepTimer = dto.isStepTimer; IsStepLocked = dto.isStepLocked; TimerSeconds = dto.timerSeconds; TimerExpiredMessage = dto.timerExpiredMessage ?? new List(); Order = dto.order; QuizQuestions = dto.quizQuestions; return this; } } // SectionMap "normal" comme avant => Via geopoints. Si il y a des guidedPath lié à la sectionMap alors il y a un parcours lié à la sectionMap, tu peux aussi avoir des geopoints classique mis là + des parcours. et aussi lier un guidedstep à un geopoint (pour le trigger et aussi pour "afficher plus") // parcours libre /*{ "IsLinear": false, "RequireSuccessToAdvance": false, "HideNextStepsUntilComplete": false, "Steps": [ { "Title": "La tour", "GeoPointId": "...", "IsOptional": false }, { "Title": "Les jardins", "GeoPointId": "...", "IsOptional": false } ] }*/ // Parcours escape game /*{ "IsLinear": true, "RequireSuccessToAdvance": true, "HideNextStepsUntilComplete": true, "Steps": [ { "Title": "Enigme 1", "RiddleQuestion": "Quel est le code ?", "RiddleAnswer": "1234" }, { "Title": "Enigme 2", "RiddleQuestion": "Combien de colonnes ?", "RiddleAnswer": "6" } ] }*/ /* * { "Id": "escape001", "IsLinear": true, "RequireSuccessToAdvance": true, "HideNextStepsUntilComplete": true, "Steps": [ { "Id": "step1", "Title": [{ "Lang": "fr", "Text": "Enigme 1" }], "TriggerGeoPoint": { "GeometryType": "Circle", "Coordinates": [{ "Latitude": 49.5, "Longitude": 5.9 }], "ZoneRadiusMeters": 30 }, "ValidationQuestion": [{ "Lang": "fr", "Text": "Quel est le code secret ?" }], "ExpectedAnswer": [{ "Lang": "fr", "Text": "1234" }], "IsStepTimer": true, "TimerSeconds": 300, "IsStepLocked": true }, { "Id": "step2", "Title": [{ "Lang": "fr", "Text": "Enigme 2" }], "TriggerGeoPoint": { "GeometryType": "Point", "Coordinates": [{ "Latitude": 49.51, "Longitude": 5.91 }] }, "ValidationQuestion": [{ "Lang": "fr", "Text": "Combien de colonnes ?" }], "ExpectedAnswer": [{ "Lang": "fr", "Text": "6" }], "IsStepTimer": false, "IsStepLocked": true } ] } */ }