///
/// class: Device.cs
///
///This file defines the abstract Device class, which serves as the base class for all device types (e.g., smartphones, smartwatches). 
///It includes common properties and methods for managing device details and assignments.
///
/// Name: Rens Pastoor
/// Studentnumber: 555408
/// Date: 11 May 2025
///
///Version: 1
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PoloClubApp {
    /// <summary>
    /// Abstract base class representing a device in the Polo Club system.
    /// </summary>
    public abstract class Device {
        /// <summary>
        /// Gets the unique identifier of the device.
        /// </summary>
        public int Id { get; }

        /// <summary>
        /// Gets the name of the device.
        /// </summary>
        public string Name { get; }

        /// <summary>
        /// Gets or sets the name of the player the device is assigned to.
        /// </summary>
        public string PlayerName { get; set; }

        /// <summary>
        /// Initializes a new instance of the Device class.
        /// </summary>
        /// <param name="id">The unique identifier for the device.</param>
        /// <param name="name">The name of the device.</param>
        /// <param name="playerName">The name of the player the device is assigned to (optional).</param>
        protected Device(int id, string name, string playerName = null) {
            Id = id;
            Name = name;
            PlayerName = playerName;
        }

        /// <summary>
        /// Gets detailed information about the device.
        /// </summary>
        /// <returns>Formatted string with device details.</returns>
        public abstract string GetDetails();

        /// <summary>
        /// Checks if the device is currently assigned to a player.
        /// </summary>
        /// <returns>True if assigned, false otherwise.</returns>
        public bool IsAssigned(){
            return !string.IsNullOrEmpty(PlayerName);
        }

        /// <summary>
        /// Assigns the device to a player.
        /// </summary>
        /// <param name="playerName">Name of the player to assign to.</param>
        /// <param name="waterResistanceMeters">Water resistance for wearables (nullable).</param>
        /// <exception cref="Exception">Throws when assignment fails.</exception>
        public void AssignDevice(string playerName, int? waterResistanceMeters){
            if (IsAssigned()){
                throw new Exception("Device is already assigned");
            }
            if (this is IWearable && waterResistanceMeters < 3){
                throw new Exception("Water resistance must be 3 meters or more for wearables");
            }
            if (Id == 0){ 
                throw new Exception("Invalid device ID");
            }
            PlayerName = playerName;
        }

        /// <summary>
        /// Returns the device from a player.
        /// </summary>
        /// <returns>True if successful, false if device wasn't assigned.</returns>
        public bool ReturnDevice(){
            if (!IsAssigned()){
                return false;
            }
            PlayerName = null;
            return true;
        }
    }
}
