from django.shortcuts import render

# Create your views here.
from django.contrib.auth.decorators import login_required
from .models import *
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
from .forms import *
from django.shortcuts import redirect
from django.db import connection
from company.models import Company,User,CGroup
import json
import time 
from django.db import connection

from django.contrib.auth.models import Group

def rbac_menu_items(item,sys_menu,auth_menu_ids=[],only_authorized=False):    
    d=item
    children=[]   
    if only_authorized:
        for i in sys_menu:      #用户登录菜单
            if i['parent_id']==d['id'] and i['id'] in auth_menu_ids:            
                children.append(i) 
    else:
        if auth_menu_ids:       #功能组别菜单
            for i in sys_menu:                
                if i['parent_id']==d['id']:
                    show=False
                    if i['id'] in auth_menu_ids:
                        show=True
                    i['show']=show
                    children.append(i) 
        else:
            for i in sys_menu:  #所有企业菜单
                if i['parent_id']==d['id']:            
                    children.append(i) 
    if children:
        d['children']=[rbac_menu_items(child,sys_menu,auth_menu_ids,only_authorized) for child in children]  
    return d 


def rbac_sys_menu(sys_menu,auth_menu_ids=[],only_authorized=False):
    menu_items=[]  
    sys_menu.sort(key=lambda x:x["priority"])
    
    if only_authorized:             #用户登录菜单
        for i in sys_menu:        
            if i['level']==1 and i['id'] in auth_menu_ids:          
                menu_items.append(rbac_menu_items(i,sys_menu,auth_menu_ids,only_authorized))  
    else:    
        if auth_menu_ids:   #功能组别菜单 
            for i in sys_menu:   
                if i['level']==1:                                   
                    show=False
                    if i['id'] in auth_menu_ids:
                        show=True
                    i['show']=show 
                    menu_items.append(rbac_menu_items(i,sys_menu,auth_menu_ids,only_authorized)) 
        else:               #所有企业菜单
            for i in sys_menu:   
                if i['level']==1:  
                    menu_items.append(rbac_menu_items(i,sys_menu,auth_menu_ids,only_authorized))     
    return menu_items


class RbacMenu(object):
    def __init__(self,company=None,cgroup=None,user=None): 
        self.only_authorized=False        
        self.sys_menu_itmes=[]
        self.auth_menu_ids=[]       
        if user:
            self.only_authorized=True 
        cur=connection.cursor()
        sWhere=''
        if company:
            sWhere=" where case when jsonb_array_length(companys_only)=0 then true "+\
                "else companys_only@>'[{\"id\":\""+str(company.id)+"\"}]'::jsonb end"   
        elif cgroup:
            sWhere=" where case when jsonb_array_length(companys_only)=0 then true "+\
                "else companys_only@>'[{\"id\":\""+str(cgroup.company.id)+"\"}]'::jsonb end" 
        elif user:
            sWhere=" where case when jsonb_array_length(companys_only)=0 then true "+\
                "else companys_only@>'[{\"id\":\""+str(user.company.id)+"\"}]'::jsonb end" 
        s="select id,title,level,coalesce(icon,''),coalesce(url,''),coalesce(parent_id,0),coalesce(priority,0),coalesce(remark,'') "+\
            "from rbac_menu"+sWhere+" order by priority,id "
        cur.execute(s)
        for r in cur.fetchall():
            self.sys_menu_itmes.append({'id':r[0],'title':r[1],'level':r[2],'icon':r[3],'url':r[4],'parent_id':r[5],'priority':r[6],'remark':r[7]})        
        if user or cgroup:
            if user:
                s="select array_to_string(array(select json_array_elements_text(menus::json) menu_id FROM rbac_cgroupmenu "+\
                    "where (select company_id from company_cgroup where id=cgroup_id)="+str(user.ancestor_id)+\
	                " and  cgroup_id in ("+\
		            "select id from company_cgroup where group_id in (select group_id FROM company_user_groups where user_id="+str(user.id)+")"+\
	                ") group by menu_id),',')"
            else:
                s="select array_to_string(array(select json_array_elements_text(menus::json) FROM rbac_cgroupmenu "+\
                    "where cgroup_id="+str(cgroup.id)+"),',')"   
            cur.execute(s)
            r=cur.fetchone()        
            if r[0]:
                self.auth_menu_ids=json.loads("["+r[0]+"]") 
            else:
                self.auth_menu_ids=[0]
        cur.close()
    def get_menu(self):
        return rbac_sys_menu(self.sys_menu_itmes,self.auth_menu_ids,self.only_authorized)
        

class MenuCompany(object):    
    def __init__(self,company_id,cgroup_id=None,user_id=None):    
        self.company_id=company_id
        self.user_id=user_id
        self.cgroup_id=cgroup_id 
    def get_company_menu(self):        
        cur=connection.cursor()
        s="select id,title,level,coalesce(icon,''),coalesce(url,''),coalesce(parent_id,0),coalesce(priority,0),coalesce(remark,'') "+\
            "from rbac_companymenu where company_id="+str(self.company_id)+" order by priority,id "
        cur.execute(s)        
        menu_items=[]
        for r in cur.fetchall():
            menu_items.append({'id':r[0],'title':r[1],'level':r[2],'icon':r[3],'url':r[4],'parent_id':r[5],'priority':r[6],'remark':r[7]})  
        cur.close()
        return rbac_sys_menu(menu_items)
    def get_user_menu(self,only_authorized=True):
        cur=connection.cursor()
        auth_menu_ids=[]
        menu_items=[]
        s="select array_to_string(array(select json_array_elements_text(menus::json) menu_id FROM rbac_cgroupmenu "+\
            "where (select company_id from company_cgroup where id=cgroup_id)=(select ancestor_id from company_user where id="+str(self.user_id)+\
	        " and  cgroup_id in ("+\
		    "select id from company_cgroup where group_id in (select group_id FROM company_user_groups where user_id="+str(self.user_id)+")"+\
	        ")"+\
            ") group by menu_id),',')"        
        cur.execute(s)
        r=cur.fetchone()        
        if r[0]:
            auth_menu_ids=json.loads("["+r[0]+"]") 
        else:
            auth_menu_ids=[0]
        s="select id,title,level,coalesce(icon,''),coalesce(url,''),coalesce(parent_id,0),coalesce(priority,0),coalesce(remark,'') "+\
            "from rbac_companymenu where company_id="+str(self.company_id)+" order by priority,id "        
        cur.execute(s)        
        for r in cur.fetchall():
            menu_items.append({'id':r[0],'title':r[1],'level':r[2],'icon':r[3],'url':r[4],'parent_id':r[5],'priority':r[6],'remark':r[7]})  
        cur.close()
        return rbac_sys_menu(menu_items,auth_menu_ids,only_authorized)    

    def get_cgroup_menu(self):
        cur=connection.cursor()
        auth_menu_ids=[]
        menu_items=[]
        only_authorized=False
        s="select array_to_string(array(select json_array_elements_text(menus::json) menu_id FROM rbac_cgroupmenu "+\
            "where cgroup_id="+str(self.cgroup_id)+" group by menu_id),',')"
        cur.execute(s)
        r=cur.fetchone()        
        if r[0]:
            auth_menu_ids=json.loads("["+r[0]+"]") 
        else:
            auth_menu_ids=[0]
        s="select id,title,level,coalesce(icon,''),coalesce(url,''),coalesce(parent_id,0),coalesce(priority,0),coalesce(remark,'') "+\
            "from rbac_companymenu where company_id="+str(self.company_id)+" order by priority,id "
        cur.execute(s)        
        for r in cur.fetchall():
            menu_items.append({'id':r[0],'title':r[1],'level':r[2],'icon':r[3],'url':r[4],'parent_id':r[5],'priority':r[6],'remark':r[7]})  
        cur.close()

        #print('auth_menus')
        #print(auth_menu_ids)

        return rbac_sys_menu(menu_items,auth_menu_ids,only_authorized)   

 
@login_required
def list_menu(request,what):
    data={'e':'','data':[],'clmns':[]}
    u=request.user
    if u.id!=3506: #sys_admin
        data['e']
        return JsonResponse(data)
    if what=='menu':  
        m=RbacMenu()
        data=m.get_menu()
        return render(request,'rbac/list_sys_menu.html', {'menuitems':data}) 
    return JsonResponse(data)


@login_required
def edit_menu(request,id=None):
    if id:
        obj=Menu.objects.get(id=int(id))
    else:
        obj=Menu()
    pid=request.GET.get('parent_id','')
    if pid:
        obj.parent_id=int(pid)
    is_saved=False
    if request.method == 'GET':           
        form = MenuForm(instance=obj)     
        companys=[]
        for c in Company.objects.filter(level_id=1).order_by('name'):
            companys.append([c.id,c.name])
    else:          
        delete=request.POST.get('delete','false')
        if delete=='true':   
            t=obj.title
            obj.delete()
            return  JsonResponse({'msg':t+'已删除'})

        form = MenuForm(request.POST, instance=obj)       
        if form.is_valid():            
            form.save()         
            is_saved=True
        return  redirect("/rbac/list/menu/")   
    return render(request, 'rbac/edit_sys_menu.html', {'form': form, 'is_saved':is_saved,'companys':companys})     


@login_required
def sync_groupmenu(request):
    data={'e':''}
    u=request.user
    if u.id!=3506: #sys_admin
        dat['e']='not authorized this operation'
        return JsonResponse(data)
    return JsonResponse(data)
    

@login_required
def rbac_action(request,what,id=None):
    data={'e':''}
    u=request.user    
    if what=='init_groupmenu':
        if u.id!=3506: #sys_admin
            data['e']='not authorized this operation'
            return JsonResponse(data)
        company_id=request.GET.get('company_id',None)
        return JsonResponse( init_groupmenu(company_id))
    elif what=='user_menu':
        u=User.objects.get(id=2)       
        m=RbacMenu(u.company,u)
        data=m.get_menu()    
        return JsonResponse(data,safe=False)
    elif what=='add_group':
        if request.method=='GET':
            cs=[]
            for c in Company.objects.filter(level_id=1).order_by('name'):
                cs.append([c.id,c.name])
            return render(request,'company/add_group.html',{'companys':cs})
        else:
            data={'e':''}
            r=json.loads(request.body)  
            name=r['name']
            company_ids=r['company_ids']
            remark=None
            if 'remark' in r:
                remark=r['remark']
            gs=Group.objects.filter(name=name)
            if gs:
                data['e']='功能组别 '+name+' 已存在'
                return JsonResponse(data)
            a=company_ids.split(',')
            if not a:
                data['e']='企业ID不能为空'
                return JsonResponse(data)
            g=Group(name=name)
            g.save()        
            for i in a:
                cg=CGroup(group_id=g.id,company_id=int(i),name=name,remark=remark)
                cg.save()
            return JsonResponse(data)
    elif what=='list_companymenu':        
        company_id=request.GET.get('company_id','')
        data={'e':'','menuitems':[],'company':{}}
        if company_id:
            cs=Company.objects.filter(id=int(company_id))
            if cs:
                c=cs[0]
                data['company']={'id':c.id,'name':c.name}
                m=MenuCompany(company_id=company_id)
                data['menuitems']=m.get_company_menu() 
            else:
                data['e']='company id err'
        else:
            data['e']='company id missing'
        return render(request,'rbac/list_company_menu.html',data)        
    elif what=='edit_companymenu':        
        if id:
            obj=CompanyMenu.objects.get(id=int(id))
        else:
            obj=CompanyMenu()
        pid=request.GET.get('parent_id','')
        if pid:
            obj.parent_id=int(pid)
        is_saved=False
        if request.method == 'GET':
            cid=request.GET.get('company_id','')
            obj.company_id=int(cid)
            form = CompanyMenuForm(instance=obj)            
        else:          
            delete=request.POST.get('delete','false')
            if delete=='true':   
                t=obj.title
                obj.delete()
                return  JsonResponse({'msg':t+'已删除'})

            form = CompanyMenuForm(request.POST, instance=obj)       
            if form.is_valid():            
                form.save()         
                is_saved=True
            return redirect("/rbac/action/list_companymenu/?company_id="+str(obj.company_id))
        return render(request, 'rbac/edit_company_menu.html', {'form': form, 'is_saved':is_saved})     
    elif what=='edit_sysmenu':  
        if id:
            obj=Menu.objects.get(id=int(id))
        else:
            obj=Menu()
        pid=request.GET.get('parent_id','')
        if pid:
            obj.parent_id=int(pid)
        is_saved=False
        if request.method == 'GET':           
            form = MenuForm(instance=obj)     
            companys=[]
            for c in Company.objects.filter(level_id=1).order_by('name'):
                companys.append([c.id,c.name])
        else:          
            delete=request.POST.get('delete','false')
            if delete=='true':   
                t=obj.title
                obj.delete()
            return  JsonResponse({'msg':t+'已删除'})

            form = MenuForm(request.POST, instance=obj)       
            if form.is_valid():            
                form.save()         
                is_saved=True
            return  redirect("/rbac/list/sys_menu/")
        return render(request, 'rbac/edit_sys_menu.html', {'form': form, 'is_saved':is_saved,'companys':companys})        
    #2021-09-09
    elif what=='create_companymenu':
        if request.method=='GET':
            company={}
            company_id=request.GET.get('company_id','')   
            cs=Company.objects.filter(id=int(company_id))
            c=None
            if cs:
                c=cs[0]
                company={'id':c.id,'name':c.name}
            sys_menu=RbacMenu(company=c)
            menuitems=sys_menu.get_menu()    
            return render(request,'rbac/create_company_menu.html', {'menuitems':menuitems,'company':company} )   
        else:
            r=json.loads(request.body) 
            ids="("+','.join(r['menu_ids'])+")"
            cid=str(r['company_id'])
            sOrder=" order by priority,id"
            cur=connection.cursor()     
            s="insert into rbac_companymenu(title,icon,priority,level,url,remark,company_id,id0,parent_id0) "+\
                "select title,icon,priority,level,url,remark,"+cid+",id,parent_id "+\
                "from rbac_menu where id in "+ids+sOrder
            cur.execute(s)
            s="update rbac_companymenu m set parent_id="+\
                "(select id from rbac_companymenu where company_id="+cid+" "+\
                    "and id0=m.parent_id0) "+\
                "where company_id="+cid
            cur.execute(s)
            #2021-09-13 添加系统管理员 group_id=4
            s="INSERT INTO rbac_cgroupmenu(menus,cgroup_id,company_id) select "+\
                "array_to_json(array(select id from logistics.rbac_companymenu where company_id="+cid+")),"+\
                "(SELECT id FROM company_cgroup WHERE company_id="+cid+" and group_id=4),"+cid            
            cur.execute(s)   
            cur.close()
            return JsonResponse({'e':''})



    #2021-09-15
    elif what=='cgroup_menu':
        if request.method=='GET':
            id=request.GET.get('cgroup_id','')
            if not id:
                cgroups=[]                
                for g in CGroup.objects.filter(company_id=u.ancestor_id):
                    cgroups.append({'id':g.id,'name':g.name})
                return render(request,'rbac/list_cgroup_menu.html', {'cgroups':cgroups})
            else:
                g=CGroup.objects.get(id=int(id))                    
                m=MenuCompany(company_id=str(u.ancestor_id),cgroup_id=int(id))      
                menuitems=m.get_cgroup_menu()                
                return render(request,'rbac/edit_cgroup_menu.html',{'menuitems':menuitems,'cgroup':g})                
        else:
            r=json.loads(request.body)   
            cgroup_id=r['cgroup_id']
            auth_ids=r['auth_ids']    
            gs=CGroupMenu.objects.filter(cgroup_id=int(cgroup_id))
            if gs:
                g=gs[0]
            else:
                g=CGroupMenu(company_id=u.ancestor_id,cgroup_id=int(cgroup_id))
            auth_ids = [ int(x) for x in auth_ids ]            
            g.menus=auth_ids
            g.save()
            data={'e':''}               
            return JsonResponse(data)     
    elif what=='cgroup_edit':
        if request.method=='GET':           
            id=request.GET.get('id','')
            if id:
                obj=CGroup.objects.get(id=int(id))
                form=CGroupForm(instance=obj)
                return render(request,'company/edit_cgroup.html',{'form':form})
            else:
                cur=connection.cursor()
                data=[]
                clmns=['功能组别','停用','备注说明']
                cur.execute("SELECT id,name,coalesce(remark,''),case when is_delete then '是' else '否' end,"+\
                    "to_char(tm_edit,'yyyy-mm-dd HH24:HI:SS') FROM company_cgroup "+\
                    "where company_id="+str(request.user.ancestor_id)+" order by name")
                for r in cur.fetchall():
                    a='<a href="/company/orginazition/cgroup/?id='+str(r[0])+'">'+r[1]+'</a>'
                    data.append([ a ,r[3],r[2] ])
                cur.close()
                return render(request,'company/list_cgroup.html',{'clmns':clmns,'data':data})
        else:
            obj=CGroup.objects.get(id=int(id))
            form=CGroupForm(request.POST,instance=obj)
            is_saved=False
           
            if form.is_valid():
                form.save()
                is_saved=True
            return render(request,'company/edit_cgroup.html',{'form':form,'is_saved':is_saved})
           













from taskman import tasks
#2021-12-02 测试
def add_test(request):
    result = tasks.add.delay(47, 36)

    
  
    
    
    return HttpResponse(result)

