using Fitness_core_BE.DTOs.Meal; using Fitness_core_BE.DTOs.Workout; using Fitness_core_BE.Models; namespace Fitness_core_BE.Interfaces { public interface ICustomerRepository { Task GetCustomerById(Guid customerId); // Central dedupe lookup: is this phone/email an existing Customer (active or not)? // Matches on Customer's own PrimaryPH/SecondaryPH/Email as well as the linked User's // PhoneNumber/Email, and deliberately does not filter by IsActive — an inactive // customer's identity still counts as "already exists" so no duplicate central // record gets created for the same person. Task GetCustomerByIdentifier(string identifier); Task CreateCustomer(Customer customer); Task UpdateCustomer(Guid customerId, Customer customer); /// /// Ensures this tenant DB has the TenantCustomerLink anchor row every tenant-side /// FK (subscriptions, cards, attendance, ...) points at. Idempotent: refreshes the /// cached display fields and re-activates the link when the row already exists, so /// it is safe to call on both first-time creation and re-enrolment. /// Task EnsureTenantCustomerLink(Customer customer); // Own-gym duplicate check: does THIS tenant already have an active customer whose // cached phone/email matches? Scoped by construction (TenantDbContext is already this // gym's own schema) -- no clientId parameter needed. Task FindActiveLinkByIdentifierAsync(string identifier); Task DeleteCustomer(Guid customerId); // Client-initiated delete: deactivates only this customer's presence at the calling // client's gym (subscriptions/members/plan assignments scoped to clientId). The shared // central Customer record is never touched — the same person may be an active member // at a different gym. Task DeactivateCustomerForClient(Guid customerId, Guid clientId); Task> GetAllClentShopsAsync(); Task GetCustomerClientId(Guid customerId); Task GetActiveMealPlanAsync(Guid? clientId = null, Guid? cusId = null); Task GetActiveWorkOutAsync(Guid? clientId = null, Guid? cusId = null); Task> GetFollowedMealPlansByCustomerIdAsync(Guid customerId); // All of the customer's own AI-generated meal plans (IsTemplate=false), regardless of // whether they're currently followed — distinct from admin/client-authored templates. Task> GetMyMealPlansByCustomerIdAsync(Guid customerId); Task GetMealPlanByIdForCustomerAsync(Guid mealPlanId); Task> GetFollowedWorkoutPlansByCustomerIdAsync(Guid customerId); Task> GetMyWorkoutPlansByCustomerIdAsync(Guid customerId); Task GetWorkoutPlanByIdForCustomerAsync(Guid workoutPlanId, Guid customerId); Task FollowMealPlan(Guid customerId, Guid mealPlanId); Task FollowWorkoutPlan(Guid customerId, Guid workOutPlanId); // Active (IsActive) CustomerWorkout join row for this customer + plan, regardless of // whether it's the currently-followed one — used to scope per-exercise completion. Task GetActiveCustomerWorkoutAsync(Guid customerId, Guid workoutPlanId); Task SetExerciseCompletionAsync(Guid customerWorkoutId, Guid workoutExerciseId, bool completed); Task GetClientBizDataAsync(Guid ClientBizId); Task GetCusHealthRec(Guid cusID); Task> GetCusProgressRec(Guid cusID); Task CreateCusHealthRecAsync(CustomerHealth customerHealth); Task UpdateCusHealthRecAsync(CustomerHealth NewcustomerHealth); Task CreateCustomerTargetAsync(CustomerTarget customerTarget); Task GetLatestCustomerTargetAsync(Guid customerId); Task> GetCustomerTargetsAsync(Guid customerId); Task UpdateLatestCustomerTargetNutritionsAsync(Guid customerId, string predictedNutritionsJson); Task>> GetCustomerProgressGroupedByGoalAsync(Guid customerId); Task UpdateWeeklyProgressAsync(Guid customerId, Guid customerTargetId, decimal weight, DateTime? recordedAt); Task> GetWeeklyProgressForCustomerAsync(Guid customerId, Guid customerTargetId); Task VerifyCustomer(Guid userId, string type, string identifire); Task IsverifiedCus(Guid cusId); Task> GetCardsByCustomerIdAsync(Guid customerId, CancellationToken ct = default); Task GetCardByIdAsync(Guid cardId, CancellationToken ct = default); Task AddCardAsync(CustomerCards card, CancellationToken ct = default); } }