import React, { useEffect, useState, useMemo } from 'react';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import { Input } from '@/components/ui/input';
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion';
import { useToast } from '@/components/ui/use-toast';
import { Loader2, Folder, Key, Search, Shield } from 'lucide-react';
import { getPermissionTree } from '../service';

interface PermissionDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onConfirm: (menuIds: number[], permissionIds: number[]) => Promise<void>;
  defaultMenuIds?: number[];
  defaultPermissionIds?: number[];
}

interface Permission {
  id: number;
  code: string;
  name: string;
  type: string;
  sort: number;
}

interface MenuItem {
  id: number;
  name: string;
  path: string;
  icon: string;
  type: number;
  permissionChildren: MenuItem[];
  permissions: Permission[];
}

/**
 * 权限分配对话框（使用 Accordion 实现树形结构）
 * 
 * 级联选择规则（与后端一致）：
 * 1. ✅ 勾选权限 → 自动勾选所属菜单及所有父菜单
 * 2. ✅ 勾选菜单 → 自动勾选该菜单、所有子菜单、所有父菜单
 * 3. ✅ 取消菜单 → 自动取消该菜单及所有子菜单的菜单ID和权限ID
 * 4. ✅ 半选状态 → 菜单部分权限被选中时显示半选状态
 * 
 * 示例：
 * - 勾选"用户管理"权限 → 自动勾选"用户管理"菜单 + "系统管理"父菜单
 * - 勾选"用户管理"菜单 → 自动勾选"系统管理"父菜单 + 所有子菜单和权限
 * - 提交时同时包含菜单ID和权限ID，后端有兜底逻辑确保数据完整性
 */
const PermissionDialog: React.FC<PermissionDialogProps> = ({
  open,
  onOpenChange,
  onConfirm,
  defaultMenuIds = [],
  defaultPermissionIds = []
}) => {
  const { toast } = useToast();
  const [loading, setLoading] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [menuTree, setMenuTree] = useState<MenuItem[]>([]);
  const [checkedMenuIds, setCheckedMenuIds] = useState<number[]>([]);
  const [checkedPermissionIds, setCheckedPermissionIds] = useState<number[]>([]);
  const [searchText, setSearchText] = useState('');

  useEffect(() => {
    const loadPermissionTree = async () => {
      if (!open) return;
      
      setLoading(true);
      try {
        const response = await getPermissionTree();
        setMenuTree(response);
        setCheckedMenuIds(defaultMenuIds);
        setCheckedPermissionIds(defaultPermissionIds);
      } catch (error) {
        console.error('获取权限树失败:', error);
        toast({
          title: '加载失败',
          description: error instanceof Error ? error.message : '未知错误',
          variant: 'destructive'
        });
      } finally {
        setLoading(false);
      }
    };

    loadPermissionTree();
  }, [open, defaultMenuIds, defaultPermissionIds]);

  // 获取某个菜单的所有父菜单ID（递归向上查找）
  const getParentMenuIds = (targetMenuId: number, menus: MenuItem[], parentIds: number[] = []): number[] => {
    for (const menu of menus) {
      if (menu.id === targetMenuId) {
        return parentIds;
      }
      if (menu.permissionChildren && menu.permissionChildren.length > 0) {
        const found = menu.permissionChildren.some(child => child.id === targetMenuId);
        if (found) {
          return [...parentIds, menu.id];
        }
        const result = getParentMenuIds(targetMenuId, menu.permissionChildren, [...parentIds, menu.id]);
        if (result.length > 0) {
          return result;
        }
      }
    }
    return [];
  };

  // 根据权限ID找到它所属的菜单
  const getMenuByPermissionId = (permissionId: number, menus: MenuItem[]): MenuItem | null => {
    for (const menu of menus) {
      if (menu.permissions?.some(p => p.id === permissionId)) {
        return menu;
      }
      if (menu.permissionChildren && menu.permissionChildren.length > 0) {
        const result = getMenuByPermissionId(permissionId, menu.permissionChildren);
        if (result) return result;
      }
    }
    return null;
  };

  // 切换菜单选中状态
  const handleToggleMenuId = (menuId: number) => {
    setCheckedMenuIds(prev =>
      prev.includes(menuId)
        ? prev.filter(id => id !== menuId)
        : [...prev, menuId]
    );
  };

  // 切换权限选中状态（带级联）
  const handleTogglePermission = (permissionId: number) => {
    setCheckedPermissionIds(prev => {
      if (prev.includes(permissionId)) {
        // 取消勾选权限
        return prev.filter(id => id !== permissionId);
      } else {
        // 勾选权限：自动勾选所属菜单及其所有父菜单
        const menu = getMenuByPermissionId(permissionId, menuTree);
        if (menu) {
          const parentIds = getParentMenuIds(menu.id, menuTree);
          const allParentMenuIds = [...parentIds, menu.id];
          
          // 添加所有父菜单ID
          setCheckedMenuIds(prevMenuIds => {
            const newMenuIds = new Set(prevMenuIds);
            allParentMenuIds.forEach(id => newMenuIds.add(id));
            return Array.from(newMenuIds);
          });
        }
        
        // 添加权限ID
        return [...prev, permissionId];
      }
    });
  };

  // 递归获取菜单下所有子菜单ID（包括自己）
  const getAllMenuIds = (menu: MenuItem): number[] => {
    const ids: number[] = [menu.id];
    if (menu.permissionChildren) {
      menu.permissionChildren.forEach(child => {
        ids.push(...getAllMenuIds(child));
      });
    }
    return ids;
  };

  // 递归获取菜单下所有权限ID
  const getAllPermissionIds = (menu: MenuItem): number[] => {
    const ids: number[] = [];
    if (menu.permissions) {
      ids.push(...menu.permissions.map(p => p.id));
    }
    if (menu.permissionChildren) {
      menu.permissionChildren.forEach(child => {
        ids.push(...getAllPermissionIds(child));
      });
    }
    return ids;
  };

  // 检查菜单是否应该显示为选中状态
  const isMenuChecked = (menu: MenuItem): boolean => {
    // 如果菜单ID在checkedMenuIds中，直接返回true
    if (checkedMenuIds.includes(menu.id)) {
      return true;
    }
    // 否则检查菜单下所有权限是否都被选中
    const allPermissionIds = getAllPermissionIds(menu);
    return allPermissionIds.length > 0 && allPermissionIds.every(id => checkedPermissionIds.includes(id));
  };

  // 检查菜单下所有权限是否全选（用于判断取消逻辑）
  const isMenuFullyChecked = (menu: MenuItem): boolean => {
    const allIds = getAllPermissionIds(menu);
    return allIds.length > 0 && allIds.every(id => checkedPermissionIds.includes(id));
  };

  // 检查菜单下是否有部分权限选中（用于半选状态）
  const isMenuPartiallyChecked = (menu: MenuItem): boolean => {
    // 如果菜单ID在checkedMenuIds中，不显示半选
    if (checkedMenuIds.includes(menu.id)) {
      return false;
    }
    // 检查是否有部分权限被选中
    const allIds = getAllPermissionIds(menu);
    const checkedCount = allIds.filter(id => checkedPermissionIds.includes(id)).length;
    return checkedCount > 0 && checkedCount < allIds.length;
  };

  // 切换菜单的全选/取消全选（带级联）
  const handleToggleMenu = (menu: MenuItem) => {
    const allPermissionIds = getAllPermissionIds(menu);
    const allMenuIds = getAllMenuIds(menu);
    // 使用 isMenuChecked 来判断当前状态
    const currentChecked = isMenuChecked(menu);
    
    if (currentChecked) {
      // 取消全选：移除菜单ID和权限ID
      setCheckedMenuIds(prev => prev.filter(id => !allMenuIds.includes(id)));
      setCheckedPermissionIds(prev => prev.filter(id => !allPermissionIds.includes(id)));
    } else {
      // 全选：添加菜单ID、权限ID，并自动勾选所有父菜单
      const parentIds = getParentMenuIds(menu.id, menuTree);
      
      setCheckedMenuIds(prev => {
        const newIds = new Set(prev);
        // 添加当前菜单及所有子菜单ID
        allMenuIds.forEach(id => newIds.add(id));
        // 添加所有父菜单ID
        parentIds.forEach(id => newIds.add(id));
        return Array.from(newIds);
      });
      
      setCheckedPermissionIds(prev => {
        const newIds = new Set(prev);
        // 添加当前菜单及所有子菜单的权限ID
        allPermissionIds.forEach(id => newIds.add(id));
        return Array.from(newIds);
      });
    }
  };

  // 筛选菜单树（根据搜索文本）
  const filteredMenuTree = useMemo(() => {
    if (!searchText.trim()) return menuTree;
    
    const filterMenu = (menu: MenuItem): MenuItem | null => {
      const matchesName = menu.name.toLowerCase().includes(searchText.toLowerCase());
      const matchingPermissions = menu.permissions?.filter(p => 
        p.name.toLowerCase().includes(searchText.toLowerCase())
      ) || [];
      const matchingChildren = menu.permissionChildren
        ?.map(child => filterMenu(child))
        .filter(Boolean) as MenuItem[] || [];
      
      if (matchesName || matchingPermissions.length > 0 || matchingChildren.length > 0) {
        return {
          ...menu,
          permissions: matchingPermissions,
          permissionChildren: matchingChildren
        };
      }
      return null;
    };
    
    return menuTree.map(menu => filterMenu(menu)).filter(Boolean) as MenuItem[];
  }, [menuTree, searchText]);

  // 统计信息
  const statistics = useMemo(() => {
    const countPermissions = (menus: MenuItem[]): number => {
      return menus.reduce((sum, menu) => {
        return sum + (menu.permissions?.length || 0) + countPermissions(menu.permissionChildren || []);
      }, 0);
    };
    const total = countPermissions(menuTree);
    const selected = checkedPermissionIds.length;
    const percentage = total > 0 ? Math.round((selected / total) * 100) : 0;
    return { total, selected, percentage };
  }, [menuTree, checkedPermissionIds]);

  // 渲染菜单项
  const renderMenuItem = (menu: MenuItem, level: number = 0): React.ReactNode => {
    const hasChildren = menu.permissionChildren && menu.permissionChildren.length > 0;
    const hasPermissions = menu.permissions && menu.permissions.length > 0;
    const isChecked = isMenuChecked(menu);
    const isPartial = isMenuPartiallyChecked(menu);

    if (!hasChildren && !hasPermissions) {
      return null;
    }

    return (
      <div key={menu.id} className={level > 0 ? 'ml-4' : 'mb-2'}>
        {hasChildren ? (
          <AccordionItem value={`menu-${menu.id}`} className="border-b-0">
            <AccordionTrigger className="py-2 hover:no-underline hover:bg-muted/50 px-2 rounded">
              <div className="flex items-center gap-2 flex-1">
                <Checkbox
                  checked={isChecked}
                  ref={(el) => {
                    if (el) {
                      // @ts-ignore - 设置 indeterminate 状态
                      el.indeterminate = isPartial && !isChecked;
                    }
                  }}
                  onCheckedChange={() => handleToggleMenu(menu)}
                  onClick={(e) => e.stopPropagation()}
                />
                <Folder className="h-4 w-4 text-blue-600" />
                <span className="text-sm font-medium">{menu.name}</span>
              </div>
            </AccordionTrigger>
            <AccordionContent className="pb-0 pt-2">
              {/* 渲染当前菜单的权限 */}
              {hasPermissions && (
                <div className="grid grid-cols-4 gap-x-3 gap-y-1 mb-2 ml-8">
                  {menu.permissions.map(permission => (
                    <div key={permission.id} className="flex items-center gap-1.5 py-1.5 px-2 rounded hover:bg-muted/50">
                      <Checkbox
                        id={`permission-${permission.id}`}
                        checked={checkedPermissionIds.includes(permission.id)}
                        onCheckedChange={() => handleTogglePermission(permission.id)}
                      />
                      <label
                        htmlFor={`permission-${permission.id}`}
                        className="text-sm cursor-pointer flex items-center gap-1.5 flex-1"
                      >
                        <Key className="h-3 w-3 text-muted-foreground flex-shrink-0" />
                        <span className="truncate">{permission.name}</span>
                      </label>
                    </div>
                  ))}
                </div>
              )}
              {/* 递归渲染子菜单 */}
              <Accordion type="multiple" className="w-full">
                {menu.permissionChildren.map(child => renderMenuItem(child, level + 1))}
              </Accordion>
            </AccordionContent>
          </AccordionItem>
        ) : (
          // 没有子菜单，只显示权限列表
          <div className="py-2 px-2">
            <div className="flex items-center gap-2 mb-2">
              <Checkbox
                checked={isChecked}
                ref={(el) => {
                  if (el) {
                    // @ts-ignore
                    el.indeterminate = isPartial && !isChecked;
                  }
                }}
                onCheckedChange={() => handleToggleMenu(menu)}
              />
              <Folder className="h-4 w-4 text-blue-600" />
              <span className="text-sm font-medium">{menu.name}</span>
            </div>
            {hasPermissions && (
              <div className="grid grid-cols-4 gap-x-3 gap-y-1 ml-8">
                {menu.permissions.map(permission => (
                  <div key={permission.id} className="flex items-center gap-1.5 py-1.5 px-2 rounded hover:bg-muted/50">
                    <Checkbox
                      id={`permission-${permission.id}`}
                      checked={checkedPermissionIds.includes(permission.id)}
                      onCheckedChange={() => handleTogglePermission(permission.id)}
                    />
                    <label
                      htmlFor={`permission-${permission.id}`}
                      className="text-sm cursor-pointer flex items-center gap-1.5 flex-1"
                    >
                      <Key className="h-3 w-3 text-muted-foreground flex-shrink-0" />
                      <span className="truncate">{permission.name}</span>
                    </label>
                  </div>
                ))}
              </div>
            )}
          </div>
        )}
      </div>
    );
  };

  const handleSubmit = async () => {
    setSubmitting(true);
    try {
      await onConfirm(checkedMenuIds, checkedPermissionIds);
      onOpenChange(false);
    } catch (error) {
      console.error('分配权限失败:', error);
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-[700px] max-h-[85vh] overflow-hidden flex flex-col p-0">
        <DialogHeader className="px-6 pt-6 pb-4 border-b">
          <DialogTitle className="flex items-center justify-between pr-8">
            <span>分配权限</span>
            {!loading && (
              <span className="text-sm font-normal text-muted-foreground">
                已选择 <span className="font-semibold text-foreground">{statistics.selected}</span> / {statistics.total} 项权限
              </span>
            )}
          </DialogTitle>
        </DialogHeader>

        {/* 搜索框 */}
        {!loading && menuTree.length > 0 && (
          <div className="px-6 py-3 border-b bg-muted/30">
            <div className="relative">
              <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
              <Input
                placeholder="搜索权限名称或菜单名称..."
                value={searchText}
                onChange={(e) => setSearchText(e.target.value)}
                className="pl-10"
              />
            </div>
          </div>
        )}

        {/* 权限树 */}
        <div className="overflow-y-auto flex-1 px-6 py-4">
          {loading ? (
            <div className="flex flex-col items-center justify-center py-16">
              <Loader2 className="h-8 w-8 animate-spin text-muted-foreground mb-3" />
              <span className="text-sm text-muted-foreground">正在加载权限数据...</span>
            </div>
          ) : filteredMenuTree.length > 0 ? (
            <Accordion type="multiple" className="w-full">
              {filteredMenuTree.map(menu => renderMenuItem(menu))}
            </Accordion>
          ) : searchText ? (
            <div className="flex flex-col items-center justify-center py-16 text-muted-foreground">
              <Search className="h-12 w-12 mb-3 opacity-30" />
              <p className="text-sm">未找到匹配的权限</p>
              <p className="text-xs mt-1">请尝试其他关键词</p>
            </div>
          ) : (
            <div className="flex flex-col items-center justify-center py-16 text-muted-foreground">
              <Shield className="h-12 w-12 mb-3 opacity-30" />
              <p className="text-sm">暂无权限数据</p>
            </div>
          )}
        </div>

        <div className="px-6 py-4 border-t bg-muted/30 flex justify-end gap-2">
          <Button 
            type="button"
            variant="outline" 
            onClick={() => onOpenChange(false)} 
            disabled={submitting}
          >
                取消
              </Button>
          <Button 
            type="button"
            onClick={handleSubmit} 
            disabled={submitting || loading}
          >
                {submitting ? '保存中...' : '确定'}
              </Button>
            </div>
      </DialogContent>
    </Dialog>
  );
};

export default PermissionDialog;
