using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using IdeaBlade.Aop;
using IdeaBlade.Core;
using IdeaBlade.EntityModel;
using IdeaBlade.Validation;

namespace CodeFirstWalk.Model
{
    public class ProductEntities : EntityManager
    {
        public ProductEntities(bool shouldConnect= true) : base(shouldConnect) { }

        public EntityQuery<Category> Categories { get; set; }
        public EntityQuery<Product> Products { get; set; }
        public EntityQuery<Supplier> Suppliers { get; set; }
    }

    [ProvideEntityAspect]
    public class Category
    {
        public int CategoryId { get; set; }
        public string CategoryName { get; set; }
    }

    public class Product : BaseEntity
    {
        public int ProductId { get; set; }
        public string ProductName { get; set; }

        public int CategoryId { get; set; } // Foreign key for "Category"
        public Category Category { get; set; }

        public Guid SupplierKey { get; set; } // Foreign key for "Supplier"
        public Supplier Supplier { get; set; }

        // Example of non-persisted property
        [NotMapped]
        public string NotPersisted
        {
            get { return _notPersisted; }
            set { _notPersisted = value; }
        }
        private string _notPersisted = "I'm not persisted to the database.";
    }

    //[Table("Supplier")] // now handled by ProductDbContext configuration
    public class Supplier : BaseEntity
    {
        public Supplier()
        {
            SupplierKey = Guid.NewGuid();
        }

        [Key] // Key for "Supplier" does not conform to conventions
        public Guid SupplierKey { get; set; }

        // Examples of useful attributes
        [Bindable(true, BindingDirection.TwoWay)]
        [Display(Name = "Company Name", AutoGenerateField = true)]
        [StringLengthVerifier(MaxValue = 50, IsRequired = true)]
        public string CompanyName { get; set; }

        // Example property interceptor
        [AfterGet("CompanyName")]
        internal void UppercaseNameAfterGet(PropertyInterceptorArgs<Product, String> args)
        {
            if (null != args.Value)
            {
                args.Value = args.Value.ToUpper();
            }
        }

        //public ICollection<Product> Products { get { return null; } } // not yet; must use RelatedEntityList<T> for now
        public RelatedEntityList<Product> Products { get { return null; } }
    }

    [ProvideEntityAspect]
    public abstract class BaseEntity : IEntity
    {
        public EntityAspect EntityAspect { get { throw new NotImplementedException(); } }
    }

}