using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;

namespace AsbCloudDb.Model
{
    [Table("t_detected_operation"), Comment("автоматически определенные операции по телеметрии")]
    public class DetectedOperation
    {
        [Key]
        [Column("id")]
        public int Id { get; set; }

        [Column("id_telemetry")]
        public int IdTelemetry { get; set; }

        [Column("id_category"), Comment("Id категории операции")]
        public int IdCategory { get; set; }

        [Column("id_user"), Comment("Id пользователя по телеметрии на момент начала операции")]
        public int IdUsersAtStart { get; set; }

        [Column("date_start", TypeName = "timestamp with time zone"), Comment("Дата начала операции")]
        public DateTimeOffset DateStart { get; set; }

        [Column("date_end", TypeName = "timestamp with time zone"), Comment("Дата начала операции")]
        public DateTimeOffset DateEnd { get; set; }

        [NotMapped]
        public double DurationMinutes => (DateEnd - DateStart).TotalMinutes;

        [Column("depth_start"), Comment("Глубина на начало операции, м")]
        public double DepthStart { get; set; }

        [Column("depth_end"), Comment("Глубина после завершения операции, м")]
        public double DepthEnd { get; set; }

        [Column("value"), Comment("Ключевой показатель операции")]
        public double Value { get; set; }

        [Column("enabled_subsystems"), Comment("флаги аключенных подсистем")]
        public int EnabledSubsystems { get; set; }

        [Column("extra_data", TypeName = "jsonb"), Comment("доп. инфо по операции")]
        public IDictionary<string, object> ExtraData { get; set; } = null!;

        [JsonIgnore]
        [ForeignKey(nameof(IdTelemetry))]
        public virtual Telemetry Telemetry { get; set; } = null!;

        [JsonIgnore]
        [ForeignKey(nameof(IdCategory))]
        public virtual WellOperationCategory OperationCategory { get; set; } = null!;

        public override string ToString()
            => $"{IdCategory}\t{DateStart:G}\t{DateEnd:G}\t{DurationMinutes:#0.#}\t{DepthStart:#0.#}\t{DepthEnd:#0.#}";

        /// <summary>
        /// Флаги аключенных подсистем
        /// </summary>
        [Flags]
        public enum EnabledSubsystemsFlags
        {
            /// <summary>
            /// Автоподача долота
            /// </summary>
            AutoRotor = 1 << 0,
            /// <summary>
            /// БУРЕНИЕ В СЛАЙДЕ
            /// </summary>
            AutoSlide = 1 << 1,
            /// <summary>
            /// ПРОРАБОТКА
            /// </summary>
            AutoConditionig = 1 << 2,
            /// <summary>
            /// СПУСК СПО
            /// </summary>
            AutoSinking = 1 << 3,
            /// <summary>
            /// ПОДЪЕМ СПО
            /// </summary>
            AutoLifting = 1 << 4,
            /// <summary>
            /// ПОДЪЕМ С ПРОРАБОТКОЙ
            /// </summary>
            AutoLiftingWithConditionig = 1 << 5,
            /// <summary>
            /// блокировка
            /// </summary>
            AutoBlocknig = 1 << 6,
        }

        /// <summary>
        /// Есть ли флаг подсистемы у операции
        /// </summary>
        /// <param name="flag"></param>
        /// <returns></returns>
        public bool HasSubsystemFlag(EnabledSubsystemsFlags flag)
        => HasSubsystemFlag((int)flag);

        /// <summary>
        /// Есть ли флаг/флаги подсистемы у операции
        /// </summary>
        /// <param name="flags"></param>
        /// <returns></returns>
        public bool HasSubsystemFlag(int flags)
        => (EnabledSubsystems & flags) > 0;        
    }
}