using System;
using System.Collections.Generic;
using System.Linq;
using BO.AppServer.Data.Entity;
using Microsoft.EntityFrameworkCore;
using Quadarax.Foundation.Core.Data;
using Quadarax.Foundation.Core.Data.Domain;
using Quadarax.Foundation.Core.Data.Extensions;
using Quadarax.Foundation.Core.Data.Interface;
using Quadarax.Foundation.Core.Data.Interface.Domain;
using Quadarax.Foundation.Core.Data.Repository;

public class WorkspaceRepo : EntityRepository<long,  Workspace>
    {
        public WorkspaceRepo(IUnitOfWork<DataDomain> unitOfWork) : base(unitOfWork)
        {
            DefaultIncludes.Add("Structures");
        }

        public Workspace CreateWorkspace(string name, BillingPlan billingPlan, string apiKeyPassword, bool isDefault, User owner, User creator)
        {
            var workspace = New();
            workspace.Name = name;
            workspace.BillingPlanId = billingPlan.Id;
            workspace.Created = DateTime.Now;
            workspace.CreatedByUser = creator;
            workspace.Apikey = Guid.NewGuid();
            workspace.Apipassword = apiKeyPassword;
            if (workspace.Structures == null)
                workspace.Structures = new List<Structure>();
            
            workspace.Structures.Add(new Structure(){Name = "Root", Created = DateTime.Now,CreatedByUserId = creator.Id});
            workspace.UserWorkspaces = new List<UserWorkspace>();

            AppendUser(workspace, owner, isDefault);
            return workspace;
        }

        public void AppendUser(Workspace workspace, User user, bool isDefault)
        {
            var userWorkspace = new UserWorkspace();
            userWorkspace.Workspace = workspace;
            userWorkspace.User = user;
            userWorkspace.IsDefault = isDefault;
            if (isDefault)
            {
                foreach (var uw in workspace.UserWorkspaces)
                    uw.IsDefault = false;
            }
            workspace.UserWorkspaces.Add(userWorkspace);
        }

        public IQueryable<Workspace> GetAllEmpty(IPaging paging)
        {
            return Query(paging).Where(x => x.Structures.Any(struc => !struc.Metadocuments.Any()));
        }
        public IQueryable<Workspace> GetAllNonEmpty(IPaging paging)
        {
            return Query(paging).Where(x => x.Structures.Any(struc => struc.Metadocuments.Count>0));
        }

        public Workspace GetByName(string name)
        {
            return Query(new Paging()).FirstOrDefault(x => x.Name.ToLower() == name.ToLower());
        }

        public Workspace GetByApiKey(string apiKey)
        {
            return Query(new Paging()).FirstOrDefault(x => x.Apikey == Guid.Parse(apiKey));
        }


        public IQueryable<Workspace> GetAllByOwner(User owner, IPaging paging)
        {
            var userWorkspaceSet = Context.GetDbSet<DbSet<UserWorkspace>>();
            return userWorkspaceSet.Page(paging.IsDisabled ? (int?)null : paging.Page, paging.PageSize)
                .Where(x => x.User == owner || owner==null).Select(x => x.Workspace);
        }

        public Workspace GetDefaultByOwner(User owner)
        {
            if (owner == null)
                throw new ArgumentNullException(nameof(owner));
            var userWorkspaceSet = Context.GetDbSet<DbSet<UserWorkspace>>();
            return userWorkspaceSet.Where(x => x.User == owner).Select(x=>x.Workspace).FirstOrDefault();
        }
}