using Monitoring.Core.Domain.AssetGroupManagement;
using Monitoring.Core.Domain.EventManagement;
using Monitoring.Core.Domain.OrganizationManagement;
using Monitoring.Core.Domain.ServiceOrganizationManagement;
using Monitoring.Core.Domain.UserLogManagement;

namespace Monitoring.Core.Domain.AssetManagement;

/// <summary>
/// Объект
/// </summary>
public class Asset
{
	/// <summary>
	/// ИД объекта.
	/// </summary>
	public AssetId Id { get; } = default!;

	/// <summary>
	/// Название.
	/// </summary>
	public AssetName Name { get; set; } = default!;

	/// <summary>
	/// Описание.
	/// </summary>
	public AssetDescription Description { get; set; } = default!;

	/// <summary>
	/// Широта.
	/// </summary>
	public Coordinates Coordinates { get; set; } = default!;

	/// <summary>
	/// ИД организации.
	/// </summary>
	public OrganizationId OrganizationId { get; } = default!;

	/// <summary>
	/// Организация.
	/// </summary>
	public Organization Organization { get; } = default!;

	/// <summary>
	/// Ид обслуживающей организации.
	/// </summary>
	public ServiceOrganizationId? ServiceOrganizationId { get; private set; } = default!;

	/// <summary>
	/// Обслуживающей организации.
	/// </summary>
	public ServiceOrganization? ServiceOrganization { get; } = default!;

	/// <summary>
	/// Список событий.
	/// </summary>
	public List<Event> Events { get; } = [];

	/// <summary>
	/// Список логов.
	/// </summary>
	public List<UserLog> Logs { get; } = [];

	/// <summary>
	/// Группы, в которые входит данный объект.
	/// </summary>
	public List<AssetGroup> Groups { get; } = [];

	/// <summary>
	/// Комментарий.
	/// </summary>
	public AssetComment Comment { get; set; } = default!;

	/// <summary>
	/// Версия строки для оптимистичной блокировки.
	/// </summary>
	public byte[] RowVersion { get; set; } = [];

	public Address Address { get; set; } = default!;

	public Owner Owner { get; set; } = default!;

	public Passwords Passwords { get; set; } = default!;

	/// <summary>
	/// IMEI устройства.
	/// </summary>
	public Imei Imei { get; set; } = Imei.Empty;

	public List<ResponsiblePerson> ResponsiblePersons { get; } = [];
	public List<Photo> Photos { get; } = [];
	public List<Area> Areas { get; } = [];
	public List<AlarmScope> AlarmScopes { get; } = [];

	public bool IsOnline { get; set; }

	/// <summary>
	/// </summary>
	public DateTime? LastStatusChange { get; set; }

	public void UpdateServiceOrganization(ServiceOrganizationId? serviceOrganizationId)
	{
		ServiceOrganizationId = serviceOrganizationId;
	}

	public static Asset Create(
		AssetName name,
		AssetDescription description,
		OrganizationId organizationId,
		Address address,
		Owner owner,
		Passwords passwords,
		Coordinates coordinates,
		ServiceOrganizationId? serviceOrganizationId,
		Imei imei,
		AssetComment? comment = null
	)
	{
		return new Asset(
			new(Guid.NewGuid()),
			name,
			description,
			organizationId,
			address,
			owner,
			passwords,
			coordinates,
			serviceOrganizationId,
			imei,
			comment ?? AssetComment.Create(string.Empty)
		);
	}

	public static Asset Create(
		AssetId id,
		AssetName name,
		AssetDescription description,
		OrganizationId organizationId,
		Address address,
		Owner owner,
		Passwords passwords,
		Coordinates coordinates,
		ServiceOrganizationId? serviceOrganizationId,
		Imei imei,
		AssetComment? comment = null
	)
	{
		return new Asset(
			id,
			name,
			description,
			organizationId,
			address,
			owner,
			passwords,
			coordinates,
			serviceOrganizationId,
			imei,
			comment ?? AssetComment.Create(string.Empty)
		);
	}

	private Asset(
		AssetId id,
		AssetName name,
		AssetDescription description,
		OrganizationId organizationId,
		Address address,
		Owner owner,
		Passwords passwords,
		Coordinates coordinates,
		ServiceOrganizationId? serviceOrganizationId,
		Imei imei,
		AssetComment? comment = null
	)
	{
		Id = id;
		Name = name;
		Description = description;
		OrganizationId = organizationId;
		Address = address;
		Owner = owner;
		Passwords = passwords;
		Coordinates = coordinates;
		ServiceOrganizationId = serviceOrganizationId;
		Imei = imei;
		Comment = comment;
	}

	protected Asset() { }
}
