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

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

    public EntityQuery<Category2> Categories2 { get; set; }
    public EntityQuery<Product2> Products2 { get; set; }
    public EntityQuery<Supplier2> Suppliers2 { get; set; }
  }

  [ProvideEntityAspect]
  public class Category2 {
    public int Category2Id { get; set; }
    public string Category2Name { get; set; }
  }

  public class Product2 : BaseEntity2 {
    public int Product2Id { get; set; }
    public string Product2Name { get; set; }

    public int Category2Id { get; set; } // Foreign key for "Category2"
    public Category2 Category2 { get; set; }

    public Guid Supplier2Key { get; set; } // Foreign key for "Supplier2"
    public Supplier2 Supplier2 { 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("Supplier2")] // now handled by Product2DbContext configuration
  public class Supplier2 : BaseEntity2 {
    public Supplier2() {
      Supplier2Key = Guid.NewGuid();
    }

    [Key] // Key for "Supplier2" does not conform to conventions
    public Guid Supplier2Key { 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<Product2, String> args) {
      if (null != args.Value) {
        args.Value = args.Value.ToUpper();
      }
    }

    //public ICollection<Product2> Product2s { get { return null; } } // not yet; must use RelatedEntityList<T> for now
    public RelatedEntityList<Product2> Products2 { get { return null; } }
  }

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