"use client";

import { useState, useEffect, useMemo } from "react";
import { Loader2, Shield, Search, X, Plus, Check, Info } from "lucide-react";
import type { WorkspaceMember, Project, PermissionKey } from "@/lib/types/api";
import { PERMISSION_LABELS, PERMISSION_GROUPS, PERMISSION_ICONS } from "@/lib/types/permission";
import {
  hasGlobalPermission,
  hasScopedPermission,
  getScopesForPermission,
  setScopedPermission,
  toggleScopedPermission,
  removePermission,
  calculatePermissionDiff,
} from "@/lib/types/permission";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
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 {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import { Separator } from "@/components/ui/separator";
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?: { type: string; id: string }[] }[]) => Promise<void>;
  workspaceId: string;
}

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

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,
}: 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 handleToggleGlobal = (key: PermissionKey) => {
    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) => {
    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 handleAddProject = (key: PermissionKey, projectId: string) => {
    setPermissions((prev) => {
      const existing = prev.find((p) => p.key === key);
      if (existing) {
        return prev.map((p) =>
          p.key === key
            ? { ...p, isGlobal: false, projectIds: [...new Set([...p.projectIds, projectId])] }
            : p
        );
      }
      return [
        ...prev,
        { key, isGlobal: false, projectIds: [projectId] },
      ];
    });
  };

  const handleRemoveProject = (key: PermissionKey, projectId: string) => {
    setPermissions((prev) => {
      const existing = prev.find((p) => p.key === key);
      if (!existing) return prev;

      const newProjectIds = existing.projectIds.filter((id) => id !== projectId);

      if (newProjectIds.length === 0) {
        return prev.filter((p) => p.key !== key);
      }

      return prev.map((p) =>
        p.key === key ? { ...p, projectIds: newProjectIds } : p
      );
    });
  };

  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 renderPermissionRow = (key: PermissionKey, group: string) => {
    const current = permissions.find((p) => p.key === key);
    const currentProjectIds = current?.projectIds || [];
    const isGlobal = current?.isGlobal ?? false;

    return (
      <div key={key} className="space-y-2">
        <div className="flex items-center justify-between gap-4">
          <div className="flex items-center gap-2 min-w-0">
            <span className="text-lg">{PERMISSION_ICONS[key]}</span>
            <span className="font-medium truncate">{PERMISSION_LABELS[key]}</span>
            <Badge variant="outline" className="text-xs shrink-0">
              {group}
            </Badge>
          </div>
          <div className="flex items-center gap-2 shrink-0">
            <Button
              variant={isGlobal ? "default" : "outline"}
              size="sm"
              onClick={() => handleToggleGlobal(key)}
              className="text-xs"
            >
              Глобально
            </Button>
            <Popover>
              <PopoverTrigger asChild>
                <Button variant={!isGlobal ? "default" : "outline"} size="sm" className="text-xs">
                  <Search className="h-3 w-3 mr-1" />
                  Проекты ({currentProjectIds.length})
                </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 justify-between p-2 rounded-md cursor-pointer transition-colors",
                              isSelected
                                ? "bg-primary/10 text-primary"
                                : "hover:bg-muted"
                            )}
                            onClick={() => handleToggleProject(key, project.id)}
                          >
                            <div className="truncate">
                              <div className="font-medium truncate">{project.title}</div>
                              {project.username && (
                                <div className="text-xs text-muted-foreground">
                                  @{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 pl-8">
            {currentProjectIds.map((id) => {
              const project = getProjectById(id);
              return (
                <Badge
                  key={id}
                  variant="secondary"
                  className="gap-1 text-xs"
                >
                  {project?.title || "Unknown"}
                  <X
                    className="h-3 w-3 cursor-pointer hover:text-destructive"
                    onClick={() => handleRemoveProject(key, id)}
                  />
                </Badge>
              );
            })}
          </div>
        )}
      </div>
    );
  };

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

        <div className="flex-1 overflow-y-auto space-y-4">
          <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">
            <div className="space-y-2">
              <h4 className="text-sm font-semibold flex items-center gap-2">
                👑 Администрирование
              </h4>
              {PERMISSION_GROUPS.admin.map((key) => renderPermissionRow(key, "admin"))}
            </div>

            <Separator />

            <div className="space-y-2">
              <h4 className="text-sm font-semibold flex items-center gap-2">
                📁 Проекты
              </h4>
              {PERMISSION_GROUPS.projects.map((key) => renderPermissionRow(key, "projects"))}
            </div>

            <Separator />

            <div className="space-y-2">
              <h4 className="text-sm font-semibold flex items-center gap-2">
                🎨 Креативы
              </h4>
              {PERMISSION_GROUPS.creatives.map((key) => renderPermissionRow(key, "creatives"))}
            </div>

            <Separator />

            <div className="space-y-2">
              <h4 className="text-sm font-semibold flex items-center gap-2">
                📋 Закупы
              </h4>
              {PERMISSION_GROUPS.placements.map((key) => renderPermissionRow(key, "placements"))}
            </div>

            <Separator />

            <div className="space-y-2">
              <h4 className="text-sm font-semibold flex items-center gap-2">
                📊 Аналитика
              </h4>
              {PERMISSION_GROUPS.analytics.map((key) => renderPermissionRow(key, "analytics"))}
            </div>
          </div>

          <div className="flex items-center gap-2 text-xs text-muted-foreground bg-muted/50 p-2 rounded">
            <Info className="h-4 w-4 shrink-0" />
            <span>
              Глобальные права применяются ко всему воркспейсу. Права на проекты применяются только к выбранным проектам.
            </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}>
              Сбросить
            </Button>
            <Button onClick={handleSave} disabled={!isDirty || isSaving}>
              {isSaving && <Loader2 className="h-4 w-4 animate-spin mr-2" />}
              Сохранить
            </Button>
          </div>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
