﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using JayBirdClassLibrary.Attributes;
using JayBirdClassLibrary.Database;
using Newtonsoft.Json;

namespace JayBirdClassLibrary.Tables
{
    public class User : JayBirdTableBase
    {
        private const string C_KEY = "Test";
        private const string C_IV = "Test";

        #region Properties

        [DatabaseField("userID", true)]
        public Guid UserID { get; set; }

        [DatabaseField("userName")]
        public string UserName { get; set; }

        [DatabaseField("personID")]
        public Guid PersonID { get; set; }

        [JsonIgnore]
        [DatabaseField("password")]
        public string Password { get; set; }

        public Person LinkedPerson { get; set; }

        #endregion

        #region Constructors

        public User()
        {
            base.DatabaseTable = DatabaseTables.User;
        }

        public User(DataRow row) : this()
        {
            base.Load(row);
        }

        #endregion

        #region Public Methods

        public void Load(DatabaseConnection DbCon, Guid userID, bool loadPerson)
        {
            string whereClause = DatabaseHelper.BuildWhereClause(base.GetPrimaryKeyFieldName(), userID, SQLOperator.EqualTo);
            string query = DatabaseHelper.BuildSelectAllString(base.DatabaseTable, whereClause);
            base.Load(DbCon, query);

            if (this.UserID != Guid.Empty && loadPerson)
            {
                this.LinkedPerson = new Person();
                this.LinkedPerson.Load(DbCon, this.PersonID);
            }
        }

        public void Load(DatabaseConnection DbCon, string userName, bool loadPerson)
        {
            string whereClause = DatabaseHelper.BuildWhereClause("userName", userName, SQLOperator.EqualTo);
            string query = DatabaseHelper.BuildSelectAllString(base.DatabaseTable, whereClause);
            base.Load(DbCon, query);

            if (this.UserID != Guid.Empty && loadPerson)
            {
                this.LinkedPerson = new Person();
                this.LinkedPerson.Load(DbCon, this.PersonID);
            }
        }

        public static List<User> GetAll(DatabaseConnection DbCon, bool loadPerson)
        {
            string query = DatabaseHelper.BuildSelectAllString(DatabaseTables.User, string.Empty, string.Empty);
            DataTable resultData = DbCon.ExecuteQuery(query);
            List<User> arrReturn = new List<User>();

            foreach (DataRow row in resultData.Rows)
            {
                User user = new User(row);

                if(loadPerson)
                {
                    user.LinkedPerson = new Person();
                    user.LinkedPerson.Load(DbCon, user.PersonID);
                }

                arrReturn.Add(user);
            }

            return arrReturn;
        }

        ////Code credit: http://stackoverflow.com/questions/1678555/password-encryption-decryption-code-in-net
        //public static string EncryptText(string openText)
        //{
        //    RC2CryptoServiceProvider rc2CSP = new RC2CryptoServiceProvider();

        //    ICryptoTransform encryptor = rc2CSP.CreateEncryptor(Convert.FromBase64String(C_KEY), Convert.FromBase64String(C_IV));
        //    using (MemoryStream msEncrypt = new MemoryStream())
        //    {
        //        using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
        //        {
        //            byte[] toEncrypt = Encoding.Unicode.GetBytes(openText);

        //            csEncrypt.Write(toEncrypt, 0, toEncrypt.Length);
        //            csEncrypt.FlushFinalBlock();

        //            byte[] encrypted = msEncrypt.ToArray();

        //            return Convert.ToBase64String(encrypted);
        //        }
        //    }
        //}

        ////Code credit: http://stackoverflow.com/questions/1678555/password-encryption-decryption-code-in-net
        //public static string DecryptText(string encryptedText)
        //{
        //    RC2CryptoServiceProvider rc2CSP = new RC2CryptoServiceProvider();
        //    ICryptoTransform decryptor = rc2CSP.CreateDecryptor(Convert.FromBase64String(C_KEY), Convert.FromBase64String(C_IV));
        //    using (MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(encryptedText)))
        //    {
        //        using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
        //        {
        //            List<Byte> bytes = new List<byte>();
        //            int b;
        //            do
        //            {
        //                b = csDecrypt.ReadByte();
        //                if (b != -1)
        //                {
        //                    bytes.Add(Convert.ToByte(b));
        //                }

        //            }
        //            while (b != -1);

        //            return Encoding.Unicode.GetString(bytes.ToArray());
        //        }
        //    }
        //}

        #endregion
    }
}
