LSFE/LSFE.MobApp/ViewModels/Coverage/AddEditDoctorVM.cs
2026-07-30 10:31:04 +08:00

311 lines
10 KiB
C#

using LSFE.MobApp.Contracts;
using LSFE.MobApp.Entities.Doctor;
using LSFE.MobApp.Entities.Location;
using LSFE.MobApp.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace LSFE.MobApp.ViewModels.Coverage
{
public class AddEditDoctorVM : INotifyPropertyChanged
{
private readonly IApiClient<Doctor> _doctorApiClient;
private readonly IApiClient<Institution> _institutionApiClient;
private readonly Doctor _existingDoctor;
private readonly bool _isEditMode;
private string _firstName;
private string _middleInitial;
private string _lastName;
private string _specialization;
private string _emailAddress;
private string _phoneNo;
private string _address;
private string _licenseNo;
private DateTime _birthDate = DateTime.Now.AddYears(-30);
private string _maxVisit = "10";
private int _selectedStatusIndex;
private Institution _selectedInstitution;
private bool _isLoading;
public AddEditDoctorVM(
IApiClient<Doctor> doctorApiClient,
IApiClient<Institution> institutionApiClient,
List<Institution> institutions,
Doctor existingDoctor = null)
{
_doctorApiClient = doctorApiClient;
_institutionApiClient = institutionApiClient;
_existingDoctor = existingDoctor;
_isEditMode = existingDoctor != null;
Institutions = institutions;
StatusOptions = new List<string> { "Pending", "Approved", "For DSM Approval", "Inactive" };
if (_isEditMode)
{
LoadExistingDoctor();
}
SaveCommand = new Command(async () => await SaveDoctor(), () => !IsLoading);
CancelCommand = new Command(async () => await Cancel());
}
private void LoadExistingDoctor()
{
FirstName = _existingDoctor.FirstName;
MiddleInitial = _existingDoctor.MiddleInitial;
LastName = _existingDoctor.LastName;
Specialization = _existingDoctor.SpecializationName;
EmailAddress = _existingDoctor.EmailAddress;
PhoneNo = _existingDoctor.PhoneNo;
Address = _existingDoctor.Address;
LicenseNo = _existingDoctor.LicenseNo;
BirthDate = _existingDoctor.BirthDate;
MaxVisit = _existingDoctor.MaxVisit.ToString();
SelectedStatusIndex = _existingDoctor.Status;
if (_existingDoctor.InstitutionId > 0)
{
SelectedInstitution = Institutions.FirstOrDefault(i => i.InstitutionId == _existingDoctor.InstitutionId);
}
}
public string PageTitle => _isEditMode ? "Edit Doctor" : "Add New Doctor";
public string SaveButtonText => _isEditMode ? "Update Doctor" : "Create Doctor";
public string FirstName
{
get => _firstName;
set { _firstName = value; OnPropertyChanged(); }
}
public string MiddleInitial
{
get => _middleInitial;
set { _middleInitial = value; OnPropertyChanged(); }
}
public string LastName
{
get => _lastName;
set { _lastName = value; OnPropertyChanged(); }
}
public string Specialization
{
get => _specialization;
set { _specialization = value; OnPropertyChanged(); }
}
public string EmailAddress
{
get => _emailAddress;
set { _emailAddress = value; OnPropertyChanged(); }
}
public string PhoneNo
{
get => _phoneNo;
set { _phoneNo = value; OnPropertyChanged(); }
}
public string Address
{
get => _address;
set { _address = value; OnPropertyChanged(); }
}
public string LicenseNo
{
get => _licenseNo;
set { _licenseNo = value; OnPropertyChanged(); }
}
public DateTime BirthDate
{
get => _birthDate;
set { _birthDate = value; OnPropertyChanged(); }
}
public string MaxVisit
{
get => _maxVisit;
set { _maxVisit = value; OnPropertyChanged(); }
}
public int SelectedStatusIndex
{
get => _selectedStatusIndex;
set { _selectedStatusIndex = value; OnPropertyChanged(); }
}
public Institution SelectedInstitution
{
get => _selectedInstitution;
set { _selectedInstitution = value; OnPropertyChanged(); }
}
public List<Institution> Institutions { get; }
public List<string> StatusOptions { get; }
public bool IsLoading
{
get => _isLoading;
set
{
_isLoading = value;
OnPropertyChanged();
((Command)SaveCommand).ChangeCanExecute();
}
}
public ICommand SaveCommand { get; }
public ICommand CancelCommand { get; }
private async Task SaveDoctor()
{
// Validation
if (string.IsNullOrWhiteSpace(FirstName))
{
await Application.Current.MainPage.DisplayAlert("Validation Error", "First name is required", "OK");
return;
}
if (string.IsNullOrWhiteSpace(LastName))
{
await Application.Current.MainPage.DisplayAlert("Validation Error", "Last name is required", "OK");
return;
}
if (string.IsNullOrWhiteSpace(EmailAddress))
{
await Application.Current.MainPage.DisplayAlert("Validation Error", "Email address is required", "OK");
return;
}
if (string.IsNullOrWhiteSpace(PhoneNo))
{
await Application.Current.MainPage.DisplayAlert("Validation Error", "Phone number is required", "OK");
return;
}
if (string.IsNullOrWhiteSpace(LicenseNo))
{
await Application.Current.MainPage.DisplayAlert("Validation Error", "License number is required", "OK");
return;
}
if (!byte.TryParse(MaxVisit, out byte maxVisitValue))
{
await Application.Current.MainPage.DisplayAlert("Validation Error", "Max visits must be a valid number", "OK");
return;
}
try
{
IsLoading = true;
Doctor doctor;
if (_isEditMode)
{
doctor = _existingDoctor;
}
else
{
doctor = new Doctor
{
Id = Guid.NewGuid(),
CreatedDate = DateTime.Now
};
}
// Map properties
doctor.FirstName = FirstName?.Trim();
doctor.MiddleInitial = MiddleInitial?.Trim();
doctor.LastName = LastName?.Trim();
doctor.SpecializationName = Specialization?.Trim();
doctor.EmailAddress = EmailAddress?.Trim();
doctor.PhoneNo = PhoneNo?.Trim();
doctor.Address = Address?.Trim();
doctor.LicenseNo = LicenseNo?.Trim();
doctor.BirthDate = BirthDate;
doctor.MaxVisit = maxVisitValue;
doctor.Status = (byte)SelectedStatusIndex;
doctor.InstitutionId = SelectedInstitution?.InstitutionId ?? 0;
doctor.IsActive = true;
ApiResponse<Doctor> response;
if (_isEditMode)
{
response = await _doctorApiClient.UpdateAsync(doctor.Id,doctor);
}
else
{
response = await _doctorApiClient.CreateAsync(doctor);
}
if (response.Success)
{
await Application.Current.MainPage.DisplayAlert(
"Success",
_isEditMode ? "Doctor updated successfully" : "Doctor created successfully",
"OK");
// Notify parent to reload
MessagingCenter.Send(this, "DoctorSaved");
await Application.Current.MainPage.Navigation.PopModalAsync();
}
else
{
await Application.Current.MainPage.DisplayAlert(
"Error",
response.Message ?? "Failed to save doctor",
"OK");
}
}
catch (Exception ex)
{
await Application.Current.MainPage.DisplayAlert("Error", $"Failed to save doctor: {ex.Message}", "OK");
}
finally
{
IsLoading = false;
}
}
private async Task Cancel()
{
var hasChanges = !string.IsNullOrEmpty(FirstName) ||
!string.IsNullOrEmpty(LastName) ||
!string.IsNullOrEmpty(EmailAddress);
if (hasChanges)
{
var confirm = await Application.Current.MainPage.DisplayAlert(
"Discard Changes",
"Are you sure you want to discard your changes?",
"Discard",
"Continue Editing");
if (!confirm) return;
}
await Application.Current.MainPage.Navigation.PopModalAsync();
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}