'use client';

import Link from 'next/link';
import { AnimatePresence, motion } from 'framer-motion';
import {
  BarChart3,
  Check,
  CreditCard,
  FolderOpen,
  LayoutDashboard,
  Link as LinkIcon,
  MoreVertical,
  PencilLine,
  Plus,
  StickyNote,
  Trash2,
  X,
} from 'lucide-react';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import ProfileAccountMenu from '@/app/components/profile/ProfileAccountMenu';
import { useToast } from '@/app/components/ToastProvider';
import { getResponseErrorTextWithRequestId } from '@/lib/api-client';
import { getRuntimeClientConfig } from '@/lib/runtime-client-config';
import type { ProfileDashboardTab } from '@/app/profile/hooks/useProfileDashboardTabs';

type Folder = {
  id: string;
  name: string;
  _count?: { links: number };
};

type ProfileSidebarProps = {
  currentTab: ProfileDashboardTab;
  onTabChange: (tab: ProfileDashboardTab) => void;
  folders: Folder[];
  activeFolderId: string | null;
  onFolderClick: (folderId: string) => void;
  onCreateClick: () => void;
  displayName: string;
  avatarInitials: string;
  isAdmin: boolean;
  onOpenSettings: () => void;
  onLogout: () => void;
  onFoldersChanged?: () => Promise<void> | void;
};

const tabItems: Array<{ id: ProfileDashboardTab; label: string; Icon: typeof LayoutDashboard }> = [
  { id: 'overview', label: 'Обзор', Icon: LayoutDashboard },
  { id: 'links', label: 'Ссылки', Icon: LinkIcon },
  { id: 'analytics', label: 'Аналитика', Icon: BarChart3 },
  { id: 'pricing', label: 'Тарифы', Icon: CreditCard },
  { id: 'notebook', label: 'Записки', Icon: StickyNote },
];

export default function ProfileSidebar({
  currentTab,
  onTabChange,
  folders,
  activeFolderId,
  onFolderClick,
  onCreateClick,
  displayName,
  avatarInitials,
  isAdmin,
  onOpenSettings,
  onLogout,
  onFoldersChanged,
}: ProfileSidebarProps) {
  const toast = useToast();
  const sidebarRef = useRef<HTMLDivElement | null>(null);
  const appName = useMemo(() => getRuntimeClientConfig().projectName || 'LinkSnap', []);

  const [isCreateFolderOpen, setIsCreateFolderOpen] = useState(false);
  const [newFolderName, setNewFolderName] = useState('');
  const [folderActionError, setFolderActionError] = useState('');
  const [isCreatingFolder, setIsCreatingFolder] = useState(false);
  const [openFolderMenuId, setOpenFolderMenuId] = useState<string | null>(null);
  const [editingFolderId, setEditingFolderId] = useState<string | null>(null);
  const [editingFolderName, setEditingFolderName] = useState('');
  const [isRenamingFolderId, setIsRenamingFolderId] = useState<string | null>(null);
  const [isDeletingFolderId, setIsDeletingFolderId] = useState<string | null>(null);

  useEffect(() => {
    if (!openFolderMenuId) return;

    const handlePointerDown = (event: PointerEvent) => {
      if (!sidebarRef.current) return;
      if (sidebarRef.current.contains(event.target as Node)) return;
      setOpenFolderMenuId(null);
    };

    window.addEventListener('pointerdown', handlePointerDown);
    return () => window.removeEventListener('pointerdown', handlePointerDown);
  }, [openFolderMenuId]);

  const refreshFolders = useCallback(async () => {
    if (!onFoldersChanged) return;
    await onFoldersChanged();
  }, [onFoldersChanged]);

  const handleCreateFolder = useCallback(async () => {
    const trimmedName = newFolderName.trim();
    if (!trimmedName || isCreatingFolder) return;

    setIsCreatingFolder(true);
    setFolderActionError('');

    try {
      const response = await fetch('/api/folders', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name: trimmedName }),
      });

      if (!response.ok) {
        throw new Error(await getResponseErrorTextWithRequestId(response, 'Не удалось создать папку'));
      }

      setNewFolderName('');
      setIsCreateFolderOpen(false);
      await refreshFolders();
      toast.success('Папка создана');
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Не удалось создать папку';
      setFolderActionError(message);
      toast.error(message);
    } finally {
      setIsCreatingFolder(false);
    }
  }, [isCreatingFolder, newFolderName, refreshFolders, toast]);

  const startRenameFolder = useCallback((folder: Folder) => {
    setEditingFolderId(folder.id);
    setEditingFolderName(folder.name);
    setOpenFolderMenuId(null);
    setFolderActionError('');
  }, []);

  const cancelRenameFolder = useCallback(() => {
    setEditingFolderId(null);
    setEditingFolderName('');
    setFolderActionError('');
  }, []);

  const handleRenameFolder = useCallback(async () => {
    if (!editingFolderId) return;

    const trimmedName = editingFolderName.trim();
    if (!trimmedName || isRenamingFolderId) return;

    setIsRenamingFolderId(editingFolderId);
    setFolderActionError('');

    try {
      const response = await fetch(`/api/folders?id=${editingFolderId}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name: trimmedName }),
      });

      if (!response.ok) {
        throw new Error(await getResponseErrorTextWithRequestId(response, 'Не удалось переименовать папку'));
      }

      setEditingFolderId(null);
      setEditingFolderName('');
      await refreshFolders();
      toast.success('Название папки обновлено');
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Не удалось переименовать папку';
      setFolderActionError(message);
      toast.error(message);
    } finally {
      setIsRenamingFolderId(null);
    }
  }, [editingFolderId, editingFolderName, isRenamingFolderId, refreshFolders, toast]);

  const handleDeleteFolder = useCallback(async (folderId: string) => {
    if (isDeletingFolderId) return;

    setIsDeletingFolderId(folderId);
    setFolderActionError('');

    try {
      const response = await fetch(`/api/folders?id=${folderId}`, { method: 'DELETE' });
      if (!response.ok) {
        throw new Error(await getResponseErrorTextWithRequestId(response, 'Не удалось удалить папку'));
      }

      if (activeFolderId === folderId) {
        onFolderClick(folderId);
      }

      setOpenFolderMenuId(null);
      await refreshFolders();
      toast.success('Папка удалена');
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Не удалось удалить папку';
      setFolderActionError(message);
      toast.error(message);
    } finally {
      setIsDeletingFolderId(null);
    }
  }, [activeFolderId, isDeletingFolderId, onFolderClick, refreshFolders, toast]);

  return (
    <aside ref={sidebarRef} className="relative hidden w-64 shrink-0 flex-col border-r border-white/10 bg-[#0A0A0A] lg:flex">
      <div className="pointer-events-none absolute inset-0 bg-gradient-to-b from-violet-500/10 via-transparent to-transparent" />

      <div className="relative z-10 flex h-16 items-center justify-between border-b border-white/10 px-6">
        <Link href="/" className="group inline-flex items-center gap-2">
          <span className="inline-flex h-7 w-7 items-center justify-center rounded-lg bg-gradient-to-br from-fuchsia-500 to-violet-600 text-white shadow-[0_0_20px_rgba(139,92,246,0.24)]">
            <LinkIcon className="h-4 w-4" strokeWidth={2.5} />
          </span>
          <span className="text-[18px] font-semibold tracking-tight text-white transition-colors group-hover:text-violet-300">{appName}</span>
        </Link>
      </div>

      <div className="relative z-10 flex min-h-0 flex-1 flex-col overflow-hidden p-4">
        <button
          type="button"
          onClick={onCreateClick}
          className="mb-6 inline-flex w-full items-center justify-center gap-2 rounded-xl bg-gradient-to-r from-fuchsia-500 to-violet-600 px-4 py-2.5 font-medium text-white shadow-[0_12px_35px_rgba(139,92,246,0.25)] transition-all duration-200 hover:opacity-95"
        >
          <Plus className="h-4 w-4" />
          Создать ссылку
        </button>

        <div className="mb-8">
          <p className="mb-3 px-3 text-[11px] font-semibold uppercase tracking-[0.16em] text-gray-500">Меню</p>
          <div className="space-y-1">
            {tabItems.map(({ id, label, Icon }) => {
              const active = currentTab === id;
              return (
                <button
                  key={id}
                  type="button"
                  onClick={() => onTabChange(id)}
                  className={`inline-flex w-full items-center gap-2 rounded-lg border px-3 py-2 text-sm font-medium transition-all duration-200 ${
                    active
                      ? 'border-white/10 bg-white/5 text-white'
                      : 'border-transparent bg-transparent text-gray-400 hover:bg-white/[0.03] hover:text-white'
                  }`}
                >
                  <Icon className={`h-4 w-4 ${active ? 'text-violet-300' : 'text-gray-500'}`} />
                  {label}
                </button>
              );
            })}
          </div>
        </div>

        <div className="min-h-0 flex flex-1 flex-col">
          <div className="mb-3 flex items-center justify-between px-3">
            <p className="text-[11px] font-semibold uppercase tracking-[0.16em] text-gray-500">Папки</p>
            <button
              type="button"
              onClick={() => {
                setIsCreateFolderOpen((prev) => !prev);
                setEditingFolderId(null);
                setOpenFolderMenuId(null);
                setFolderActionError('');
              }}
              className="inline-flex h-6 w-6 items-center justify-center rounded-md border border-white/10 bg-white/[0.03] text-gray-400 transition-colors hover:bg-white/[0.08] hover:text-white"
              title="Новая папка"
            >
              {isCreateFolderOpen ? <X className="h-3.5 w-3.5" /> : <Plus className="h-3.5 w-3.5" />}
            </button>
          </div>

          <AnimatePresence initial={false}>
            {isCreateFolderOpen ? (
              <motion.div
                initial={{ opacity: 0, y: -6 }}
                animate={{ opacity: 1, y: 0 }}
                exit={{ opacity: 0, y: -6 }}
                transition={{ duration: 0.16 }}
                className="mb-2 rounded-xl border border-white/10 bg-black/35 p-2"
              >
                <label className="sr-only" htmlFor="profile-new-folder">
                  Название папки
                </label>
                <input
                  id="profile-new-folder"
                  value={newFolderName}
                  onChange={(event) => setNewFolderName(event.target.value)}
                  onKeyDown={(event) => {
                    if (event.key === 'Enter') {
                      event.preventDefault();
                      void handleCreateFolder();
                    }
                  }}
                  placeholder="Название папки..."
                  className="mb-2 h-9 w-full rounded-lg border border-white/10 bg-black/40 px-3 text-xs text-white placeholder:text-gray-500 outline-none transition-colors focus:border-violet-500/40"
                />
                <div className="flex items-center gap-1.5">
                  <button
                    type="button"
                    onClick={() => void handleCreateFolder()}
                    disabled={isCreatingFolder || !newFolderName.trim()}
                    className="inline-flex flex-1 items-center justify-center gap-1 rounded-lg border border-violet-500/30 bg-violet-500/15 px-2 py-1.5 text-xs text-violet-100 transition-colors hover:bg-violet-500/25 disabled:cursor-not-allowed disabled:opacity-60"
                  >
                    {isCreatingFolder ? (
                      <>
                        <span className="h-3 w-3 animate-spin rounded-full border border-violet-200 border-t-transparent" />
                        Создание...
                      </>
                    ) : (
                      <>
                        <Check className="h-3.5 w-3.5" />
                        Создать
                      </>
                    )}
                  </button>
                  <button
                    type="button"
                    onClick={() => {
                      setIsCreateFolderOpen(false);
                      setNewFolderName('');
                      setFolderActionError('');
                    }}
                    className="inline-flex flex-1 items-center justify-center rounded-lg border border-white/10 bg-white/[0.03] px-2 py-1.5 text-xs text-gray-300 transition-colors hover:bg-white/[0.08] hover:text-white"
                  >
                    Отмена
                  </button>
                </div>
              </motion.div>
            ) : null}
          </AnimatePresence>

          <div className="min-h-0 flex-1 overflow-y-auto pr-1 [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden">
            <div className="space-y-1">
              {folders.length > 0 ? (
                folders.map((folder) => {
                  const active = activeFolderId === folder.id;
                  const isEditing = editingFolderId === folder.id;
                  return (
                    <div key={folder.id} className="relative">
                      {isEditing ? (
                        <div className="rounded-lg border border-white/10 bg-black/35 p-2">
                          <input
                            value={editingFolderName}
                            onChange={(event) => setEditingFolderName(event.target.value)}
                            onKeyDown={(event) => {
                              if (event.key === 'Enter') {
                                event.preventDefault();
                                void handleRenameFolder();
                              }
                              if (event.key === 'Escape') {
                                event.preventDefault();
                                cancelRenameFolder();
                              }
                            }}
                            className="mb-1.5 h-8 w-full rounded-md border border-white/10 bg-black/40 px-2 text-xs text-white outline-none transition-colors focus:border-violet-500/40"
                            placeholder="Название папки"
                          />
                          <div className="flex items-center gap-1.5">
                            <button
                              type="button"
                              onClick={() => void handleRenameFolder()}
                              disabled={isRenamingFolderId === folder.id || !editingFolderName.trim()}
                              className="inline-flex flex-1 items-center justify-center gap-1 rounded-md border border-violet-500/30 bg-violet-500/15 px-2 py-1 text-[11px] text-violet-100 transition-colors hover:bg-violet-500/25 disabled:cursor-not-allowed disabled:opacity-60"
                            >
                              {isRenamingFolderId === folder.id ? (
                                <>
                                  <span className="h-3 w-3 animate-spin rounded-full border border-violet-200 border-t-transparent" />
                                  Сохранение...
                                </>
                              ) : (
                                'Сохранить'
                              )}
                            </button>
                            <button
                              type="button"
                              onClick={cancelRenameFolder}
                              className="inline-flex flex-1 items-center justify-center rounded-md border border-white/10 bg-white/[0.03] px-2 py-1 text-[11px] text-gray-300 transition-colors hover:bg-white/[0.08] hover:text-white"
                            >
                              Отмена
                            </button>
                          </div>
                        </div>
                      ) : (
                        <div
                          className={`inline-flex w-full items-center rounded-lg border px-2 py-1.5 text-sm transition-all duration-200 ${
                            active
                              ? 'border-violet-500/20 bg-violet-500/10 text-violet-200'
                              : 'border-transparent bg-transparent text-gray-400 hover:bg-white/[0.03] hover:text-white'
                          }`}
                        >
                          <button
                            type="button"
                            onClick={() => onFolderClick(folder.id)}
                            className="inline-flex min-w-0 flex-1 items-center justify-between gap-2 text-left"
                          >
                            <span className="inline-flex min-w-0 items-center gap-2">
                              <FolderOpen className={`h-4 w-4 shrink-0 ${active ? 'text-violet-300' : 'text-gray-500'}`} />
                              <span className="truncate">{folder.name}</span>
                            </span>
                            <span className="shrink-0 rounded border border-white/10 bg-black/40 px-1.5 py-0.5 text-[10px] text-gray-500">
                              {typeof folder._count?.links === 'number' ? Math.max(0, folder._count.links) : 0}
                            </span>
                          </button>

                          <div className="relative ml-1 shrink-0">
                            <button
                              type="button"
                              onClick={(event) => {
                                event.stopPropagation();
                                setOpenFolderMenuId((prev) => (prev === folder.id ? null : folder.id));
                                setEditingFolderId(null);
                              }}
                              className="inline-flex h-7 w-7 items-center justify-center rounded-md border border-transparent text-gray-500 transition-colors hover:border-white/10 hover:bg-white/[0.08] hover:text-white"
                              title="Действия"
                            >
                              <MoreVertical className="h-3.5 w-3.5" />
                            </button>

                            <AnimatePresence>
                              {openFolderMenuId === folder.id ? (
                                <motion.div
                                  initial={{ opacity: 0, y: 4, scale: 0.98 }}
                                  animate={{ opacity: 1, y: 0, scale: 1 }}
                                  exit={{ opacity: 0, y: 4, scale: 0.98 }}
                                  transition={{ duration: 0.14 }}
                                  className="absolute right-0 top-[115%] z-30 mt-1 w-40 rounded-lg border border-white/10 bg-[#111] p-1.5 shadow-[0_10px_35px_rgba(0,0,0,0.6)]"
                                >
                                  <button
                                    type="button"
                                    onClick={() => startRenameFolder(folder)}
                                    className="inline-flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-xs text-gray-300 transition-colors hover:bg-white/[0.06] hover:text-white"
                                  >
                                    <PencilLine className="h-3.5 w-3.5 text-blue-300" />
                                    Переименовать
                                  </button>
                                  <button
                                    type="button"
                                    disabled={isDeletingFolderId === folder.id}
                                    onClick={() => void handleDeleteFolder(folder.id)}
                                    className="inline-flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-xs text-red-200 transition-colors hover:bg-red-500/15 disabled:cursor-not-allowed disabled:opacity-60"
                                  >
                                    <Trash2 className="h-3.5 w-3.5" />
                                    {isDeletingFolderId === folder.id ? 'Удаление...' : 'Удалить'}
                                  </button>
                                </motion.div>
                              ) : null}
                            </AnimatePresence>
                          </div>
                        </div>
                      )}
                    </div>
                  );
                })
              ) : (
                <div className="rounded-lg border border-white/5 bg-white/[0.01] px-3 py-2 text-xs text-gray-500">Пока нет папок</div>
              )}
            </div>
          </div>

          {folderActionError ? (
            <p className="mt-2 rounded-lg border border-red-500/20 bg-red-500/10 px-2.5 py-1.5 text-[11px] text-red-200">
              {folderActionError}
            </p>
          ) : null}
        </div>
      </div>

      <div className="relative z-10 border-t border-white/10 bg-[#0A0A0A] p-4">
        <ProfileAccountMenu
          displayName={displayName}
          avatarInitials={avatarInitials}
          isAdmin={isAdmin}
          onOpenSettings={onOpenSettings}
          onLogout={onLogout}
        />
      </div>
    </aside>
  );
}
