import {  useEffect, useMemo, useState} from "react";
import {App, Button, Checkbox, Collapse, Form, GetProp, Input} from "antd";
import {useFetch} from "@common/hooks/http.ts";
import {BasicResponse, STATUS_CODE} from "@common/const/const.ts";
import WithPermission from "@common/components/aoplatform/WithPermission.tsx";
import { useNavigate, useParams } from "react-router-dom";
import { RouterParams } from "@core/components/aoplatform/RenderRoutes.tsx";
import { LeftOutlined } from "@ant-design/icons";

type PermissionItem = {
    name:string 
    cname:string 
    value:string
}

type PermissionClassify = PermissionItem & {children : ( PermissionItem & {dependents:string[]})[]}

type RolePermissionItem = PermissionItem & {
    children:PermissionClassify[]}


type DependenciesMapType = Map<string, {dependents:string[], control:string[]}>

type PermissionCollapseProps = {
    id?: string;
    value?: string[];
    onChange?: (value:string[]) => void;
    permissionTemplate:RolePermissionItem[]
    dependenciesMap?: DependenciesMapType
}

type PermissionInfo = {
    permit: string[]
    description: string
    update_time: string
    create_time: string
    name: string
}

const PermissionContent = ({permits,onChange,value=[],id,dependenciesMap}:{permits:PermissionClassify[],dependenciesMap:DependenciesMapType,value:string[],id:string, onChange?: (value:string[]) => void;})=>{
            
    const onSingleCheckboxChange: GetProp<typeof Checkbox, 'onChange'> = (e) => {
        if(e.target.checked){
            onChange?.(Array.from(new Set([...value, e.target.id, ...(dependenciesMap?.get(e.target.id!)?.dependents || [])] as string[])))
        }else{
            const cancelValue = [...dependenciesMap?.get(e.target.id!)?.control || [], e.target.id]
            onChange?.(value.filter(x=>!cancelValue.includes(x)))
        }
    };
    
    return (
        <div id={id} className="flex flex-col gap-btnbase p-btnbase">
        {
            permits.map((item:PermissionClassify)=>(
                <>
                    <div className="flex flex-col gap-btnbase" key={`group-${item.name}`}>
                        {item.cname !== '' && <p className="">{item.cname}</p>}
                        <div className=" pl-[20px]">
                            {item.children.map(x=><Checkbox id={x.value} key={x.value} checked={value && value.length > 0 && value.indexOf(x.value)>-1} onChange={onSingleCheckboxChange}>{x.cname}</Checkbox>)}
                        </div>
                    </div>
                </>
            ))
        }</div>
    )
}
    // 自定义表单控件
    const PermissionCollapse:React.FC<PermissionCollapseProps>  = (props)=>{
        const { id, value = [], onChange,permissionTemplate ,dependenciesMap} = props;
        const [openCollapses, setOpenCollapses] = useState<string[]>([])
        
        const items = useMemo(()=>{
            const generatePermissionItem = (permissionItem:RolePermissionItem[])=> permissionItem.map((item:RolePermissionItem)=>({
                        key:item.name,
                        label:item.cname,
                        children:<PermissionContent value={value} permits={item.children} onChange={(e)=>onChange?.(e)} id={id!} dependenciesMap={dependenciesMap!}/>
                    }))
            return  permissionTemplate && permissionTemplate.length > 0 ? generatePermissionItem(permissionTemplate) : []
        },[permissionTemplate,value])

        useEffect(()=>{
            permissionTemplate && setOpenCollapses(permissionTemplate?.map(x=>x.name))
        },[permissionTemplate])
        
    const onCollapseChange = (keys: string | string[]) => {
        setOpenCollapses(keys as string[])
    };

    return <Collapse items={items} activeKey={openCollapses} onChange={onCollapseChange} />
    }


const RoleConfig = ()=>{
    const { message } = App.useApp()
    const [form] = Form.useForm();
    // const [formData, dispatch] = useReducer(formReducer, {});
    // const [dataSource,setDataSource] = useState<RoleNodeModalTableListItem[]>([])
    const {fetchData} = useFetch()
    const navigateTo = useNavigate()
    const { roleType, roleId} = useParams<RouterParams>()
    const [permissionTemplate, setPermissionTemplate] = useState<RolePermissionItem[]>()
    const [dependenciesMap, setDependenciesMap] = useState<DependenciesMapType>()
    const APP_MODE = import.meta.env.VITE_APP_MODE;


    const generateDependenciesMap = (data:RolePermissionItem[])=>{
        const map = new Map<string, {dependents:string[], control:string[]}>()
        data.forEach((item:RolePermissionItem)=>{
            item.children.forEach((child:PermissionClassify)=>{
                child.children.forEach((permission:PermissionItem & {dependents:string[]})=>{

                    if (permission.dependents && permission.dependents.length > 0) {
                        // 获取当前权限的依赖
                        const currentDependents = map.get(permission.value);
                        if (currentDependents) {
                            currentDependents.dependents.push(...permission.dependents);
                        } else {
                            map.set(permission.value, { dependents: [...permission.dependents], control: [] });
                        }
    
                        // 更新依赖项的控制项
                        permission.dependents.forEach((dependent: string) => {
                            const dependentEntry = map.get(dependent);
                            if (dependentEntry) {
                                dependentEntry.control.push(permission.value);
                            } else {
                                map.set(dependent, { dependents: [], control: [permission.value] });
                            }
                        });
                    }
                })
            })
        })
        setDependenciesMap(map)
    }
    
    const generateNewPermit:(data:RolePermissionItem[])=>RolePermissionItem[] = (data:RolePermissionItem[]) =>{
       return data.map((item:RolePermissionItem)=>({
            ...item,children:item.children.map((child:PermissionClassify)=>({
                ...child,
                children:child.children.map((permission:PermissionItem & {dependents:string[]})=>({
                    ...permission, value:`${roleType}.${item.value}.${child.value}.${permission.value}`
                }))
            }))
        }))
    }

    const getPermissionTemplate = ()=>{
        return fetchData<BasicResponse<{permits:RolePermissionItem[]}>>(`${roleType}/role/template`,{method:'GET'}).then(response=>{
            const {code,data,msg} = response
            if(code === STATUS_CODE.SUCCESS){
                const newPermits = generateNewPermit(data.permits)
                generateDependenciesMap(newPermits)
                setPermissionTemplate(newPermits)
                console.log(newPermits)
            }else{
                console.log(message)
                message.error(msg || '获取权限模板失败')
            }
        })
    }

    const getPermissionInfo = ()=>{
        fetchData<BasicResponse<{role:PermissionInfo}>>(`${roleType}/role`,{method:'GET',eoParams:{role:roleId}}).then(response=>{
            const {code,data,msg} = response
            if(code === STATUS_CODE.SUCCESS){
                message.success(msg || '操作成功！')
                form.setFieldsValue({name:data.role.name,permits:data.role.permit})
                return Promise.resolve(true)
            }else{
                message.error(msg || '操作失败')
                return Promise.reject(msg || '操作失败')
            }
        }).catch((errInfo)=>Promise.reject(errInfo))
    }

    useEffect(() => {
        getPermissionTemplate()
        form.setFieldsValue({name:'',permits:[]})
        if(roleId){
            getPermissionInfo()
        }
    }, []);

    const onFinish =async() => {
            const body = await form.validateFields()

            return fetchData<BasicResponse<null>>(`${roleType}/role`,{method:roleId === undefined? 'POST' : 'PUT',eoBody:({...body}),...(roleId !== undefined?{eoParams:{role:roleId}}:{})}).then(response=>{
                const {code,msg} = response
                if(code === STATUS_CODE.SUCCESS){
                    message.success(msg || '操作成功！')
                    return Promise.resolve(true)
                }else{
                    message.error(msg || '操作失败')
                    return Promise.reject(msg || '操作失败')
                }
            }).catch((errInfo)=>Promise.reject(errInfo))
    };

    return  (<div className="h-full flex flex-col overflow-hidden">
     <a className="m-btnbase block" onClick={()=>navigateTo(-1)}> <LeftOutlined />返回</a>
            <WithPermission access={roleId !== undefined  ? `system.organization.role.${roleType}.edit`: `system.organization.role.${roleType}.add`}>
                <Form
                    id="permission"
                    layout='vertical'
                    labelAlign='left'
                    scrollToFirstError
                    form={form}
                    className="mx-auto w-full flex-1 no-bg-form overflow-hidden "
                    name="rolePermissionConfig"
                    onFinish={onFinish}
                    autoComplete="off"
                >
                    <div className="flex flex-col h-full">
                    <Form.Item
                        className=" m-btnbase"
                        name="name"
                        rules={[{ required: true, message: '必填项',whitespace:true  }]}
                    >
                        <Input className="w-INPUT_NORMAL" placeholder="请输入角色名称"/>
                    </Form.Item>
                    <Form.Item
                        name="permits"
                        className="m-btnbase flex-1 overflow-auto"
                    >
                        <PermissionCollapse permissionTemplate={permissionTemplate!} dependenciesMap={dependenciesMap} />
                    </Form.Item>

                    {APP_MODE === 'pro' && <div className="p-btnbase">
                        <WithPermission access={roleId === undefined ?`system.organization.role.${roleType}.edit`:`system.organization.role.${roleType}.add`}>
                            <Button type="primary" htmlType="submit">
                                保存
                            </Button>
                        </WithPermission>
                        <Button className="ml-btnrbase" type="default" onClick={() => navigateTo(-1)}>
                                取消
                        </Button>
                    </div>}
                    </div>
             </Form>
            </WithPermission> 
    </div>)
}
export default RoleConfig