﻿using Jarvis.Server.Interfaces;
using SQLite.Net.Attributes;
using System;
using System.Collections.Generic;

namespace Jarvis.Server.Data.Persistent
{
    public class Shutter : AbstractActuatorNode, IDeserializable
    {
        [NotNull, Unique]
        public int ChannelCode { get; set; }

        public Shutter(int channelCode, string label, string areaId, bool isFavorite = false) : base(label, areaId, isFavorite)
        {
            ChannelCode = channelCode;
        }

        [Obsolete("Only for deserializing", true)]
        public Shutter() : base()
        {
        }

        public static IEnumerable<Shutter> GetAll()
        {
            lock (db)
            {
                return db.Table<Shutter>();
            }
        }

        override public string ToString()
        {
            return $"[Type: {GetType()} | Label: {Label} | IsFavorite: {IsFavorite} | ChannelCode: {Convert.ToString(ChannelCode, 2)}]";
        }

        public override AbstractDatabaseObject GetStaleObject()
        {
            lock (db)
            {
                return db.Query<Shutter>("SELECT * FROM Shutter WHERE Id = ?", Id).ToArray()[0];
            }
        }

        public ShutterCode GetISMCode() // TODO put in interface
        {
            return db.Query<ShutterCode>("SELECT * FROM ShutterCode WHERE Channel = ?", ChannelCode).ToArray()[0];
        }

        public override bool Insert() // TODO put in abstract class
        {
            lock (db)
            {
                db.BeginTransaction();
                base.Insert();
                GetISMCode().SetUsed(true);
                if (db.IsInTransaction)
                    db.Commit();
                return true;
            }
        }

        public override bool Update()
        {
            lock (db)
            {
                db.BeginTransaction();
                ((AbstractSwitchable)GetStaleObject()).GetISMCode().SetUsed(false);
                base.Update();
                this.GetISMCode().SetUsed(true);
                if (db.IsInTransaction)
                    db.Commit();
                return true;
            }
        }

        public override bool Delete()
        {
            lock (db)
            {
                db.BeginTransaction();
                base.Delete();
                this.GetISMCode().SetUsed(false);
                if (db.IsInTransaction)
                    db.Commit();
                return true;
            }
        }
    }
}