"use client";

import { useState, useEffect, useMemo } from "react";
import {
  Loader2,
  Shield,
  Search,
  X,
  Check,
  Info,
  Crown,
  FolderOpen,
  Palette,
  ClipboardList,
  BarChart3,
  Users,
  Lock,
  Eye,
  Pencil,
  ChartArea,
  UserRoundX,
  FileUser,
  Globe,
} from "lucide-react";
import type { WorkspaceMember, Project, PermissionKey, PermissionScope } from "@/lib/types/api";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Separator } from "@/components/ui/separator";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { cn } from "@/lib/utils";

interface PermissionModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  member: WorkspaceMember;
  projects: Project[];
  onSave: (workspaceId: string, memberId: string, userId: string, permissions: { key: PermissionKey; scopes?: PermissionScope[] }[]) => Promise<void>;
  workspaceId: string;
  currentUserId: string;
  isOnlyAdmin: boolean;
}

interface PermissionState {
  key: PermissionKey;
  isGlobal: boolean;
  projectIds: string[];
}

const PERMISSION_CONFIG: Record<PermissionKey, { icon: typeof Crown; label: string; group: string }> = {
  admin_full: { icon: Crown, label: "Полный доступ", group: "admin" },
  projects_read: { icon: Eye, label: "Просмотр проектов", group: "projects" },
  projects_write: { icon: Pencil, label: "Управление проектами", group: "projects" },
  creatives_read: { icon: Eye, label: "Просмотр креативов", group: "creatives" },
  creatives_write: { icon: Pencil, label: "Создание и редактирование креативов", group: "creatives" },
  placements_read: { icon: Eye, label: "Просмотр закупок", group: "placements" },
  placements_write: { icon: Pencil, label: "Создание и редактирование закупок", group: "placements" },
  analytics_read: { icon: ChartArea, label: "Полный доступ к статистике", group: "analytics" },
  analytics_without_clicks: { icon: UserRoundX, label: "Статистика без переходов", group: "analytics" },
  analytics_own_creatives: { icon: FileUser, label: "Статистика только своих креативов", group: "analytics" },
};

const GROUPS = [
  { key: "admin", label: "Администрирование", icon: Shield },
  { key: "projects", label: "Проекты", icon: FolderOpen },
  { key: "creatives", label: "Креативы", icon: Palette },
  { key: "placements", label: "Закупки", icon: ClipboardList },
  { key: "analytics", label: "Аналитика", icon: BarChart3 },
] as const;

const PRESETS = [
  { label: "Полный доступ", keys: ["admin_full"] },
  { label: "Только чтение", keys: ["projects_read", "creatives_read", "placements_read", "analytics_read"] },
  { label: "Менеджер", keys: ["projects_read", "projects_write", "placements_read", "placements_write"] },
  { label: "Убрать все", keys: [] },
];

export function PermissionModal({
  open,
  onOpenChange,
  member,
  projects,
  onSave,
  workspaceId,
  currentUserId,
  isOnlyAdmin,
}: PermissionModalProps) {
  const [isSaving, setIsSaving] = useState(false);
  const [permissions, setPermissions] = useState<PermissionState[]>([]);
  const [projectSearch, setProjectSearch] = useState("");

  useEffect(() => {
    if (open && member) {
      const perms: PermissionState[] = [];

      for (const perm of member.permissions) {
        const isGlobal = !perm.scopes || perm.scopes.length === 0;
        const projectIds = perm.scopes
          ? perm.scopes.filter((s) => s.type === "project").map((s) => s.id)
          : [];

        perms.push({
          key: perm.key,
          isGlobal,
          projectIds,
        });
      }

      setPermissions(perms);
    }
  }, [open, member]);

  const hasGlobalAdmin = useMemo(() => {
    const admin = permissions.find((p) => p.key === "admin_full");
    return admin?.isGlobal ?? false;
  }, [permissions]);

  const isPermissionDisabled = (key: PermissionKey): boolean => {
    return hasGlobalAdmin && key !== "admin_full";
  };

  const handleToggleGlobal = (key: PermissionKey) => {
    if (hasGlobalAdmin && key !== "admin_full") return;

    setPermissions((prev) => {
      const existing = prev.find((p) => p.key === key);
      if (existing) {
        return prev.map((p) =>
          p.key === key ? { ...p, isGlobal: !p.isGlobal, projectIds: [] } : p
        );
      }
      return [...prev, { key, isGlobal: true, projectIds: [] }];
    });
  };

  const handleToggleProject = (key: PermissionKey, projectId: string) => {
    if (hasGlobalAdmin && key !== "admin_full") return;

    setPermissions((prev) => {
      const existing = prev.find((p) => p.key === key);
      if (existing) {
        return prev.map((p) =>
          p.key === key
            ? { ...p, isGlobal: false, projectIds: toggleInArray(p.projectIds, projectId) }
            : p
        );
      }
      return [
        ...prev,
        { key, isGlobal: false, projectIds: [projectId] },
      ];
    });
  };

  const toggleInArray = (arr: string[], item: string): string[] => {
    if (arr.includes(item)) {
      return arr.filter((i) => i !== item);
    }
    return [...arr, item];
  };

  const applyPreset = (keys: PermissionKey[]) => {
    if (keys.length === 0) {
      setPermissions([]);
      return;
    }

    setPermissions(
      keys.map((key) => ({
        key,
        isGlobal: true,
        projectIds: [],
      }))
    );
  };

  const getProjectById = (id: string): Project | undefined => {
    return projects.find((p) => p.id === id);
  };

  const availableProjects = useMemo(() => {
    return projects.filter(
      (p) =>
        p.title.toLowerCase().includes(projectSearch.toLowerCase()) ||
        p.username?.toLowerCase().includes(projectSearch.toLowerCase())
    );
  }, [projects, projectSearch]);

  const isDirty = useMemo(() => {
    if (permissions.length !== member.permissions.length) return true;

    for (const perm of permissions) {
      const orig = member.permissions.find((p) => p.key === perm.key);
      if (!orig) return true;

      const origIsGlobal = !orig.scopes || orig.scopes.length === 0;
      const origProjectIds = orig.scopes
        ? orig.scopes.filter((s) => s.type === "project").map((s) => s.id)
        : [];

      if (perm.isGlobal !== origIsGlobal) return true;
      if (!perm.isGlobal) {
        const permProjectSet = new Set(perm.projectIds);
        const origProjectSet = new Set(origProjectIds);
        if (permProjectSet.size !== origProjectSet.size) return true;
        for (const id of permProjectSet) {
          if (!origProjectSet.has(id)) return true;
        }
      }
    }
    return false;
  }, [permissions, member.permissions]);

  const handleSave = async () => {
    setIsSaving(true);
    try {
      const result = permissions
        .filter((p) => {
          if (p.isGlobal) return true;
          return p.projectIds.length > 0;
        })
        .map((p) => {
          if (p.isGlobal) {
            return { key: p.key };
          }
          return {
            key: p.key,
            scopes: p.projectIds.map((id) => ({ type: "project" as const, id })),
          };
        });

      await onSave(workspaceId, member.id, member.user.id, result);
      onOpenChange(false);
    } finally {
      setIsSaving(false);
    }
  };

  const handleReset = () => {
    const perms: PermissionState[] = [];

    for (const perm of member.permissions) {
      const isGlobal = !perm.scopes || perm.scopes.length === 0;
      const projectIds = perm.scopes
        ? perm.scopes.filter((s) => s.type === "project").map((s) => s.id)
        : [];

      perms.push({
        key: perm.key,
        isGlobal,
        projectIds,
      });
    }

    setPermissions(perms);
  };

  const isEditingOwnPermissions = member.user.id === currentUserId;

  const renderPermissionRow = (key: PermissionKey) => {
    const config = PERMISSION_CONFIG[key];
    const current = permissions.find((p) => p.key === key);
    const currentProjectIds = current?.projectIds || [];
    const isGlobal = current?.isGlobal ?? false;
    const isDisabled = isPermissionDisabled(key);

    return (
      <div
        key={key}
        className={cn(
          "space-y-2 transition-opacity",
          isDisabled && "opacity-50"
        )}
      >
        <div className="flex items-center justify-between gap-3 min-w-0">
          <div className="flex items-center gap-2 min-w-0 flex-1">
            {isDisabled ? (
              <Lock className="h-4 w-4 shrink-0 text-muted-foreground" />
            ) : (
              <config.icon className="h-4 w-4 shrink-0 text-muted-foreground" />
            )}
            <span className={cn("font-medium text-sm truncate", isDisabled && "text-muted-foreground")}>
              {config.label}
            </span>
            {isDisabled && (
              <Badge variant="secondary" className="text-xs shrink-0">
                Выдан полный доступ
              </Badge>
            )}
          </div>
          <div className="flex items-center gap-2 shrink-0">
            <Button
              variant={isGlobal ? "default" : "outline"}
              size="sm"
              onClick={() => handleToggleGlobal(key)}
              disabled={isDisabled}
              className={cn(
                "text-xs shrink-0",
                isDisabled && "cursor-not-allowed opacity-50"
              )}
            >
              <Globe className="h-3 w-3 mr-1" />
              Глобально
            </Button>
            <Popover>
              <PopoverTrigger asChild>
                <Button
                  variant={!isGlobal ? "default" : "outline"}
                  size="sm"
                  disabled={isDisabled}
                  className={cn(
                    "text-xs shrink-0 min-w-[100px]",
                    isDisabled && "cursor-not-allowed opacity-50"
                  )}
                >
                  <Search className="h-3 w-3 mr-1" />
                  {currentProjectIds.length > 0
                    ? `${currentProjectIds.length} проект${currentProjectIds.length === 1 ? "" : currentProjectIds.length > 4 ? "ов" : "а"}`
                    : "Проекты"}
                </Button>
              </PopoverTrigger>
              <PopoverContent className="w-80" align="end">
                <div className="space-y-2">
                  <div className="flex items-center gap-2">
                    <Input
                      placeholder="Поиск проекта..."
                      value={projectSearch}
                      onChange={(e) => setProjectSearch(e.target.value)}
                      className="h-8"
                    />
                  </div>
                  <ScrollArea className="h-64">
                    <div className="space-y-1 pr-2">
                      {availableProjects.map((project) => {
                        const isSelected = currentProjectIds.includes(project.id);
                        return (
                          <div
                            key={project.id}
                            className={cn(
                              "flex items-center gap-2 p-2 rounded-md cursor-pointer transition-colors",
                              isSelected
                                ? "bg-primary/10 text-primary"
                                : "hover:bg-muted"
                            )}
                            onClick={() => handleToggleProject(key, project.id)}
                          >
                            <Avatar className="h-6 w-6 shrink-0">
                              <AvatarImage src={project.username ? `https://t.me/i/userpic/320/${project.username}.jpg` : undefined} />
                              <AvatarFallback className="text-xs">
                                {project.title.charAt(0).toUpperCase()}
                              </AvatarFallback>
                            </Avatar>
                            <div className="truncate min-w-0 flex-1">
                              <div className="font-medium text-sm truncate">{project.title}</div>
                              {project.username && (
                                <div className="text-xs text-muted-foreground truncate">
                                  @{project.username}
                                </div>
                              )}
                            </div>
                            {isSelected && <Check className="h-4 w-4 shrink-0" />}
                          </div>
                        );
                      })}
                      {availableProjects.length === 0 && (
                        <div className="text-center py-4 text-muted-foreground text-sm">
                          Проекты не найдены
                        </div>
                      )}
                    </div>
                  </ScrollArea>
                </div>
              </PopoverContent>
            </Popover>
          </div>
        </div>

        {!isGlobal && currentProjectIds.length > 0 && (
          <div className="flex flex-wrap gap-1 ml-6">
            {currentProjectIds.map((id) => {
              const project = getProjectById(id);
              return (
                <Badge
                  key={id}
                  variant="secondary"
                  className={cn("gap-1 text-xs", isDisabled && "opacity-50")}
                >
                  <Avatar className="h-4 w-4">
                    <AvatarImage src={project?.username ? `https://t.me/i/userpic/320/${project.username}.jpg` : undefined} />
                    <AvatarFallback className="text-[10px]">
                      {project?.title.charAt(0).toUpperCase() || "?"}
                    </AvatarFallback>
                  </Avatar>
                  <span className="truncate max-w-[150px]">{project?.title || "Unknown"}</span>
                  <span
                    className={cn(
                      "h-3 w-3 ml-1 cursor-pointer hover:text-destructive",
                      isDisabled && "cursor-not-allowed text-muted-foreground/50"
                    )}
                    onClick={(e) => {
                      e.stopPropagation();
                      if (isDisabled) return;
                      setPermissions((prev) => {
                        const existing = prev.find((p) => p.key === key);
                        if (!existing) return prev;
                        const newProjectIds = existing.projectIds.filter((pid) => pid !== id);
                        if (newProjectIds.length === 0) {
                          return prev.filter((p) => p.key !== key);
                        }
                        return prev.map((p) =>
                          p.key === key ? { ...p, projectIds: newProjectIds } : p
                        );
                      });
                    }}
                  >
                    <X className="h-3 w-3" />
                  </span>
                </Badge>
              );
            })}
          </div>
        )}
      </div>
    );
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-3xl w-[98vw] max-h-[90vh] flex flex-col">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <Users className="h-5 w-5" />
            Права доступа
          </DialogTitle>
          <DialogDescription>
            Настройте права доступа для участника{" "}
            <span className="font-medium">
              {member.user.first_name || member.user.username || `User ${member.user.telegram_id}`}
            </span>
          </DialogDescription>
        </DialogHeader>

        {isEditingOwnPermissions && isOnlyAdmin && (
          <div className="flex items-center gap-2 text-sm text-amber-600 bg-amber-50 dark:bg-amber-950/20 p-3 rounded-md">
            <Lock className="h-4 w-4 shrink-0" />
            <span>
              Вы не можете изменить свои права, так как вы единственный администратор воркспейса.
            </span>
          </div>
        )}

        <div className="flex-1 overflow-y-auto space-y-4 px-1">
          <div className="flex flex-wrap gap-2 pb-2">
            <span className="text-sm text-muted-foreground mr-2">Быстрые настройки:</span>
            {PRESETS.map((preset) => (
              <Button
                key={preset.label}
                variant="outline"
                size="sm"
                onClick={() => applyPreset(preset.keys as PermissionKey[])}
                className="text-xs"
              >
                {preset.label}
              </Button>
            ))}
          </div>

          <Separator />

          <div className="space-y-4">
            {GROUPS.slice(1).map((group) => {
              const groupPermissions = Object.entries(PERMISSION_CONFIG)
                .filter(([, config]) => config.group === group.key)
                .map(([key, config]) => ({ ...config, key: key as PermissionKey }));

              if (groupPermissions.length === 0) return null;

              return (
                <div key={group.key} className="space-y-2">
                  <div className="flex items-center gap-2 text-sm font-semibold text-muted-foreground">
                    <group.icon className="h-4 w-4" />
                    {group.label}
                  </div>
                  <div className="space-y-3 pl-6 border-l-2 border-muted ml-2">
                    {groupPermissions.map((perm) => renderPermissionRow(perm.key))}
                  </div>
                </div>
              );
            })}
          </div>

          <Separator />

          <div className="space-y-2">
            <div className="flex items-center gap-2 text-sm font-semibold text-muted-foreground">
              <Shield className="h-4 w-4" />
              Администрирование
            </div>
            <div className="space-y-3 pl-6 border-l-2 border-muted ml-2">
              {Object.entries(PERMISSION_CONFIG)
                .filter(([, config]) => config.group === "admin")
                .map(([key, config]) => ({ ...config, key: key as PermissionKey }))
                .map((perm) => renderPermissionRow(perm.key))}
            </div>
          </div>

          <div className="flex items-center gap-2 text-xs text-muted-foreground bg-muted/50 p-3 rounded">
            <Info className="h-4 w-4 shrink-0" />
            <span>
              <strong>Полный доступ</strong> автоматически включает все остальные права.
              Остальные права можно оставить для случая, если позже потребуется убрать полный доступ.
            </span>
          </div>
        </div>

        <DialogFooter className="flex justify-between items-center pt-4 border-t">
          <div className="text-sm text-muted-foreground">
            {isDirty && <span className="text-primary">Есть несохранённые изменения</span>}
          </div>
          <div className="flex gap-2">
            <Button variant="outline" onClick={handleReset} disabled={isSaving || (isEditingOwnPermissions && isOnlyAdmin)}>
              Сбросить
            </Button>
            <Button
              onClick={handleSave}
              disabled={!isDirty || isSaving || (isEditingOwnPermissions && isOnlyAdmin)}
            >
              {isSaving && <Loader2 className="h-4 w-4 animate-spin mr-2" />}
              Сохранить
            </Button>
          </div>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
