import { useMemo, useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { Plus, UploadCloud, Puzzle, Rocket, Copy } 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 {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from '@/components/ui/dialog';

interface Game {
  id: string;
  slug: string;
  name: string;
}

interface GamesResponse {
  data: Game[];
}

interface GlobalPlugin {
  id: string;
  gameId: string;
  gameName: string;
  gameSlug: string;
  name: string;
  slug: string;
  description: string | null;
  source: 'manual' | 'spiget';
  isGlobal: boolean;
}

interface GlobalPluginsResponse {
  data: GlobalPlugin[];
}

interface PluginRelease {
  id: string;
  pluginId: string;
  version: string;
  channel: 'stable' | 'beta' | 'alpha';
  artifactType: 'file' | 'zip';
  artifactUrl: string;
  destination: string | null;
  fileName: string | null;
  changelog: string | null;
  installSchema: unknown[];
  configTemplates: unknown[];
  isPublished: boolean;
  createdAt: string;
  updatedAt: string;
}

interface PluginReleaseResponse {
  plugin: GlobalPlugin;
  releases: PluginRelease[];
}

type ReleaseInputMode = 'url' | 'upload';

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 prettyJson(input: unknown): string {
  try {
    return JSON.stringify(input, null, 2);
  } catch {
    return '[]';
  }
}

function parseJsonArray(raw: string): unknown[] {
  if (raw.trim() === '') return [];
  const parsed = JSON.parse(raw) as unknown;
  if (!Array.isArray(parsed)) {
    throw new Error('JSON value must be an array');
  }
  return parsed;
}

async function parseJsonArrayFile(file: File, label: string): Promise<unknown[]> {
  let raw = await file.text();
  if (raw.charCodeAt(0) === 0xfeff) {
    raw = raw.slice(1);
  }

  try {
    const parsed = JSON.parse(raw) as unknown;
    if (!Array.isArray(parsed)) {
      throw new Error('JSON value must be an array');
    }
    return parsed;
  } catch (error) {
    const message = error instanceof Error ? error.message : 'Invalid JSON';
    throw new Error(`${label}: ${message}`);
  }
}

export function AdminPluginsPage() {
  const queryClient = useQueryClient();

  const [selectedGameId, setSelectedGameId] = useState<string>('');
  const [selectedPluginId, setSelectedPluginId] = useState<string | null>(null);

  const [createPluginOpen, setCreatePluginOpen] = useState(false);
  const [createPluginName, setCreatePluginName] = useState('');
  const [createPluginSlug, setCreatePluginSlug] = useState('');
  const [createPluginDescription, setCreatePluginDescription] = useState('');

  const [createReleaseOpen, setCreateReleaseOpen] = useState(false);
  const [releaseInputMode, setReleaseInputMode] = useState<ReleaseInputMode>('upload');
  const [releaseVersion, setReleaseVersion] = useState('');
  const [releaseChannel, setReleaseChannel] = useState<'stable' | 'beta' | 'alpha'>('stable');
  const [releaseArtifactType, setReleaseArtifactType] = useState<'file' | 'zip'>('file');
  const [releaseArtifactUrl, setReleaseArtifactUrl] = useState('');
  const [releaseDestination, setReleaseDestination] = useState('');
  const [releaseFileName, setReleaseFileName] = useState('');
  const [releaseChangelog, setReleaseChangelog] = useState('');
  const [releaseInstallSchemaJson, setReleaseInstallSchemaJson] = useState('[]');
  const [releaseTemplatesJson, setReleaseTemplatesJson] = useState('[]');
  const [releaseInstallSchemaFile, setReleaseInstallSchemaFile] = useState<File | null>(null);
  const [releaseTemplatesFile, setReleaseTemplatesFile] = useState<File | null>(null);
  const [releaseInstallSchemaFileInputKey, setReleaseInstallSchemaFileInputKey] = useState(0);
  const [releaseTemplatesFileInputKey, setReleaseTemplatesFileInputKey] = useState(0);
  const [releaseArtifactFiles, setReleaseArtifactFiles] = useState<File[]>([]);

  const { data: gamesData } = useQuery({
    queryKey: ['admin-games'],
    queryFn: () => api.get<GamesResponse>('/admin/games'),
  });

  const games = gamesData?.data ?? [];

  const { data: pluginsData } = useQuery({
    queryKey: ['admin-plugins', selectedGameId],
    queryFn: () =>
      api.get<GlobalPluginsResponse>(
        '/admin/plugins',
        selectedGameId ? { gameId: selectedGameId } : undefined,
      ),
  });

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

  const selectedPlugin = useMemo(
    () => plugins.find((plugin) => plugin.id === selectedPluginId) ?? null,
    [plugins, selectedPluginId],
  );

  const { data: releaseData } = useQuery({
    queryKey: ['admin-plugin-releases', selectedPluginId],
    enabled: Boolean(selectedPluginId),
    queryFn: () => api.get<PluginReleaseResponse>(`/admin/plugins/${selectedPluginId}/releases`),
  });

  const releases = releaseData?.releases ?? [];

  const resetReleaseForm = () => {
    setCreateReleaseOpen(false);
    setReleaseInputMode('upload');
    setReleaseVersion('');
    setReleaseChannel('stable');
    setReleaseArtifactType('file');
    setReleaseArtifactUrl('');
    setReleaseDestination('');
    setReleaseFileName('');
    setReleaseChangelog('');
    setReleaseInstallSchemaJson('[]');
    setReleaseTemplatesJson('[]');
    setReleaseInstallSchemaFile(null);
    setReleaseTemplatesFile(null);
    setReleaseInstallSchemaFileInputKey((prev) => prev + 1);
    setReleaseTemplatesFileInputKey((prev) => prev + 1);
    setReleaseArtifactFiles([]);
  };

  const appendReleaseFiles = (incoming: FileList | null) => {
    if (!incoming || incoming.length === 0) return;

    setReleaseArtifactFiles((prev) => {
      const map = new Map<string, File>();

      for (const item of prev) {
        const relative = (item as File & { webkitRelativePath?: string }).webkitRelativePath || item.name;
        map.set(`${relative}::${item.size}::${item.lastModified}`, item);
      }

      for (const item of Array.from(incoming)) {
        const relative = (item as File & { webkitRelativePath?: string }).webkitRelativePath || item.name;
        map.set(`${relative}::${item.size}::${item.lastModified}`, item);
      }

      return Array.from(map.values());
    });
  };

  const createPluginMutation = useMutation({
    mutationFn: (body: {
      gameId: string;
      name: string;
      slug?: string;
      description?: string;
    }) => api.post('/admin/plugins', body),
    onSuccess: () => {
      toast.success('Global plugin created');
      setCreatePluginOpen(false);
      setCreatePluginName('');
      setCreatePluginSlug('');
      setCreatePluginDescription('');
      queryClient.invalidateQueries({ queryKey: ['admin-plugins'] });
    },
    onError: (error) => {
      toast.error(extractApiMessage(error, 'Failed to create plugin'));
    },
  });

  const createReleaseMutation = useMutation({
    mutationFn: (body: {
      version: string;
      channel: 'stable' | 'beta' | 'alpha';
      artifactType: 'file' | 'zip';
      artifactUrl: string;
      destination?: string;
      fileName?: string;
      changelog?: string;
      installSchema?: unknown[];
      configTemplates?: unknown[];
    }) => {
      if (!selectedPluginId) {
        throw new Error('No plugin selected');
      }
      return api.post(`/admin/plugins/${selectedPluginId}/releases`, body);
    },
    onSuccess: () => {
      toast.success('Release published');
      resetReleaseForm();
      queryClient.invalidateQueries({ queryKey: ['admin-plugin-releases', selectedPluginId] });
      queryClient.invalidateQueries({ queryKey: ['admin-plugins'] });
    },
    onError: (error) => {
      toast.error(extractApiMessage(error, 'Failed to publish release'));
    },
  });

  const createUploadReleaseMutation = useMutation({
    mutationFn: (formData: FormData) => {
      if (!selectedPluginId) {
        throw new Error('No plugin selected');
      }
      return api.post(`/admin/plugins/${selectedPluginId}/releases/upload`, formData);
    },
    onSuccess: () => {
      toast.success('Release uploaded and published');
      resetReleaseForm();
      queryClient.invalidateQueries({ queryKey: ['admin-plugin-releases', selectedPluginId] });
      queryClient.invalidateQueries({ queryKey: ['admin-plugins'] });
    },
    onError: (error) => {
      toast.error(extractApiMessage(error, 'Failed to upload release'));
    },
  });

  const togglePublishedMutation = useMutation({
    mutationFn: ({ releaseId, isPublished }: { releaseId: string; isPublished: boolean }) => {
      if (!selectedPluginId) {
        throw new Error('No plugin selected');
      }
      return api.patch(`/admin/plugins/${selectedPluginId}/releases/${releaseId}`, { isPublished });
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['admin-plugin-releases', selectedPluginId] });
    },
    onError: (error) => {
      toast.error(extractApiMessage(error, 'Failed to update release'));
    },
  });

  const openReleaseDialogFrom = (release?: PluginRelease) => {
    setReleaseVersion('');
    setReleaseChannel('stable');
    setReleaseArtifactType('file');
    setReleaseArtifactUrl('');
    setReleaseDestination('');
    setReleaseFileName('');
    setReleaseChangelog('');
    setReleaseInstallSchemaJson('[]');
    setReleaseTemplatesJson('[]');
    setReleaseInstallSchemaFile(null);
    setReleaseTemplatesFile(null);
    setReleaseInstallSchemaFileInputKey((prev) => prev + 1);
    setReleaseTemplatesFileInputKey((prev) => prev + 1);
    setReleaseArtifactFiles([]);
    setReleaseInputMode(release ? 'url' : 'upload');

    if (release) {
      setReleaseChannel(release.channel);
      setReleaseArtifactType(release.artifactType);
      setReleaseArtifactUrl(release.artifactUrl);
      setReleaseDestination(release.destination ?? '');
      setReleaseFileName(release.fileName ?? '');
      setReleaseChangelog(release.changelog ?? '');
      setReleaseInstallSchemaJson(prettyJson(release.installSchema));
      setReleaseTemplatesJson(prettyJson(release.configTemplates));
    }
    setCreateReleaseOpen(true);
  };

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between gap-3">
        <div>
          <h1 className="text-2xl font-bold">Global Plugins</h1>
          <p className="text-sm text-muted-foreground">
            Oyun bazında global plugin tanımla, release yayınla, install ayar şemasını yönet.
          </p>
        </div>
        <Dialog open={createPluginOpen} onOpenChange={setCreatePluginOpen}>
          <DialogTrigger asChild>
            <Button>
              <Plus className="h-4 w-4" /> Add Global Plugin
            </Button>
          </DialogTrigger>
          <DialogContent>
            <DialogHeader>
              <DialogTitle>Create Global Plugin</DialogTitle>
            </DialogHeader>
            <form
              className="space-y-4"
              onSubmit={(event) => {
                event.preventDefault();
                if (!selectedGameId) {
                  toast.error('Select a game first');
                  return;
                }
                createPluginMutation.mutate({
                  gameId: selectedGameId,
                  name: createPluginName,
                  slug: createPluginSlug || undefined,
                  description: createPluginDescription || undefined,
                });
              }}
            >
              <div className="space-y-2">
                <Label>Game</Label>
                <Input
                  value={games.find((game) => game.id === selectedGameId)?.name ?? ''}
                  readOnly
                  placeholder="Select game from filter above"
                />
              </div>
              <div className="space-y-2">
                <Label>Name</Label>
                <Input value={createPluginName} onChange={(e) => setCreatePluginName(e.target.value)} required />
              </div>
              <div className="space-y-2">
                <Label>Slug (optional)</Label>
                <Input value={createPluginSlug} onChange={(e) => setCreatePluginSlug(e.target.value)} />
              </div>
              <div className="space-y-2">
                <Label>Description (optional)</Label>
                <Input value={createPluginDescription} onChange={(e) => setCreatePluginDescription(e.target.value)} />
              </div>
              <DialogFooter>
                <Button type="submit" disabled={createPluginMutation.isPending}>
                  {createPluginMutation.isPending ? 'Creating...' : 'Create'}
                </Button>
              </DialogFooter>
            </form>
          </DialogContent>
        </Dialog>
      </div>

      <Card>
        <CardContent className="pt-6">
          <div className="flex flex-wrap items-center gap-2">
            <Label className="min-w-20">Game Filter</Label>
            <select
              className="h-10 rounded-md border bg-background px-3 text-sm"
              value={selectedGameId}
              onChange={(e) => {
                setSelectedGameId(e.target.value);
                setSelectedPluginId(null);
              }}
            >
              <option value="">All Games</option>
              {games.map((game) => (
                <option key={game.id} value={game.id}>
                  {game.name} ({game.slug})
                </option>
              ))}
            </select>
          </div>
        </CardContent>
      </Card>

      <div className="grid gap-4 lg:grid-cols-[1.2fr_1fr]">
        <Card>
          <CardHeader>
            <CardTitle>Plugins</CardTitle>
          </CardHeader>
          <CardContent className="space-y-2">
            {plugins.length === 0 && (
              <p className="text-sm text-muted-foreground">No plugins found for this filter.</p>
            )}
            {plugins.map((plugin) => (
              <button
                key={plugin.id}
                type="button"
                onClick={() => setSelectedPluginId(plugin.id)}
                className={`w-full rounded-md border px-3 py-2 text-left transition ${
                  selectedPluginId === plugin.id ? 'border-primary bg-primary/5' : 'hover:bg-muted/40'
                }`}
              >
                <div className="flex items-center gap-2">
                  <Puzzle className="h-4 w-4 text-primary" />
                  <span className="font-medium">{plugin.name}</span>
                  <Badge variant="outline">{plugin.gameSlug}</Badge>
                  <Badge variant="secondary">{plugin.source}</Badge>
                </div>
                <p className="mt-1 text-xs text-muted-foreground">{plugin.slug}</p>
                {plugin.description && (
                  <p className="mt-1 text-sm text-muted-foreground">{plugin.description}</p>
                )}
              </button>
            ))}
          </CardContent>
        </Card>

        <Card>
          <CardHeader className="flex flex-row items-center justify-between">
            <CardTitle>Releases</CardTitle>
            <div className="flex gap-2">
              <Button
                size="sm"
                variant="outline"
                onClick={() => openReleaseDialogFrom(releases[0])}
                disabled={!selectedPlugin}
              >
                <Copy className="h-4 w-4" /> Clone Latest
              </Button>
              <Button
                size="sm"
                onClick={() => openReleaseDialogFrom()}
                disabled={!selectedPlugin}
              >
                <UploadCloud className="h-4 w-4" /> New Release
              </Button>
            </div>
          </CardHeader>
          <CardContent className="space-y-2">
            {!selectedPlugin && (
              <p className="text-sm text-muted-foreground">Select a plugin to manage releases.</p>
            )}
            {selectedPlugin && releases.length === 0 && (
              <p className="text-sm text-muted-foreground">No releases published yet.</p>
            )}
            {releases.map((release) => (
              <div key={release.id} className="rounded-md border px-3 py-2">
                <div className="flex flex-wrap items-center gap-2">
                  <span className="font-medium">v{release.version}</span>
                  <Badge variant="outline">{release.channel}</Badge>
                  <Badge variant="secondary">{release.artifactType}</Badge>
                  {!release.isPublished && <Badge variant="destructive">Unpublished</Badge>}
                </div>
                <p className="mt-1 line-clamp-1 text-xs text-muted-foreground">{release.artifactUrl}</p>
                <p className="mt-1 text-xs text-muted-foreground">
                  Schema: {Array.isArray(release.installSchema) ? release.installSchema.length : 0} fields • Templates:{' '}
                  {Array.isArray(release.configTemplates) ? release.configTemplates.length : 0}
                </p>
                <div className="mt-2">
                  <Button
                    size="sm"
                    variant="outline"
                    onClick={() =>
                      togglePublishedMutation.mutate({
                        releaseId: release.id,
                        isPublished: !release.isPublished,
                      })
                    }
                    disabled={togglePublishedMutation.isPending}
                  >
                    <Rocket className="h-4 w-4" />
                    {release.isPublished ? 'Unpublish' : 'Publish'}
                  </Button>
                </div>
              </div>
            ))}
          </CardContent>
        </Card>
      </div>

      <Dialog
        open={createReleaseOpen}
        onOpenChange={(open) => {
          if (open) {
            setCreateReleaseOpen(true);
            return;
          }
          resetReleaseForm();
        }}
      >
        <DialogContent className="max-w-3xl">
          <DialogHeader>
            <DialogTitle>Publish Release{selectedPlugin ? ` - ${selectedPlugin.name}` : ''}</DialogTitle>
          </DialogHeader>
          <form
            className="space-y-4"
            onSubmit={async (event) => {
              event.preventDefault();
              try {
                const installSchema = releaseInstallSchemaFile
                  ? await parseJsonArrayFile(releaseInstallSchemaFile, 'Install schema file')
                  : parseJsonArray(releaseInstallSchemaJson);
                const configTemplates = releaseTemplatesFile
                  ? await parseJsonArrayFile(releaseTemplatesFile, 'Config templates file')
                  : parseJsonArray(releaseTemplatesJson);

                if (releaseInputMode === 'upload') {
                  if (releaseArtifactFiles.length === 0) {
                    toast.error('Select at least one file or folder');
                    return;
                  }

                  const formData = new FormData();
                  formData.append('version', releaseVersion);
                  formData.append('channel', releaseChannel);
                  if (releaseDestination.trim()) formData.append('destination', releaseDestination.trim());
                  if (releaseFileName.trim()) formData.append('fileName', releaseFileName.trim());
                  if (releaseChangelog.trim()) formData.append('changelog', releaseChangelog);
                  if (releaseInstallSchemaFile) {
                    formData.append(
                      'installSchemaFile',
                      releaseInstallSchemaFile,
                      releaseInstallSchemaFile.name,
                    );
                  } else {
                    formData.append('installSchema', JSON.stringify(installSchema));
                  }
                  if (releaseTemplatesFile) {
                    formData.append(
                      'configTemplatesFile',
                      releaseTemplatesFile,
                      releaseTemplatesFile.name,
                    );
                  } else {
                    formData.append('configTemplates', JSON.stringify(configTemplates));
                  }

                  for (const file of releaseArtifactFiles) {
                    const relativePath = (file as File & { webkitRelativePath?: string }).webkitRelativePath;
                    formData.append('relativePath', relativePath && relativePath.length > 0 ? relativePath : file.name);
                    formData.append('files', file, file.name);
                  }

                  createUploadReleaseMutation.mutate(formData);
                  return;
                }

                createReleaseMutation.mutate({
                  version: releaseVersion,
                  channel: releaseChannel,
                  artifactType: releaseArtifactType,
                  artifactUrl: releaseArtifactUrl,
                  destination: releaseDestination || undefined,
                  fileName: releaseFileName || undefined,
                  changelog: releaseChangelog || undefined,
                  installSchema,
                  configTemplates,
                });
              } catch (error) {
                const message = error instanceof Error ? error.message : 'Invalid JSON';
                toast.error(`Release JSON error: ${message}`);
              }
            }}
          >
            <div className="grid gap-3 sm:grid-cols-2">
              <div className="space-y-2">
                <Label>Version</Label>
                <Input value={releaseVersion} onChange={(e) => setReleaseVersion(e.target.value)} required />
              </div>
              <div className="space-y-2">
                <Label>Channel</Label>
                <select
                  className="h-10 w-full rounded-md border bg-background px-3 text-sm"
                  value={releaseChannel}
                  onChange={(e) => setReleaseChannel(e.target.value as 'stable' | 'beta' | 'alpha')}
                >
                  <option value="stable">stable</option>
                  <option value="beta">beta</option>
                  <option value="alpha">alpha</option>
                </select>
              </div>
            </div>

            <div className="space-y-2">
              <Label>Release Source</Label>
              <div className="flex flex-wrap gap-2">
                <Button
                  type="button"
                  size="sm"
                  variant={releaseInputMode === 'upload' ? 'default' : 'outline'}
                  onClick={() => setReleaseInputMode('upload')}
                >
                  CDN Upload
                </Button>
                <Button
                  type="button"
                  size="sm"
                  variant={releaseInputMode === 'url' ? 'default' : 'outline'}
                  onClick={() => setReleaseInputMode('url')}
                >
                  URL
                </Button>
              </div>
            </div>

            {releaseInputMode === 'url' && (
              <div className="grid gap-3 sm:grid-cols-2">
                <div className="space-y-2">
                  <Label>Artifact Type</Label>
                  <select
                    className="h-10 w-full rounded-md border bg-background px-3 text-sm"
                    value={releaseArtifactType}
                    onChange={(e) => setReleaseArtifactType(e.target.value as 'file' | 'zip')}
                  >
                    <option value="file">file</option>
                    <option value="zip">zip</option>
                  </select>
                </div>
                <div className="space-y-2">
                  <Label>Artifact URL</Label>
                  <Input
                    type="url"
                    value={releaseArtifactUrl}
                    onChange={(e) => setReleaseArtifactUrl(e.target.value)}
                    required={releaseInputMode === 'url'}
                  />
                </div>
              </div>
            )}

            {releaseInputMode === 'upload' && (
              <div className="space-y-3 rounded-md border p-3">
                <p className="text-xs text-muted-foreground">
                  Tek dosya secersen tekil upload olur. Birden fazla dosya veya klasor secersen otomatik zip
                  yapilip CDN&apos;e yuklenir.
                </p>
                <div className="grid gap-3 sm:grid-cols-2">
                  <div className="space-y-2">
                    <Label>Files</Label>
                    <input
                      type="file"
                      multiple
                      className="block w-full text-sm"
                      onChange={(e) => appendReleaseFiles(e.target.files)}
                    />
                  </div>
                  <div className="space-y-2">
                    <Label>Folder</Label>
                    <input
                      type="file"
                      multiple
                      {...({ webkitdirectory: '', directory: '' } as Record<string, string>)}
                      className="block w-full text-sm"
                      onChange={(e) => appendReleaseFiles(e.target.files)}
                    />
                  </div>
                </div>
                <div className="flex items-center justify-between">
                  <p className="text-xs text-muted-foreground">Selected: {releaseArtifactFiles.length} file(s)</p>
                  {releaseArtifactFiles.length > 0 && (
                    <Button type="button" variant="ghost" size="sm" onClick={() => setReleaseArtifactFiles([])}>
                      Clear
                    </Button>
                  )}
                </div>
                {releaseArtifactFiles.length > 0 && (
                  <div className="max-h-28 space-y-1 overflow-auto rounded bg-muted/40 p-2 text-xs">
                    {releaseArtifactFiles.map((file, index) => {
                      const relativePath = (file as File & { webkitRelativePath?: string }).webkitRelativePath;
                      return (
                        <p key={`${relativePath || file.name}-${index}`} className="truncate">
                          {relativePath || file.name}
                        </p>
                      );
                    })}
                  </div>
                )}
              </div>
            )}

            <div className="grid gap-3 sm:grid-cols-2">
              <div className="space-y-2">
                <Label>Destination (optional)</Label>
                <Input
                  value={releaseDestination}
                  onChange={(e) => setReleaseDestination(e.target.value)}
                  placeholder="/game/csgo/addons"
                />
              </div>
              <div className="space-y-2">
                <Label>File Name (optional)</Label>
                <Input
                  value={releaseFileName}
                  onChange={(e) => setReleaseFileName(e.target.value)}
                  placeholder="plugin.dll"
                />
              </div>
            </div>

            <div className="space-y-2">
              <Label>Changelog (optional)</Label>
              <textarea
                value={releaseChangelog}
                onChange={(e) => setReleaseChangelog(e.target.value)}
                className="min-h-[90px] w-full rounded-md border bg-background px-3 py-2 text-sm"
              />
            </div>

            <div className="grid gap-3 sm:grid-cols-2">
              <div className="space-y-2">
                <Label>Install Schema JSON (array)</Label>
                <input
                  key={releaseInstallSchemaFileInputKey}
                  type="file"
                  accept="application/json,.json"
                  className="block w-full text-xs"
                  onChange={(e) => setReleaseInstallSchemaFile(e.target.files?.[0] ?? null)}
                />
                {releaseInstallSchemaFile && (
                  <div className="flex items-center justify-between gap-2 text-xs text-muted-foreground">
                    <p>File secili: {releaseInstallSchemaFile.name}. Bu dosya, alttaki metni override eder.</p>
                    <Button
                      type="button"
                      variant="ghost"
                      size="sm"
                      onClick={() => {
                        setReleaseInstallSchemaFile(null);
                        setReleaseInstallSchemaFileInputKey((prev) => prev + 1);
                      }}
                    >
                      Clear
                    </Button>
                  </div>
                )}
                <textarea
                  value={releaseInstallSchemaJson}
                  onChange={(e) => setReleaseInstallSchemaJson(e.target.value)}
                  className="min-h-[180px] w-full rounded-md border bg-background px-3 py-2 font-mono text-xs"
                />
              </div>
              <div className="space-y-2">
                <Label>Config Templates JSON (array)</Label>
                <input
                  key={releaseTemplatesFileInputKey}
                  type="file"
                  accept="application/json,.json"
                  className="block w-full text-xs"
                  onChange={(e) => setReleaseTemplatesFile(e.target.files?.[0] ?? null)}
                />
                {releaseTemplatesFile && (
                  <div className="flex items-center justify-between gap-2 text-xs text-muted-foreground">
                    <p>File secili: {releaseTemplatesFile.name}. Bu dosya, alttaki metni override eder.</p>
                    <Button
                      type="button"
                      variant="ghost"
                      size="sm"
                      onClick={() => {
                        setReleaseTemplatesFile(null);
                        setReleaseTemplatesFileInputKey((prev) => prev + 1);
                      }}
                    >
                      Clear
                    </Button>
                  </div>
                )}
                <textarea
                  value={releaseTemplatesJson}
                  onChange={(e) => setReleaseTemplatesJson(e.target.value)}
                  className="min-h-[180px] w-full rounded-md border bg-background px-3 py-2 font-mono text-xs"
                />
              </div>
            </div>

            <DialogFooter>
              <Button
                type="submit"
                disabled={
                  createReleaseMutation.isPending ||
                  createUploadReleaseMutation.isPending ||
                  !selectedPlugin
                }
              >
                {(createReleaseMutation.isPending || createUploadReleaseMutation.isPending)
                  ? 'Publishing...'
                  : 'Publish Release'}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>
    </div>
  );
}
