import { useState } from 'react';
import { useOutletContext, useParams } from 'react-router';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import {
  Download,
  Puzzle,
  Search,
  Star,
  ToggleLeft,
  ToggleRight,
  Trash2,
  Upload,
  Store,
  Plus,
  Pencil,
} from 'lucide-react';
import { toast } from 'sonner';
import { api, ApiError } from '@/lib/api';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from '@/components/ui/dialog';

interface PluginInstallField {
  key: string;
  label: string;
  type: 'text' | 'number' | 'boolean' | 'select';
  description?: string;
  required?: boolean;
  defaultValue?: unknown;
  options?: Array<{ label: string; value: string }>;
  min?: number;
  max?: number;
  pattern?: string;
  secret?: boolean;
}

interface InstalledPluginRelease {
  id: string;
  version: string;
  installSchema: PluginInstallField[];
}

interface InstalledPlugin {
  id: string;
  pluginId: string;
  releaseId: string | null;
  name: string;
  slug: string;
  description: string | null;
  source: 'spiget' | 'manual';
  externalId: string | null;
  installedVersion: string | null;
  isActive: boolean;
  installOptions: Record<string, unknown>;
  autoUpdateChannel: 'stable' | 'beta' | 'alpha';
  isPinned: boolean;
  status: 'installed' | 'updating' | 'failed';
  lastError: string | null;
  updateAvailable: boolean;
  latestReleaseId: string | null;
  latestVersion: string | null;
  latestChannel: 'stable' | 'beta' | 'alpha' | null;
  installedAt: string;
  currentRelease: InstalledPluginRelease | null;
}

interface SpigetResult {
  id: number;
  name: string;
  tag: string;
  downloads: number;
  rating: { average: number; count: number };
  updateDate: number;
  external: boolean;
}

interface MarketplacePlugin {
  id: string;
  name: string;
  slug: string;
  description: string | null;
  source: 'spiget' | 'manual';
  externalId: string | null;
  downloadUrl: string | null;
  version: string | null;
  updatedAt: string;
  isInstalled: boolean;
  installId: string | null;
  installedVersion: string | null;
  isActive: boolean;
  isPinned: boolean;
  autoUpdateChannel: 'stable' | 'beta' | 'alpha';
  installedAt: string | null;
  releaseId: string | null;
  updateAvailable: boolean;
  latestRelease: {
    id: string;
    version: string;
    channel: 'stable' | 'beta' | 'alpha';
    artifactType: 'file' | 'zip';
    artifactUrl: string;
    installSchema: PluginInstallField[];
  } | null;
}

interface MarketplaceResponse {
  game: {
    id: string;
    slug: string;
    name: string;
  };
  plugins: MarketplacePlugin[];
}

function extractApiMessage(error: unknown, fallback: string): string {
  if (error instanceof ApiError && error.data && typeof error.data === 'object') {
    const maybeMessage = (error.data as { message?: unknown }).message;
    if (typeof maybeMessage === 'string' && maybeMessage.trim()) {
      return maybeMessage;
    }
  }
  return fallback;
}

function buildInstallOptionsState(
  fields: PluginInstallField[],
  current: Record<string, unknown> = {},
): Record<string, unknown> {
  const next: Record<string, unknown> = {};

  for (const field of fields) {
    if (field.defaultValue !== undefined) {
      next[field.key] = field.defaultValue;
    }
  }

  for (const [key, value] of Object.entries(current)) {
    next[key] = value;
  }

  return next;
}

function PluginInstallSchemaFields({
  fields,
  values,
  onChange,
}: {
  fields: PluginInstallField[];
  values: Record<string, unknown>;
  onChange: (next: Record<string, unknown>) => void;
}) {
  return (
    <>
      {fields.map((field) => (
        <div className="space-y-2" key={field.key}>
          <Label>{field.label}</Label>
          {field.type === 'select' ? (
            <select
              className="h-10 w-full rounded-md border bg-background px-3 text-sm"
              value={String(values[field.key] ?? '')}
              onChange={(e) => onChange({ ...values, [field.key]: e.target.value })}
            >
              <option value="">Select...</option>
              {(field.options ?? []).map((option) => (
                <option key={option.value} value={option.value}>
                  {option.label}
                </option>
              ))}
            </select>
          ) : field.type === 'boolean' ? (
            <label className="inline-flex items-center gap-2 text-sm">
              <input
                type="checkbox"
                checked={Boolean(values[field.key])}
                onChange={(e) => onChange({ ...values, [field.key]: e.target.checked })}
              />
              Enabled
            </label>
          ) : (
            <Input
              type={field.type === 'number' ? 'number' : field.secret ? 'password' : 'text'}
              value={String(values[field.key] ?? '')}
              onChange={(e) =>
                onChange({
                  ...values,
                  [field.key]:
                    field.type === 'number'
                      ? e.target.value === ''
                        ? ''
                        : Number(e.target.value)
                      : e.target.value,
                })
              }
              min={field.type === 'number' ? field.min : undefined}
              max={field.type === 'number' ? field.max : undefined}
              pattern={field.type === 'text' ? field.pattern : undefined}
              required={Boolean(field.required)}
            />
          )}
          {field.description && (
            <p className="text-xs text-muted-foreground">{field.description}</p>
          )}
        </div>
      ))}
    </>
  );
}

export function PluginsPage() {
  const { orgId, serverId } = useParams();
  const { server } = useOutletContext<{ server?: { gameSlug: string } }>();
  const isMinecraft = server?.gameSlug === 'minecraft-java';

  const { data: pluginsData } = useQuery({
    queryKey: ['plugins', orgId, serverId],
    queryFn: () =>
      api.get<{ plugins: InstalledPlugin[] }>(
        `/organizations/${orgId}/servers/${serverId}/plugins`,
      ),
  });

  const installed = pluginsData?.plugins ?? [];

  return (
    <Tabs defaultValue="marketplace" className="space-y-4">
      <TabsList className="flex h-auto w-full flex-wrap">
        <TabsTrigger value="marketplace">
          <Store className="mr-1.5 h-3.5 w-3.5" />
          Marketplace
        </TabsTrigger>
        <TabsTrigger value="installed">
          <Puzzle className="mr-1.5 h-3.5 w-3.5" />
          Installed ({installed.length})
        </TabsTrigger>
        {isMinecraft && (
          <TabsTrigger value="search">
            <Search className="mr-1.5 h-3.5 w-3.5" />
            Spiget Search
          </TabsTrigger>
        )}
        <TabsTrigger value="manual">
          <Upload className="mr-1.5 h-3.5 w-3.5" />
          Manual Install
        </TabsTrigger>
      </TabsList>

      <TabsContent value="marketplace">
        <MarketplacePlugins orgId={orgId!} serverId={serverId!} />
      </TabsContent>

      <TabsContent value="installed">
        <InstalledPlugins installed={installed} orgId={orgId!} serverId={serverId!} />
      </TabsContent>

      {isMinecraft && (
        <TabsContent value="search">
          <SpigetSearch orgId={orgId!} serverId={serverId!} />
        </TabsContent>
      )}

      <TabsContent value="manual">
        <ManualInstall orgId={orgId!} serverId={serverId!} />
      </TabsContent>
    </Tabs>
  );
}

function MarketplacePlugins({ orgId, serverId }: { orgId: string; serverId: string }) {
  const queryClient = useQueryClient();
  const [search, setSearch] = useState('');
  const [searchTerm, setSearchTerm] = useState('');
  const [createOpen, setCreateOpen] = useState(false);
  const [editOpen, setEditOpen] = useState(false);
  const [editingPluginId, setEditingPluginId] = useState<string | null>(null);
  const [name, setName] = useState('');
  const [slug, setSlug] = useState('');
  const [downloadUrl, setDownloadUrl] = useState('');
  const [version, setVersion] = useState('');
  const [description, setDescription] = useState('');
  const [installDialogOpen, setInstallDialogOpen] = useState(false);
  const [installTarget, setInstallTarget] = useState<MarketplacePlugin | null>(null);
  const [installOptions, setInstallOptions] = useState<Record<string, unknown>>({});
  const [installPinVersion, setInstallPinVersion] = useState(false);
  const [installAutoUpdateChannel, setInstallAutoUpdateChannel] = useState<
    'stable' | 'beta' | 'alpha'
  >('stable');

  const { data, isLoading } = useQuery({
    queryKey: ['plugin-marketplace', orgId, serverId, searchTerm],
    queryFn: () =>
      api.get<MarketplaceResponse>(
        `/organizations/${orgId}/servers/${serverId}/plugins/marketplace`,
        searchTerm ? { q: searchTerm } : undefined,
      ),
  });

  const installMutation = useMutation({
    mutationFn: ({
      pluginId,
      payload,
    }: {
      pluginId: string;
      payload?: {
        releaseId?: string;
        options?: Record<string, unknown>;
        pinVersion?: boolean;
        autoUpdateChannel?: 'stable' | 'beta' | 'alpha';
      };
    }) =>
      api.post(
        `/organizations/${orgId}/servers/${serverId}/plugins/install/${pluginId}`,
        payload ?? {},
      ),
    onSuccess: () => {
      toast.success('Plugin installed');
      setInstallDialogOpen(false);
      setInstallTarget(null);
      setInstallOptions({});
      queryClient.invalidateQueries({ queryKey: ['plugins', orgId, serverId] });
      queryClient.invalidateQueries({ queryKey: ['plugin-marketplace', orgId, serverId] });
    },
    onError: (error) => {
      toast.error(extractApiMessage(error, 'Plugin install failed'));
    },
  });

  const uninstallMutation = useMutation({
    mutationFn: (installId: string) =>
      api.delete(`/organizations/${orgId}/servers/${serverId}/plugins/${installId}`),
    onSuccess: () => {
      toast.success('Plugin uninstalled');
      queryClient.invalidateQueries({ queryKey: ['plugins', orgId, serverId] });
      queryClient.invalidateQueries({ queryKey: ['plugin-marketplace', orgId, serverId] });
    },
    onError: (error) => {
      toast.error(extractApiMessage(error, 'Plugin uninstall failed'));
    },
  });

  const updateInstallMutation = useMutation({
    mutationFn: ({ installId }: { installId: string }) =>
      api.post(`/organizations/${orgId}/servers/${serverId}/plugins/${installId}/update`),
    onSuccess: () => {
      toast.success('Plugin updated');
      queryClient.invalidateQueries({ queryKey: ['plugins', orgId, serverId] });
      queryClient.invalidateQueries({ queryKey: ['plugin-marketplace', orgId, serverId] });
    },
    onError: (error) => {
      toast.error(extractApiMessage(error, 'Plugin update failed'));
    },
  });

  const createMutation = useMutation({
    mutationFn: (body: {
      name: string;
      slug?: string;
      description?: string;
      downloadUrl: string;
      version?: string;
    }) => api.post(`/organizations/${orgId}/servers/${serverId}/plugins/marketplace`, body),
    onSuccess: () => {
      toast.success('Marketplace plugin added');
      setCreateOpen(false);
      setName('');
      setSlug('');
      setDownloadUrl('');
      setVersion('');
      setDescription('');
      queryClient.invalidateQueries({ queryKey: ['plugin-marketplace', orgId, serverId] });
    },
    onError: (error) => {
      toast.error(extractApiMessage(error, 'Failed to add marketplace plugin'));
    },
  });

  const deleteMutation = useMutation({
    mutationFn: (pluginId: string) =>
      api.delete(`/organizations/${orgId}/servers/${serverId}/plugins/marketplace/${pluginId}`),
    onSuccess: () => {
      toast.success('Marketplace plugin removed');
      queryClient.invalidateQueries({ queryKey: ['plugin-marketplace', orgId, serverId] });
    },
    onError: (error) => {
      toast.error(extractApiMessage(error, 'Failed to remove marketplace plugin'));
    },
  });

  const updateMutation = useMutation({
    mutationFn: (body: {
      pluginId: string;
      name: string;
      slug?: string;
      description?: string;
      downloadUrl?: string;
      version?: string;
    }) =>
      api.patch(
        `/organizations/${orgId}/servers/${serverId}/plugins/marketplace/${body.pluginId}`,
        {
          name: body.name,
          slug: body.slug,
          description: body.description,
          downloadUrl: body.downloadUrl,
          version: body.version,
        },
      ),
    onSuccess: () => {
      toast.success('Marketplace plugin updated');
      setEditOpen(false);
      setEditingPluginId(null);
      setName('');
      setSlug('');
      setDownloadUrl('');
      setVersion('');
      setDescription('');
      queryClient.invalidateQueries({ queryKey: ['plugin-marketplace', orgId, serverId] });
    },
    onError: (error) => {
      toast.error(extractApiMessage(error, 'Failed to update marketplace plugin'));
    },
  });

  const openEditDialog = (plugin: MarketplacePlugin) => {
    setEditingPluginId(plugin.id);
    setName(plugin.name);
    setSlug(plugin.slug);
    setDownloadUrl(plugin.downloadUrl ?? '');
    setVersion(plugin.version ?? '');
    setDescription(plugin.description ?? '');
    setEditOpen(true);
  };

  const openInstallDialog = (plugin: MarketplacePlugin) => {
    const fields = plugin.latestRelease?.installSchema ?? [];
    setInstallTarget(plugin);
    setInstallOptions(buildInstallOptionsState(fields));
    setInstallPinVersion(false);
    setInstallAutoUpdateChannel('stable');
    setInstallDialogOpen(true);
  };

  const installDirect = (plugin: MarketplacePlugin) => {
    installMutation.mutate({
      pluginId: plugin.id,
      payload: {
        releaseId: plugin.latestRelease?.id ?? undefined,
        pinVersion: false,
        autoUpdateChannel: 'stable',
      },
    });
  };

  const plugins = data?.plugins ?? [];
  const gameName = data?.game.name ?? 'Game';

  return (
    <div className="space-y-4">
      <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <div>
          <h3 className="text-lg font-semibold">{gameName} Marketplace</h3>
          <p className="text-sm text-muted-foreground">
            Oyununuza uygun eklentileri tek tıkla kur/kaldırın.
          </p>
        </div>
        <Dialog open={createOpen} onOpenChange={setCreateOpen}>
          <DialogTrigger asChild>
            <Button>
              <Plus className="h-4 w-4" />
              Plugin Ekle
            </Button>
          </DialogTrigger>
          <DialogContent>
            <DialogHeader>
              <DialogTitle>Marketplace Plugin Ekle</DialogTitle>
            </DialogHeader>
            <form
              className="space-y-4"
              onSubmit={(e) => {
                e.preventDefault();
                createMutation.mutate({
                  name,
                  slug: slug || undefined,
                  description: description || undefined,
                  downloadUrl,
                  version: version || undefined,
                });
              }}
            >
              <div className="space-y-2">
                <Label>Plugin Name</Label>
                <Input value={name} onChange={(e) => setName(e.target.value)} required />
              </div>
              <div className="space-y-2">
                <Label>Slug (optional)</Label>
                <Input value={slug} onChange={(e) => setSlug(e.target.value)} />
              </div>
              <div className="space-y-2">
                <Label>Download URL</Label>
                <Input
                  type="url"
                  value={downloadUrl}
                  onChange={(e) => setDownloadUrl(e.target.value)}
                  placeholder="https://example.com/plugin.jar"
                  required
                />
              </div>
              <div className="space-y-2">
                <Label>Version (optional)</Label>
                <Input value={version} onChange={(e) => setVersion(e.target.value)} />
              </div>
              <div className="space-y-2">
                <Label>Description (optional)</Label>
                <Input value={description} onChange={(e) => setDescription(e.target.value)} />
              </div>
              <DialogFooter>
                <Button type="submit" disabled={createMutation.isPending}>
                  {createMutation.isPending ? 'Ekleniyor...' : 'Ekle'}
                </Button>
              </DialogFooter>
            </form>
          </DialogContent>
        </Dialog>
        <Dialog
          open={editOpen}
          onOpenChange={(open) => {
            setEditOpen(open);
            if (!open) {
              setEditingPluginId(null);
              setName('');
              setSlug('');
              setDownloadUrl('');
              setVersion('');
              setDescription('');
            }
          }}
        >
          <DialogContent>
            <DialogHeader>
              <DialogTitle>Marketplace Plugin Düzenle</DialogTitle>
            </DialogHeader>
            <form
              className="space-y-4"
              onSubmit={(e) => {
                e.preventDefault();
                if (!editingPluginId) return;
                updateMutation.mutate({
                  pluginId: editingPluginId,
                  name,
                  slug: slug || undefined,
                  description: description || undefined,
                  downloadUrl: downloadUrl || undefined,
                  version: version || undefined,
                });
              }}
            >
              <div className="space-y-2">
                <Label>Plugin Name</Label>
                <Input value={name} onChange={(e) => setName(e.target.value)} required />
              </div>
              <div className="space-y-2">
                <Label>Slug (optional)</Label>
                <Input value={slug} onChange={(e) => setSlug(e.target.value)} />
              </div>
              <div className="space-y-2">
                <Label>Download URL (optional)</Label>
                <Input
                  type="url"
                  value={downloadUrl}
                  onChange={(e) => setDownloadUrl(e.target.value)}
                  placeholder="https://example.com/plugin.jar"
                />
              </div>
              <div className="space-y-2">
                <Label>Version (optional)</Label>
                <Input value={version} onChange={(e) => setVersion(e.target.value)} />
              </div>
              <div className="space-y-2">
                <Label>Description (optional)</Label>
                <Input value={description} onChange={(e) => setDescription(e.target.value)} />
              </div>
              <DialogFooter>
                <Button type="submit" disabled={updateMutation.isPending}>
                  {updateMutation.isPending ? 'Kaydediliyor...' : 'Kaydet'}
                </Button>
              </DialogFooter>
            </form>
          </DialogContent>
        </Dialog>
      </div>

      <div className="flex gap-2">
        <Input
          placeholder="Plugin ara..."
          value={search}
          onChange={(e) => setSearch(e.target.value)}
          onKeyDown={(e) => {
            if (e.key === 'Enter') setSearchTerm(search.trim());
          }}
        />
        <Button onClick={() => setSearchTerm(search.trim())}>
          <Search className="h-4 w-4" />
          Ara
        </Button>
      </div>

      {isLoading && <p className="text-sm text-muted-foreground">Marketplace yükleniyor...</p>}

      {!isLoading && plugins.length === 0 && (
        <Card>
          <CardContent className="flex flex-col items-center justify-center py-10 text-center">
            <Store className="mb-3 h-10 w-10 text-muted-foreground/60" />
            <p className="font-medium">Bu oyun için plugin bulunamadı</p>
            <p className="text-sm text-muted-foreground">
              Yetkili kullanıcılar yukarıdan marketplace plugin ekleyebilir.
            </p>
          </CardContent>
        </Card>
      )}

      <div className="space-y-2">
        {plugins.map((plugin) => (
          <Card key={plugin.id}>
            <CardContent className="flex flex-col gap-3 p-4 sm:flex-row sm:items-center sm:justify-between">
              <div className="space-y-1">
                <div className="flex flex-wrap items-center gap-2">
                  <p className="font-medium">{plugin.name}</p>
                  <Badge variant="outline">{plugin.source}</Badge>
                  {plugin.latestRelease?.version && (
                    <Badge variant="secondary">v{plugin.latestRelease.version}</Badge>
                  )}
                  {plugin.isInstalled && <Badge>Installed</Badge>}
                  {plugin.updateAvailable && <Badge variant="destructive">Update Available</Badge>}
                </div>
                {plugin.description && (
                  <p className="text-sm text-muted-foreground">{plugin.description}</p>
                )}
                {plugin.latestRelease?.artifactUrl && (
                  <p className="line-clamp-1 text-xs text-muted-foreground">
                    {plugin.latestRelease.artifactUrl}
                  </p>
                )}
              </div>
              <div className="flex flex-wrap items-center gap-2">
                {plugin.isInstalled && plugin.installId ? (
                  <>
                    {plugin.updateAvailable && (
                      <Button
                        size="sm"
                        variant="secondary"
                        onClick={() =>
                          updateInstallMutation.mutate({ installId: plugin.installId! })
                        }
                        disabled={updateInstallMutation.isPending}
                      >
                        <Download className="h-4 w-4" />
                        Güncelle
                      </Button>
                    )}
                    <Button
                      variant="destructive"
                      size="sm"
                      onClick={() => uninstallMutation.mutate(plugin.installId!)}
                      disabled={uninstallMutation.isPending}
                    >
                      <Trash2 className="h-4 w-4" />
                      Kaldır
                    </Button>
                  </>
                ) : (
                  <>
                    {(plugin.latestRelease?.installSchema?.length ?? 0) > 0 ? (
                      <Button
                        size="sm"
                        onClick={() => openInstallDialog(plugin)}
                        disabled={installMutation.isPending}
                      >
                        <Download className="h-4 w-4" />
                        Ayarla ve Kur
                      </Button>
                    ) : (
                      <Button
                        size="sm"
                        onClick={() => installDirect(plugin)}
                        disabled={installMutation.isPending}
                      >
                        <Download className="h-4 w-4" />
                        Kur
                      </Button>
                    )}
                  </>
                )}

                <Button
                  size="icon"
                  variant="ghost"
                  onClick={() => openEditDialog(plugin)}
                  title="Marketplace kaydını düzenle"
                >
                  <Pencil className="h-4 w-4" />
                </Button>

                <Button
                  size="icon"
                  variant="ghost"
                  onClick={() => deleteMutation.mutate(plugin.id)}
                  disabled={deleteMutation.isPending || plugin.isInstalled}
                  title={plugin.isInstalled ? 'Önce sunucudan kaldırın' : 'Marketplace kaydını sil'}
                >
                  <Trash2 className="h-4 w-4 text-destructive" />
                </Button>
              </div>
            </CardContent>
          </Card>
        ))}
      </div>

      <Dialog open={installDialogOpen} onOpenChange={setInstallDialogOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>
              Install Plugin
              {installTarget ? ` - ${installTarget.name}` : ''}
            </DialogTitle>
          </DialogHeader>
          <form
            className="space-y-4"
            onSubmit={(event) => {
              event.preventDefault();
              if (!installTarget) return;

              installMutation.mutate({
                pluginId: installTarget.id,
                payload: {
                  releaseId: installTarget.latestRelease?.id ?? undefined,
                  options: installOptions,
                  pinVersion: installPinVersion,
                  autoUpdateChannel: installAutoUpdateChannel,
                },
              });
            }}
          >
            <PluginInstallSchemaFields
              fields={installTarget?.latestRelease?.installSchema ?? []}
              values={installOptions}
              onChange={setInstallOptions}
            />

            <div className="space-y-2">
              <Label>Auto Update Channel</Label>
              <select
                className="h-10 w-full rounded-md border bg-background px-3 text-sm"
                value={installAutoUpdateChannel}
                onChange={(e) =>
                  setInstallAutoUpdateChannel(e.target.value as 'stable' | 'beta' | 'alpha')
                }
              >
                <option value="stable">stable</option>
                <option value="beta">beta</option>
                <option value="alpha">alpha</option>
              </select>
            </div>

            <label className="inline-flex items-center gap-2 text-sm">
              <input
                type="checkbox"
                checked={installPinVersion}
                onChange={(e) => setInstallPinVersion(e.target.checked)}
              />
              Pin this release version
            </label>

            <DialogFooter>
              <Button type="submit" disabled={installMutation.isPending || !installTarget}>
                {installMutation.isPending ? 'Installing...' : 'Install'}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>
    </div>
  );
}

function InstalledPlugins({
  installed,
  orgId,
  serverId,
}: {
  installed: InstalledPlugin[];
  orgId: string;
  serverId: string;
}) {
  const queryClient = useQueryClient();
  const [configureDialogOpen, setConfigureDialogOpen] = useState(false);
  const [configureTarget, setConfigureTarget] = useState<InstalledPlugin | null>(null);
  const [configureOptions, setConfigureOptions] = useState<Record<string, unknown>>({});

  const toggleMutation = useMutation({
    mutationFn: (id: string) =>
      api.patch(`/organizations/${orgId}/servers/${serverId}/plugins/${id}/toggle`),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['plugins', orgId, serverId] }),
    onError: (error) => {
      toast.error(extractApiMessage(error, 'Plugin durumu güncellenemedi'));
    },
  });

  const uninstallMutation = useMutation({
    mutationFn: (id: string) =>
      api.delete(`/organizations/${orgId}/servers/${serverId}/plugins/${id}`),
    onSuccess: () => {
      toast.success('Plugin kaldırıldı');
      queryClient.invalidateQueries({ queryKey: ['plugins', orgId, serverId] });
      queryClient.invalidateQueries({ queryKey: ['plugin-marketplace', orgId, serverId] });
    },
    onError: (error) => {
      toast.error(extractApiMessage(error, 'Plugin kaldırılamadı'));
    },
  });

  const updateMutation = useMutation({
    mutationFn: (id: string) =>
      api.post(`/organizations/${orgId}/servers/${serverId}/plugins/${id}/update`),
    onSuccess: () => {
      toast.success('Plugin güncellendi');
      queryClient.invalidateQueries({ queryKey: ['plugins', orgId, serverId] });
      queryClient.invalidateQueries({ queryKey: ['plugin-marketplace', orgId, serverId] });
    },
    onError: (error) => {
      toast.error(extractApiMessage(error, 'Plugin güncellenemedi'));
    },
  });

  const configureMutation = useMutation({
    mutationFn: ({
      id,
      payload,
    }: {
      id: string;
      payload: {
        releaseId: string;
        options: Record<string, unknown>;
      };
    }) => api.post(`/organizations/${orgId}/servers/${serverId}/plugins/${id}/update`, payload),
    onSuccess: () => {
      toast.success('Plugin ayarları güncellendi');
      setConfigureDialogOpen(false);
      setConfigureTarget(null);
      setConfigureOptions({});
      queryClient.invalidateQueries({ queryKey: ['plugins', orgId, serverId] });
      queryClient.invalidateQueries({ queryKey: ['plugin-marketplace', orgId, serverId] });
    },
    onError: (error) => {
      toast.error(extractApiMessage(error, 'Plugin ayarları güncellenemedi'));
    },
  });

  const openConfigureDialog = (plugin: InstalledPlugin) => {
    const fields = plugin.currentRelease?.installSchema ?? [];
    setConfigureTarget(plugin);
    setConfigureOptions(buildInstallOptionsState(fields, plugin.installOptions));
    setConfigureDialogOpen(true);
  };

  if (installed.length === 0) {
    return (
      <Card>
        <CardContent className="flex flex-col items-center justify-center py-12">
          <Puzzle className="mb-4 h-12 w-12 text-muted-foreground/50" />
          <p className="text-muted-foreground">No plugins installed</p>
          <p className="mt-1 text-xs text-muted-foreground">
            Marketplace sekmesinden tek tıkla kurulum yapabilirsiniz.
          </p>
        </CardContent>
      </Card>
    );
  }

  return (
    <>
      <div className="space-y-2">
        {installed.map((plugin) => (
          <Card key={plugin.id}>
            <CardContent className="flex flex-col gap-3 p-4 sm:flex-row sm:items-center sm:justify-between">
              <div className="flex items-start gap-3">
                <Puzzle className="h-5 w-5 text-primary" />
                <div>
                  <div className="flex flex-wrap items-center gap-2">
                    <p className="font-medium">{plugin.name}</p>
                    <Badge variant="outline">{plugin.source}</Badge>
                    {plugin.installedVersion && (
                      <Badge variant="secondary">v{plugin.installedVersion}</Badge>
                    )}
                    {!plugin.isActive && <Badge variant="secondary">Disabled</Badge>}
                    {plugin.status !== 'installed' && (
                      <Badge variant={plugin.status === 'failed' ? 'destructive' : 'outline'}>
                        {plugin.status}
                      </Badge>
                    )}
                    {plugin.updateAvailable && (
                      <Badge variant="destructive">Update Available</Badge>
                    )}
                  </div>
                  {plugin.description && (
                    <p className="text-sm text-muted-foreground">{plugin.description}</p>
                  )}
                  {plugin.latestVersion && (
                    <p className="text-xs text-muted-foreground">
                      Latest: v{plugin.latestVersion}
                      {plugin.latestChannel ? ` (${plugin.latestChannel})` : ''}
                    </p>
                  )}
                  {plugin.lastError && (
                    <p className="text-xs text-destructive">{plugin.lastError}</p>
                  )}
                </div>
              </div>
              <div className="flex items-center gap-2">
                {plugin.currentRelease && plugin.currentRelease.installSchema.length > 0 && (
                  <Button
                    size="icon"
                    variant="ghost"
                    onClick={() => openConfigureDialog(plugin)}
                    title="Ayarları düzenle"
                    disabled={configureMutation.isPending}
                  >
                    <Pencil className="h-4 w-4" />
                  </Button>
                )}
                {plugin.updateAvailable && (
                  <Button
                    size="icon"
                    variant="ghost"
                    onClick={() => updateMutation.mutate(plugin.id)}
                    title="Update"
                    disabled={updateMutation.isPending}
                  >
                    <Download className="h-4 w-4" />
                  </Button>
                )}
                <Button
                  size="icon"
                  variant="ghost"
                  onClick={() => toggleMutation.mutate(plugin.id)}
                  title={plugin.isActive ? 'Disable' : 'Enable'}
                >
                  {plugin.isActive ? (
                    <ToggleRight className="h-4 w-4 text-green-500" />
                  ) : (
                    <ToggleLeft className="h-4 w-4 text-muted-foreground" />
                  )}
                </Button>
                <Button
                  size="icon"
                  variant="ghost"
                  onClick={() => uninstallMutation.mutate(plugin.id)}
                >
                  <Trash2 className="h-4 w-4 text-destructive" />
                </Button>
              </div>
            </CardContent>
          </Card>
        ))}
      </div>

      <Dialog
        open={configureDialogOpen}
        onOpenChange={(open) => {
          setConfigureDialogOpen(open);
          if (!open) {
            setConfigureTarget(null);
            setConfigureOptions({});
          }
        }}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>
              Plugin Ayarları
              {configureTarget ? ` - ${configureTarget.name}` : ''}
            </DialogTitle>
          </DialogHeader>
          <form
            className="space-y-4"
            onSubmit={(event) => {
              event.preventDefault();
              if (!configureTarget?.currentRelease) return;

              configureMutation.mutate({
                id: configureTarget.id,
                payload: {
                  releaseId: configureTarget.currentRelease.id,
                  options: configureOptions,
                },
              });
            }}
          >
            <PluginInstallSchemaFields
              fields={configureTarget?.currentRelease?.installSchema ?? []}
              values={configureOptions}
              onChange={setConfigureOptions}
            />

            <DialogFooter>
              <Button
                type="submit"
                disabled={configureMutation.isPending || !configureTarget?.currentRelease}
              >
                {configureMutation.isPending ? 'Kaydediliyor...' : 'Kaydet'}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>
    </>
  );
}

function SpigetSearch({ orgId, serverId }: { orgId: string; serverId: string }) {
  const queryClient = useQueryClient();
  const [query, setQuery] = useState('');
  const [searchTerm, setSearchTerm] = useState('');

  const { data: results, isLoading } = useQuery({
    queryKey: ['spiget-search', orgId, serverId, searchTerm],
    queryFn: () =>
      api.get<{ results: SpigetResult[] }>(
        `/organizations/${orgId}/servers/${serverId}/plugins/search`,
        { q: searchTerm },
      ),
    enabled: searchTerm.length >= 2,
  });

  const installMutation = useMutation({
    mutationFn: (resourceId: number) =>
      api.post(`/organizations/${orgId}/servers/${serverId}/plugins/install/spiget`, {
        resourceId,
      }),
    onSuccess: () => {
      toast.success('Spiget plugin installed');
      queryClient.invalidateQueries({ queryKey: ['plugins', orgId, serverId] });
      queryClient.invalidateQueries({ queryKey: ['plugin-marketplace', orgId, serverId] });
    },
    onError: (error) => {
      toast.error(extractApiMessage(error, 'Spiget install failed'));
    },
  });

  const handleSearch = () => {
    if (query.length >= 2) setSearchTerm(query);
  };

  return (
    <div className="space-y-4">
      <div className="flex gap-2">
        <Input
          placeholder="Search Spiget plugins (Minecraft only)..."
          value={query}
          onChange={(e) => setQuery(e.target.value)}
          onKeyDown={(e) => e.key === 'Enter' && handleSearch()}
        />
        <Button onClick={handleSearch} disabled={query.length < 2}>
          <Search className="h-4 w-4" />
          Search
        </Button>
      </div>

      {isLoading && <p className="text-sm text-muted-foreground">Searching...</p>}

      {results?.results && results.results.length === 0 && (
        <p className="text-sm text-muted-foreground">No results found</p>
      )}

      <div className="space-y-2">
        {results?.results?.map((r) => (
          <Card key={r.id}>
            <CardContent className="flex items-center justify-between p-4">
              <div>
                <p className="font-medium">{r.name}</p>
                <p className="text-sm text-muted-foreground">{r.tag}</p>
                <div className="mt-1 flex items-center gap-3 text-xs text-muted-foreground">
                  <span className="flex items-center gap-1">
                    <Star className="h-3 w-3" />
                    {r.rating.average.toFixed(1)} ({r.rating.count})
                  </span>
                  <span>
                    <Download className="inline h-3 w-3" /> {r.downloads.toLocaleString()}
                  </span>
                </div>
              </div>
              <Button
                size="sm"
                onClick={() => installMutation.mutate(r.id)}
                disabled={installMutation.isPending || r.external}
              >
                <Download className="h-4 w-4" />
                {r.external ? 'External' : 'Install'}
              </Button>
            </CardContent>
          </Card>
        ))}
      </div>
    </div>
  );
}

function ManualInstall({ orgId, serverId }: { orgId: string; serverId: string }) {
  const queryClient = useQueryClient();
  const [name, setName] = useState('');
  const [filePath, setFilePath] = useState('');
  const [version, setVersion] = useState('');

  const installMutation = useMutation({
    mutationFn: (body: { name: string; filePath: string; version?: string }) =>
      api.post(`/organizations/${orgId}/servers/${serverId}/plugins/install/manual`, body),
    onSuccess: () => {
      toast.success('Plugin registered');
      queryClient.invalidateQueries({ queryKey: ['plugins', orgId, serverId] });
      queryClient.invalidateQueries({ queryKey: ['plugin-marketplace', orgId, serverId] });
      setName('');
      setFilePath('');
      setVersion('');
    },
    onError: (error) => {
      toast.error(extractApiMessage(error, 'Plugin registration failed'));
    },
  });

  return (
    <Card>
      <CardHeader>
        <CardTitle>Manual Plugin Install</CardTitle>
      </CardHeader>
      <CardContent>
        <form
          className="space-y-4"
          onSubmit={(e) => {
            e.preventDefault();
            installMutation.mutate({
              name,
              filePath,
              version: version || undefined,
            });
          }}
        >
          <div className="space-y-2">
            <Label>Plugin Name</Label>
            <Input value={name} onChange={(e) => setName(e.target.value)} required />
          </div>
          <div className="space-y-2">
            <Label>File Path</Label>
            <Input
              value={filePath}
              onChange={(e) => setFilePath(e.target.value)}
              placeholder="plugins/plugin.jar"
              required
            />
            <p className="text-xs text-muted-foreground">
              Files sekmesinden dosyayı önce sunucuya yükleyin. Relative path girerseniz oyunun
              varsayılan plugin dizinine göre çözülür.
            </p>
          </div>
          <div className="space-y-2">
            <Label>Version (optional)</Label>
            <Input value={version} onChange={(e) => setVersion(e.target.value)} />
          </div>
          <Button type="submit" disabled={installMutation.isPending}>
            {installMutation.isPending ? 'Registering...' : 'Register Plugin'}
          </Button>
        </form>
      </CardContent>
    </Card>
  );
}
