// components/permissions/permission-group-manager.tsx

"use client";

import { useState, useEffect } from "react";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Badge } from "@/components/ui/badge";
import { Checkbox } from "@/components/ui/checkbox";
import { ScrollArea } from "@/components/ui/scroll-area";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "@/components/ui/accordion";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { 
  Shield,
  Plus,
  Edit,
  Trash2,
  Copy,
  Users,
  Key,
  MoreVertical,
  Package,
  ChevronRight,
  Loader2,
  Search
} from "lucide-react";
import { toast } from "sonner";
import { cn } from "@/lib/utils";
import {
  getPermissionGroups,
  createPermissionGroup,
  updatePermissionGroup,
  deletePermissionGroup,
  getGroupPermissions,
  updateGroupPermissions,
  clonePermissionGroup,
  getGroupAssignments,
} from "@/lib/permissions/permission-group-actions";

interface PermissionGroup {
  id: number;
  groupKey: string;
  name: string;
  description?: string;
  domain?: string;
  isActive: boolean;
  permissionCount: number;
  roleCount: number;
  userCount: number;
  createdAt: Date;
  updatedAt: Date;
}

interface Permission {
  id: number;
  permissionKey: string;
  name: string;
  description?: string;
  resource: string;
  action: string;
  permissionType: string;
  scope: string;
}

export function PermissionGroupManager() {
  const [groups, setGroups] = useState<PermissionGroup[]>([]);
  const [selectedGroup, setSelectedGroup] = useState<PermissionGroup | null>(null);
  const [groupPermissions, setGroupPermissions] = useState<Permission[]>([]);
  const [availablePermissions, setAvailablePermissions] = useState<Permission[]>([]);
  const [searchQuery, setSearchQuery] = useState("");
  const [loading, setLoading] = useState(false);
  const [createDialogOpen, setCreateDialogOpen] = useState(false);
  const [editingGroup, setEditingGroup] = useState<PermissionGroup | null>(null);
  const [permissionDialogOpen, setPermissionDialogOpen] = useState(false);

  useEffect(() => {
    loadGroups();
  }, []);

  useEffect(() => {
    if (selectedGroup) {
      loadGroupPermissions(selectedGroup.id);
    }
  }, [selectedGroup]);

  const loadGroups = async () => {
    setLoading(true);
    try {
      const data = await getPermissionGroups();
      setGroups(data);
    } catch (error) {
      toast.error("권한 그룹을 불러오는데 실패했습니다.");
    } finally {
      setLoading(false);
    }
  };

  const loadGroupPermissions = async (groupId: number) => {
    try {
      const data = await getGroupPermissions(groupId);
      setGroupPermissions(data.permissions);
      setAvailablePermissions(data.availablePermissions);
    } catch (error) {
      toast.error("권한 정보를 불러오는데 실패했습니다.");
    }
  };

  const handleDelete = async (id: number) => {
    if (!confirm("이 권한 그룹을 삭제하시겠습니까? 관련된 모든 할당이 제거됩니다.")) {
      return;
    }

    try {
      await deletePermissionGroup(id);
      toast.success("권한 그룹이 삭제되었습니다.");
      if (selectedGroup?.id === id) {
        setSelectedGroup(null);
      }
      loadGroups();
    } catch (error) {
      toast.error("권한 그룹 삭제에 실패했습니다.");
    }
  };

  const handleClone = async (group: PermissionGroup) => {
    try {
      const cloned = await clonePermissionGroup(group.id);
      toast.success(`"${cloned.name}" 그룹이 생성되었습니다.`);
      loadGroups();
    } catch (error) {
      toast.error("권한 그룹 복제에 실패했습니다.");
    }
  };

  // 검색 필터링
  const filteredGroups = groups.filter(group =>
    group.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
    group.groupKey.toLowerCase().includes(searchQuery.toLowerCase()) ||
    group.description?.toLowerCase().includes(searchQuery.toLowerCase())
  );

  return (
    <div className="space-y-6">
      <Card>
        <CardHeader>
          <div className="flex items-center justify-between">
            <div>
              <CardTitle>권한 그룹</CardTitle>
              <CardDescription>
                관련된 권한들을 그룹으로 묶어 효율적으로 관리합니다.
              </CardDescription>
            </div>
            <Button onClick={() => setCreateDialogOpen(true)}>
              <Plus className="mr-2 h-4 w-4" />
              그룹 생성
            </Button>
          </div>
        </CardHeader>
        <CardContent>
          {/* 검색 */}
          <div className="mb-4">
            <div className="relative">
              <Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
              <Input
                placeholder="그룹명, 키로 검색..."
                value={searchQuery}
                onChange={(e) => setSearchQuery(e.target.value)}
                className="pl-8"
              />
            </div>
          </div>

          {/* 그룹 목록 */}
          <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
            {filteredGroups.map(group => (
              <GroupCard
                key={group.id}
                group={group}
                isSelected={selectedGroup?.id === group.id}
                onSelect={() => setSelectedGroup(group)}
                onEdit={() => setEditingGroup(group)}
                onClone={() => handleClone(group)}
                onDelete={() => handleDelete(group.id)}
                onManagePermissions={() => {
                  setSelectedGroup(group);
                  setPermissionDialogOpen(true);
                }}
              />
            ))}
          </div>
        </CardContent>
      </Card>

      {/* 선택된 그룹 상세 */}
      {selectedGroup && (
        <GroupDetailCard
          group={selectedGroup}
          permissions={groupPermissions}
          onEditPermissions={() => setPermissionDialogOpen(true)}
        />
      )}

      {/* 그룹 생성/수정 다이얼로그 */}
      <GroupFormDialog
        open={createDialogOpen || !!editingGroup}
        onOpenChange={(open) => {
          if (!open) {
            setCreateDialogOpen(false);
            setEditingGroup(null);
          }
        }}
        group={editingGroup}
        onSuccess={() => {
          setCreateDialogOpen(false);
          setEditingGroup(null);
          loadGroups();
        }}
      />

      {/* 권한 관리 다이얼로그 */}
      {selectedGroup && (
        <GroupPermissionsDialog
          open={permissionDialogOpen}
          onOpenChange={setPermissionDialogOpen}
          group={selectedGroup}
          groupPermissions={groupPermissions}
          availablePermissions={availablePermissions}
          onSuccess={() => {
            loadGroupPermissions(selectedGroup.id);
            loadGroups();
          }}
        />
      )}
    </div>
  );
}

// 그룹 카드 컴포넌트
function GroupCard({
  group,
  isSelected,
  onSelect,
  onEdit,
  onClone,
  onDelete,
  onManagePermissions,
}: {
  group: PermissionGroup;
  isSelected: boolean;
  onSelect: () => void;
  onEdit: () => void;
  onClone: () => void;
  onDelete: () => void;
  onManagePermissions: () => void;
}) {
  return (
    <Card
      className={cn(
        "cursor-pointer transition-colors",
        isSelected && "ring-2 ring-primary"
      )}
      onClick={onSelect}
    >
      <CardHeader className="pb-3">
        <div className="flex items-start justify-between">
          <div>
            <CardTitle className="text-lg">{group.name}</CardTitle>
            <div className="flex items-center gap-2 mt-1">
              <code className="text-xs bg-muted px-1 py-0.5 rounded">
                {group.groupKey}
              </code>
              {group.domain && (
                <Badge variant="outline" className="text-xs">
                  {group.domain}
                </Badge>
              )}
            </div>
          </div>
          <DropdownMenu>
            <DropdownMenuTrigger asChild onClick={(e) => e.stopPropagation()}>
              <Button variant="ghost" className="h-8 w-8 p-0">
                <MoreVertical className="h-4 w-4" />
              </Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end">
              <DropdownMenuItem onClick={(e) => {
                e.stopPropagation();
                onManagePermissions();
              }}>
                <Key className="mr-2 h-4 w-4" />
                권한 관리
              </DropdownMenuItem>
              <DropdownMenuItem onClick={(e) => {
                e.stopPropagation();
                onEdit();
              }}>
                <Edit className="mr-2 h-4 w-4" />
                수정
              </DropdownMenuItem>
              <DropdownMenuItem onClick={(e) => {
                e.stopPropagation();
                onClone();
              }}>
                <Copy className="mr-2 h-4 w-4" />
                복제
              </DropdownMenuItem>
              <DropdownMenuSeparator />
              <DropdownMenuItem
                onClick={(e) => {
                  e.stopPropagation();
                  onDelete();
                }}
                className="text-destructive"
              >
                <Trash2 className="mr-2 h-4 w-4" />
                삭제
              </DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>
        </div>
      </CardHeader>
      <CardContent>
        {group.description && (
          <p className="text-sm text-muted-foreground mb-3">
            {group.description}
          </p>
        )}
        <div className="flex items-center gap-4 text-sm">
          <div className="flex items-center gap-1">
            <Key className="h-3 w-3" />
            <span>{group.permissionCount}개 권한</span>
          </div>
          <div className="flex items-center gap-1">
            <Users className="h-3 w-3" />
            <span>{group.roleCount}개 역할</span>
          </div>
          <div className="flex items-center gap-1">
            <Shield className="h-3 w-3" />
            <span>{group.userCount}명</span>
          </div>
        </div>
      </CardContent>
    </Card>
  );
}

// 그룹 상세 카드
function GroupDetailCard({
  group,
  permissions,
  onEditPermissions,
}: {
  group: PermissionGroup;
  permissions: Permission[];
  onEditPermissions: () => void;
}) {
  // 리소스별로 권한 그룹화
  const groupedPermissions = permissions.reduce((acc, perm) => {
    const resource = perm.resource;
    if (!acc[resource]) acc[resource] = [];
    acc[resource].push(perm);
    return acc;
  }, {} as Record<string, Permission[]>);

  return (
    <Card>
      <CardHeader>
        <div className="flex items-center justify-between">
          <div>
            <CardTitle>{group.name} 권한 목록</CardTitle>
            <CardDescription>이 그룹에 포함된 모든 권한입니다.</CardDescription>
          </div>
          <Button onClick={onEditPermissions}>
            <Edit className="mr-2 h-4 w-4" />
            권한 편집
          </Button>
        </div>
      </CardHeader>
      <CardContent>
        <Accordion type="multiple" className="w-full">
          {Object.entries(groupedPermissions).map(([resource, perms]) => (
            <AccordionItem key={resource} value={resource}>
              <AccordionTrigger>
                <div className="flex items-center justify-between flex-1 mr-2">
                  <span className="font-medium">{resource}</span>
                  <Badge variant="secondary">{perms.length}개</Badge>
                </div>
              </AccordionTrigger>
              <AccordionContent>
                <div className="space-y-2">
                  {perms.map(permission => (
                    <div key={permission.id} className="flex items-start gap-3 p-2">
                      <Badge variant="outline" className="mt-0.5">
                        {permission.action}
                      </Badge>
                      <div className="flex-1">
                        <div className="text-sm font-medium">{permission.name}</div>
                        <div className="text-xs text-muted-foreground">
                          {permission.permissionKey}
                        </div>
                        {permission.description && (
                          <div className="text-xs text-muted-foreground mt-1">
                            {permission.description}
                          </div>
                        )}
                      </div>
                      <Badge variant="secondary" className="text-xs">
                        {permission.scope}
                      </Badge>
                    </div>
                  ))}
                </div>
              </AccordionContent>
            </AccordionItem>
          ))}
        </Accordion>
      </CardContent>
    </Card>
  );
}

// 그룹 생성/수정 폼 다이얼로그
function GroupFormDialog({
  open,
  onOpenChange,
  group,
  onSuccess,
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  group?: PermissionGroup | null;
  onSuccess: () => void;
}) {
  const [formData, setFormData] = useState({
    groupKey: "",
    name: "",
    description: "",
    domain: "",
    isActive: true,
  });
  const [saving, setSaving] = useState(false);

  useEffect(() => {
    if (group) {
      setFormData({
        groupKey: group.groupKey,
        name: group.name,
        description: group.description || "",
        domain: group.domain || "",
        isActive: group.isActive,
      });
    } else {
      setFormData({
        groupKey: "",
        name: "",
        description: "",
        domain: "",
        isActive: true,
      });
    }
  }, [group]);

  const handleSubmit = async () => {
    if (!formData.groupKey || !formData.name) {
      toast.error("필수 항목을 입력해주세요.");
      return;
    }

    setSaving(true);
    try {
      if (group) {
        await updatePermissionGroup(group.id, formData);
        toast.success("권한 그룹이 수정되었습니다.");
      } else {
        await createPermissionGroup(formData);
        toast.success("권한 그룹이 생성되었습니다.");
      }
      onSuccess();
    } catch (error: any) {
      toast.error(error.message || "권한 그룹 저장에 실패했습니다.");
    } finally {
      setSaving(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>{group ? "권한 그룹 수정" : "권한 그룹 생성"}</DialogTitle>
          <DialogDescription>
            권한 그룹 정보를 입력하세요.
          </DialogDescription>
        </DialogHeader>

        <div className="grid gap-4 py-4">
          <div>
            <Label>그룹 키*</Label>
            <Input
              value={formData.groupKey}
              onChange={(e) => setFormData({ ...formData, groupKey: e.target.value })}
              placeholder="예: rfq_manager"
            />
          </div>

          <div>
            <Label>그룹명*</Label>
            <Input
              value={formData.name}
              onChange={(e) => setFormData({ ...formData, name: e.target.value })}
              placeholder="예: RFQ 관리자 권한"
            />
          </div>

          <div>
            <Label>설명</Label>
            <Textarea
              value={formData.description}
              onChange={(e) => setFormData({ ...formData, description: e.target.value })}
              placeholder="그룹에 대한 설명"
            />
          </div>

          <div>
            <Label>도메인</Label>
            <Select
              value={formData.domain}
              onValueChange={(v) => setFormData({ ...formData, domain: v })}
            >
              <SelectTrigger>
                <SelectValue placeholder="도메인 선택" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="">전체</SelectItem>
                <SelectItem value="evcp">EVCP</SelectItem>
                <SelectItem value="partners">Partners</SelectItem>
                <SelectItem value="procurement">Procurement</SelectItem>
                <SelectItem value="sales">Sales</SelectItem>
                <SelectItem value="engineering">Engineering</SelectItem>
              </SelectContent>
            </Select>
          </div>

          <div className="flex items-center gap-2">
            <Checkbox
              id="isActive"
              checked={formData.isActive}
              onCheckedChange={(v) => setFormData({ ...formData, isActive: !!v })}
            />
            <Label htmlFor="isActive">활성 상태</Label>
          </div>
        </div>

        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            취소
          </Button>
          <Button onClick={handleSubmit} disabled={saving}>
            {saving ? "저장 중..." : group ? "수정" : "생성"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

// 그룹 권한 관리 다이얼로그
function GroupPermissionsDialog({
  open,
  onOpenChange,
  group,
  groupPermissions,
  availablePermissions,
  onSuccess,
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  group: PermissionGroup;
  groupPermissions: Permission[];
  availablePermissions: Permission[];
  onSuccess: () => void;
}) {
  const [selectedPermissions, setSelectedPermissions] = useState<Set<number>>(
    new Set(groupPermissions.map(p => p.id))
  );
  const [saving, setSaving] = useState(false);
  const [searchQuery, setSearchQuery] = useState("");

  // 검색 필터링
  const filteredPermissions = availablePermissions.filter(p =>
    p.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
    p.permissionKey.toLowerCase().includes(searchQuery.toLowerCase())
  );

  // 리소스별로 권한 그룹화
  const groupedPermissions = filteredPermissions.reduce((acc, perm) => {
    const resource = perm.resource;
    if (!acc[resource]) acc[resource] = [];
    acc[resource].push(perm);
    return acc;
  }, {} as Record<string, Permission[]>);

  const handleSave = async () => {
    setSaving(true);
    try {
      await updateGroupPermissions(group.id, Array.from(selectedPermissions));
      toast.success("권한이 업데이트되었습니다.");
      onSuccess();
      onOpenChange(false);
    } catch (error) {
      toast.error("권한 업데이트에 실패했습니다.");
    } finally {
      setSaving(false);
    }
  };

  const togglePermission = (permissionId: number) => {
    const newSet = new Set(selectedPermissions);
    if (newSet.has(permissionId)) {
      newSet.delete(permissionId);
    } else {
      newSet.add(permissionId);
    }
    setSelectedPermissions(newSet);
  };

  const toggleResource = (resource: string) => {
    const resourcePerms = groupedPermissions[resource] || [];
    const allSelected = resourcePerms.every(p => selectedPermissions.has(p.id));
    
    const newSet = new Set(selectedPermissions);
    resourcePerms.forEach(p => {
      if (allSelected) {
        newSet.delete(p.id);
      } else {
        newSet.add(p.id);
      }
    });
    setSelectedPermissions(newSet);
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-3xl max-h-[80vh]">
        <DialogHeader>
          <DialogTitle>{group.name} 권한 설정</DialogTitle>
          <DialogDescription>
            이 그룹에 포함할 권한을 선택하세요.
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-4">
          {/* 검색 */}
          <div className="relative">
            <Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
            <Input
              placeholder="권한 검색..."
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
              className="pl-8"
            />
          </div>

          {/* 선택 정보 */}
          <div className="flex items-center justify-between p-2 bg-muted rounded">
            <span className="text-sm">
              {selectedPermissions.size}개 권한 선택됨
            </span>
            <div className="flex gap-2">
              <Button
                size="sm"
                variant="outline"
                onClick={() => setSelectedPermissions(new Set())}
              >
                전체 해제
              </Button>
              <Button
                size="sm"
                variant="outline"
                onClick={() => setSelectedPermissions(new Set(availablePermissions.map(p => p.id)))}
              >
                전체 선택
              </Button>
            </div>
          </div>

          {/* 권한 목록 */}
          <ScrollArea className="h-[400px] pr-4">
            <Accordion type="multiple" className="w-full">
              {Object.entries(groupedPermissions).map(([resource, perms]) => {
                const allSelected = perms.every(p => selectedPermissions.has(p.id));
                const someSelected = perms.some(p => selectedPermissions.has(p.id));
                
                return (
                  <AccordionItem key={resource} value={resource}>
                    <AccordionTrigger>
                      <div className="flex items-center gap-2 flex-1">
                        <Checkbox
                          checked={allSelected}
                          indeterminate={!allSelected && someSelected}
                          onCheckedChange={() => toggleResource(resource)}
                          onClick={(e) => e.stopPropagation()}
                        />
                        <span className="font-medium">{resource}</span>
                        <Badge variant="secondary" className="ml-auto mr-2">
                          {perms.filter(p => selectedPermissions.has(p.id)).length}/{perms.length}
                        </Badge>
                      </div>
                    </AccordionTrigger>
                    <AccordionContent>
                      <div className="space-y-2 pl-6">
                        {perms.map(permission => (
                          <label
                            key={permission.id}
                            className="flex items-start gap-3 cursor-pointer p-2 hover:bg-muted rounded"
                          >
                            <Checkbox
                              checked={selectedPermissions.has(permission.id)}
                              onCheckedChange={() => togglePermission(permission.id)}
                            />
                            <div className="flex-1">
                              <div className="text-sm font-medium">{permission.name}</div>
                              <div className="text-xs text-muted-foreground">
                                {permission.permissionKey}
                              </div>
                              {permission.description && (
                                <div className="text-xs text-muted-foreground mt-1">
                                  {permission.description}
                                </div>
                              )}
                            </div>
                            <div className="flex gap-1">
                              <Badge variant="outline" className="text-xs">
                                {permission.permissionType}
                              </Badge>
                              <Badge variant="secondary" className="text-xs">
                                {permission.scope}
                              </Badge>
                            </div>
                          </label>
                        ))}
                      </div>
                    </AccordionContent>
                  </AccordionItem>
                );
              })}
            </Accordion>
          </ScrollArea>
        </div>

        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            취소
          </Button>
          <Button onClick={handleSave} disabled={saving}>
            {saving ? "저장 중..." : "저장"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}