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

"use client";

import { useState, useEffect, useTransition } from "react";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import { Checkbox } from "@/components/ui/checkbox";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { ScrollArea } from "@/components/ui/scroll-area";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Calendar } from "@/components/ui/calendar";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { 
  Search, 
  UserPlus, 
  Shield, 
  Clock, 
  AlertTriangle,
  CheckCircle,
  XCircle,
  CalendarIcon,
  Plus,
  Minus,
  Settings,
  Key,
  Users,
  Building,
  ChevronRight
} from "lucide-react";
import { format } from "date-fns";
import { ko } from "date-fns/locale";
import { toast } from "sonner";
import { cn } from "@/lib/utils";
import {
  getUserPermissionDetails,
  grantPermissionToUser,
  revokePermissionFromUser,
  searchUsers,
  getUserRoles,
} from "@/lib/permissions/service";

interface User {
  id: number;
  name: string;
  email: string;
  imageUrl?: string;
  domain: string;
  companyName?: string;
  roles: { id: number; name: string }[];
}

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

interface UserPermission extends Permission {
  source: "role" | "direct";
  roleName?: string;
  grantedBy?: string;
  grantedAt?: Date;
  expiresAt?: Date;
  reason?: string;
  isGrant: boolean;
}

export function UserPermissionManager() {
  const [searchQuery, setSearchQuery] = useState("");
  const [selectedUser, setSelectedUser] = useState<User | null>(null);
  const [users, setUsers] = useState<User[]>([]);
  const [userPermissions, setUserPermissions] = useState<UserPermission[]>([]);
  const [availablePermissions, setAvailablePermissions] = useState<Permission[]>([]);
  const [loading, setLoading] = useState(false);
  const [isPending, startTransition] = useTransition();
  const [addPermissionDialogOpen, setAddPermissionDialogOpen] = useState(false);

  // 사용자 검색
  useEffect(() => {
    const timer = setTimeout(() => {
      if (searchQuery) {
        searchUsersData(searchQuery);
      }
    }, 300);
    return () => clearTimeout(timer);
  }, [searchQuery]);

  // 선택된 사용자의 권한 로드
  useEffect(() => {
    if (selectedUser) {
      loadUserPermissions(selectedUser.id);
    }
  }, [selectedUser]);

  const searchUsersData = async (query: string) => {
    try {
      const data = await searchUsers(query);
      setUsers(data);
    } catch (error) {
      toast.error("사용자 검색에 실패했습니다.");
    }
  };

  const loadUserPermissions = async (userId: number) => {
    setLoading(true);
    try {
      const data = await getUserPermissionDetails(userId);
      setUserPermissions(data.permissions);
      setAvailablePermissions(data.availablePermissions);
    } catch (error) {
      toast.error("권한 정보를 불러오는데 실패했습니다.");
    } finally {
      setLoading(false);
    }
  };

  // 역할 기반 권한과 직접 부여 권한 분리
  const rolePermissions = userPermissions.filter(p => p.source === "role");
  const directPermissions = userPermissions.filter(p => p.source === "direct");

  return (
    <div className="grid grid-cols-3 gap-6">
      {/* 사용자 검색 및 선택 */}
      <Card className="col-span-1">
        <CardHeader>
          <CardTitle>사용자 선택</CardTitle>
          <CardDescription>권한을 관리할 사용자를 검색하세요.</CardDescription>
        </CardHeader>
        <CardContent>
          <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>

            {/* 사용자 목록 */}
            <ScrollArea className="h-[500px]">
              <div className="space-y-2">
                {users.map((user) => (
                  <button
                    key={user.id}
                    onClick={() => setSelectedUser(user)}
                    className={cn(
                      "w-full p-3 rounded-lg border text-left transition-colors",
                      selectedUser?.id === user.id
                        ? "bg-primary/10 border-primary"
                        : "hover:bg-muted"
                    )}
                  >
                    <div className="flex items-center gap-3">
                      <Avatar>
                        <AvatarImage src={user.imageUrl} />
                        <AvatarFallback>{user.name[0]}</AvatarFallback>
                      </Avatar>
                      <div className="flex-1 min-w-0">
                        <div className="font-medium truncate">{user.name}</div>
                        <div className="text-sm text-muted-foreground truncate">
                          {user.email}
                        </div>
                        <div className="flex items-center gap-2 mt-1">
                          <Badge variant="outline" className="text-xs">
                            {user.domain}
                          </Badge>
                          {user.companyName && (
                            <span className="text-xs text-muted-foreground">
                              {user.companyName}
                            </span>
                          )}
                        </div>
                      </div>
                    </div>
                  </button>
                ))}
              </div>
            </ScrollArea>
          </div>
        </CardContent>
      </Card>

      {/* 권한 상세 */}
      {selectedUser ? (
        <Card className="col-span-2">
          <CardHeader>
            <div className="flex items-center justify-between">
              <div>
                <CardTitle>{selectedUser.name}의 권한</CardTitle>
                <CardDescription>
                  {selectedUser.email} • {selectedUser.domain}
                </CardDescription>
              </div>
              <AddPermissionDialog
                userId={selectedUser.id}
                availablePermissions={availablePermissions.filter(
                  p => !userPermissions.some(up => up.id === p.id)
                )}
                onSuccess={() => loadUserPermissions(selectedUser.id)}
              />
            </div>
          </CardHeader>
          <CardContent>
            <Tabs defaultValue="all" className="w-full">
              <TabsList>
                <TabsTrigger value="all">
                  전체 권한 ({userPermissions.length})
                </TabsTrigger>
                <TabsTrigger value="role">
                  <Users className="mr-2 h-4 w-4" />
                  역할 기반 ({rolePermissions.length})
                </TabsTrigger>
                <TabsTrigger value="direct">
                  <Shield className="mr-2 h-4 w-4" />
                  직접 부여 ({directPermissions.length})
                </TabsTrigger>
              </TabsList>

              <TabsContent value="all" className="mt-4">
                <PermissionList 
                  permissions={userPermissions}
                  userId={selectedUser.id}
                  onRevoke={() => loadUserPermissions(selectedUser.id)}
                />
              </TabsContent>

              <TabsContent value="role" className="mt-4">
                <div className="space-y-4">
                  {/* 역할 표시 */}
                  <div className="p-4 bg-muted/50 rounded-lg">
                    <h4 className="text-sm font-medium mb-2">보유 역할</h4>
                    <div className="flex flex-wrap gap-2">
                      {selectedUser.roles.map(role => (
                        <Badge key={role.id} variant="secondary">
                          {role.name}
                        </Badge>
                      ))}
                    </div>
                  </div>
                  <PermissionList 
                    permissions={rolePermissions}
                    userId={selectedUser.id}
                    readOnly
                  />
                </div>
              </TabsContent>

              <TabsContent value="direct" className="mt-4">
                <PermissionList 
                  permissions={directPermissions}
                  userId={selectedUser.id}
                  onRevoke={() => loadUserPermissions(selectedUser.id)}
                />
              </TabsContent>
            </Tabs>
          </CardContent>
        </Card>
      ) : (
        <Card className="col-span-2 flex items-center justify-center h-[600px]">
          <div className="text-center text-muted-foreground">
            <Shield className="h-12 w-12 mx-auto mb-4 opacity-50" />
            <p>사용자를 선택하면 권한 정보가 표시됩니다.</p>
          </div>
        </Card>
      )}
    </div>
  );
}

// 권한 목록 컴포넌트
function PermissionList({ 
  permissions, 
  userId, 
  readOnly = false,
  onRevoke 
}: {
  permissions: UserPermission[];
  userId: number;
  readOnly?: boolean;
  onRevoke?: () => void;
}) {
  const [revoking, setRevoking] = useState<number | null>(null);

  const handleRevoke = async (permissionId: number) => {
    if (!confirm("이 권한을 제거하시겠습니까?")) return;
    
    setRevoking(permissionId);
    try {
      await revokePermissionFromUser(userId, permissionId);
      toast.success("권한이 제거되었습니다.");
      onRevoke?.();
    } catch (error) {
      toast.error("권한 제거에 실패했습니다.");
    } finally {
      setRevoking(null);
    }
  };

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

  return (
    <div className="space-y-4">
      {Object.entries(groupedPermissions).map(([resource, perms]) => (
        <div key={resource} className="border rounded-lg">
          <div className="px-4 py-2 bg-muted/30 font-medium text-sm">
            {resource}
          </div>
          <div className="divide-y">
            {perms.map((permission) => (
              <div key={permission.id} className="p-4">
                <div className="flex items-start justify-between">
                  <div className="space-y-1">
                    <div className="flex items-center gap-2">
                      <span className="font-medium">{permission.name}</span>
                      {permission.source === "role" && (
                        <Badge variant="outline" className="text-xs">
                          역할: {permission.roleName}
                        </Badge>
                      )}
                      {permission.isGrant === false && (
                        <Badge variant="destructive" className="text-xs">
                          제한
                        </Badge>
                      )}
                    </div>
                    <div className="text-sm text-muted-foreground">
                      {permission.description}
                    </div>
                    <div className="flex items-center gap-4 text-xs text-muted-foreground">
                      <span>타입: {permission.permissionType}</span>
                      <span>범위: {permission.scope}</span>
                      {permission.expiresAt && (
                        <span className="text-orange-600">
                          <Clock className="inline h-3 w-3 mr-1" />
                          {format(new Date(permission.expiresAt), "yyyy-MM-dd")} 만료
                        </span>
                      )}
                    </div>
                    {permission.reason && (
                      <div className="text-xs text-muted-foreground mt-2">
                        사유: {permission.reason}
                      </div>
                    )}
                  </div>
                  
                  {!readOnly && permission.source === "direct" && (
                    <Button
                      variant="ghost"
                      size="sm"
                      onClick={() => handleRevoke(permission.id)}
                      disabled={revoking === permission.id}
                    >
                      <XCircle className="h-4 w-4" />
                    </Button>
                  )}
                </div>
              </div>
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}

// 권한 추가 다이얼로그
function AddPermissionDialog({ 
  userId, 
  availablePermissions,
  onSuccess 
}: {
  userId: number;
  availablePermissions: Permission[];
  onSuccess: () => void;
}) {
  const [open, setOpen] = useState(false);
  const [selectedPermissions, setSelectedPermissions] = useState<number[]>([]);
  const [reason, setReason] = useState("");
  const [expiresAt, setExpiresAt] = useState<Date | undefined>();
  const [isGrant, setIsGrant] = useState(true);
  const [saving, setSaving] = useState(false);

  const handleSubmit = async () => {
    if (selectedPermissions.length === 0) {
      toast.error("권한을 선택해주세요.");
      return;
    }

    setSaving(true);
    try {
      await grantPermissionToUser({
        userId,
        permissionIds: selectedPermissions,
        isGrant,
        reason,
        expiresAt,
      });
      toast.success("권한이 추가되었습니다.");
      setOpen(false);
      onSuccess();
      // Reset form
      setSelectedPermissions([]);
      setReason("");
      setExpiresAt(undefined);
      setIsGrant(true);
    } catch (error) {
      toast.error("권한 추가에 실패했습니다.");
    } finally {
      setSaving(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogTrigger asChild>
        <Button>
          <Plus className="mr-2 h-4 w-4" />
          권한 추가
        </Button>
      </DialogTrigger>
      <DialogContent className="max-w-2xl">
        <DialogHeader>
          <DialogTitle>권한 추가</DialogTitle>
          <DialogDescription>
            사용자에게 직접 권한을 부여하거나 제한합니다.
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-4 py-4">
          {/* 권한 타입 선택 */}
          <div className="flex items-center space-x-4">
            <Label>권한 타입</Label>
            <div className="flex gap-4">
              <label className="flex items-center gap-2">
                <input
                  type="radio"
                  checked={isGrant}
                  onChange={() => setIsGrant(true)}
                />
                <span className="text-sm">부여</span>
              </label>
              <label className="flex items-center gap-2">
                <input
                  type="radio"
                  checked={!isGrant}
                  onChange={() => setIsGrant(false)}
                />
                <span className="text-sm text-destructive">제한</span>
              </label>
            </div>
          </div>

          {/* 권한 선택 */}
          <div>
            <Label>권한 선택</Label>
            <ScrollArea className="h-[200px] border rounded-md p-4 mt-2">
              <div className="space-y-2">
                {availablePermissions.map(permission => (
                  <label
                    key={permission.id}
                    className="flex items-start gap-2 cursor-pointer"
                  >
                    <Checkbox
                      checked={selectedPermissions.includes(permission.id)}
                      onCheckedChange={(checked) => {
                        if (checked) {
                          setSelectedPermissions([...selectedPermissions, permission.id]);
                        } else {
                          setSelectedPermissions(
                            selectedPermissions.filter(id => id !== permission.id)
                          );
                        }
                      }}
                    />
                    <div className="flex-1">
                      <div className="text-sm font-medium">{permission.name}</div>
                      <div className="text-xs text-muted-foreground">
                        {permission.description}
                      </div>
                    </div>
                  </label>
                ))}
              </div>
            </ScrollArea>
          </div>

          {/* 사유 */}
          <div>
            <Label>사유</Label>
            <Textarea
              placeholder="권한 부여/제한 사유를 입력하세요."
              value={reason}
              onChange={(e) => setReason(e.target.value)}
              className="mt-2"
            />
          </div>

          {/* 만료일 */}
          <div>
            <Label>만료일 (선택)</Label>
            <Popover>
              <PopoverTrigger asChild>
                <Button
                  variant="outline"
                  className={cn(
                    "w-full justify-start text-left font-normal mt-2",
                    !expiresAt && "text-muted-foreground"
                  )}
                >
                  <CalendarIcon className="mr-2 h-4 w-4" />
                  {expiresAt ? format(expiresAt, "PPP", { locale: ko }) : "만료일 선택"}
                </Button>
              </PopoverTrigger>
              <PopoverContent className="w-auto p-0" align="start">
                <Calendar
                  mode="single"
                  selected={expiresAt}
                  onSelect={setExpiresAt}
                  initialFocus
                />
              </PopoverContent>
            </Popover>
          </div>
        </div>

        <DialogFooter>
          <Button variant="outline" onClick={() => setOpen(false)}>
            취소
          </Button>
          <Button onClick={handleSubmit} disabled={saving}>
            {saving ? "저장 중..." : "권한 추가"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}