import { useState } from 'react';
import { useParams } from 'react-router';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import {
  Folder,
  FileText,
  ArrowUp,
  Trash2,
  Plus,
  Download,
  Upload,
  Save,
  X,
} from 'lucide-react';
import { api } from '@/lib/api';
import { formatBytes } from '@/lib/utils';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogClose,
} from '@/components/ui/dialog';

interface FileEntry {
  name: string;
  path: string;
  isDirectory: boolean;
  size: number;
  modifiedAt: number;
}

export function FilesPage() {
  const { orgId, serverId } = useParams();
  const queryClient = useQueryClient();
  const [currentPath, setCurrentPath] = useState('/');
  const [editingFile, setEditingFile] = useState<{ path: string; content: string } | null>(null);
  const [newFileName, setNewFileName] = useState('');
  const [showNewFile, setShowNewFile] = useState(false);
  const [deleteTarget, setDeleteTarget] = useState<string | null>(null);

  const filesQuery = useQuery({
    queryKey: ['files', orgId, serverId, currentPath],
    queryFn: () =>
      api.get<{ files: FileEntry[] }>(
        `/organizations/${orgId}/servers/${serverId}/files`,
        { path: currentPath },
      ),
    enabled: !editingFile,
  });

  const deleteMutation = useMutation({
    mutationFn: (paths: string[]) =>
      api.post(`/organizations/${orgId}/servers/${serverId}/files/delete`, { paths }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['files', orgId, serverId, currentPath] });
      setDeleteTarget(null);
    },
  });

  const saveMutation = useMutation({
    mutationFn: ({ path, data }: { path: string; data: string }) =>
      api.post(`/organizations/${orgId}/servers/${serverId}/files/write`, { path, data }),
    onSuccess: () => {
      setEditingFile(null);
      queryClient.invalidateQueries({ queryKey: ['files', orgId, serverId, currentPath] });
    },
  });

  const createFileMutation = useMutation({
    mutationFn: ({ path, data }: { path: string; data: string }) =>
      api.post(`/organizations/${orgId}/servers/${serverId}/files/write`, { path, data }),
    onSuccess: () => {
      setShowNewFile(false);
      setNewFileName('');
      queryClient.invalidateQueries({ queryKey: ['files', orgId, serverId, currentPath] });
    },
  });

  const openFile = async (file: FileEntry) => {
    if (file.isDirectory) {
      setCurrentPath(file.path);
      return;
    }
    const res = await api.get<{ data: string }>(
      `/organizations/${orgId}/servers/${serverId}/files/read`,
      { path: file.path },
    );
    setEditingFile({ path: file.path, content: res.data });
  };

  const goUp = () => {
    if (currentPath === '/') return;
    const parts = currentPath.split('/').filter(Boolean);
    parts.pop();
    setCurrentPath('/' + parts.join('/'));
  };

  const breadcrumbs = currentPath.split('/').filter(Boolean);

  const files = filesQuery.data?.files ?? [];

  return (
    <div className="space-y-4">
      {editingFile ? (
        <Card>
          <CardHeader className="flex flex-row items-center justify-between">
            <CardTitle className="text-sm font-mono">{editingFile.path}</CardTitle>
            <div className="flex gap-2">
              <Button
                size="sm"
                onClick={() =>
                  saveMutation.mutate({ path: editingFile.path, data: editingFile.content })
                }
                disabled={saveMutation.isPending}
              >
                <Save className="h-4 w-4" />
                Save
              </Button>
              <Button size="sm" variant="outline" onClick={() => setEditingFile(null)}>
                <X className="h-4 w-4" />
                Close
              </Button>
            </div>
          </CardHeader>
          <CardContent>
            <textarea
              value={editingFile.content}
              onChange={(e) => setEditingFile({ ...editingFile, content: e.target.value })}
              className="min-h-[500px] w-full rounded-md border bg-background p-3 font-mono text-sm focus:outline-none focus:ring-1 focus:ring-ring"
              spellCheck={false}
            />
          </CardContent>
        </Card>
      ) : (
        <>
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-2 text-sm">
              <Button variant="ghost" size="icon" onClick={goUp} disabled={currentPath === '/'}>
                <ArrowUp className="h-4 w-4" />
              </Button>
              <span className="text-muted-foreground">/</span>
              {breadcrumbs.map((crumb, i) => (
                <span key={i} className="flex items-center gap-1">
                  <button
                    className="text-muted-foreground hover:text-foreground"
                    onClick={() =>
                      setCurrentPath('/' + breadcrumbs.slice(0, i + 1).join('/'))
                    }
                  >
                    {crumb}
                  </button>
                  {i < breadcrumbs.length - 1 && (
                    <span className="text-muted-foreground">/</span>
                  )}
                </span>
              ))}
            </div>
            <Button size="sm" variant="outline" onClick={() => setShowNewFile(true)}>
              <Plus className="h-4 w-4" />
              New File
            </Button>
          </div>

          {showNewFile && (
            <div className="flex gap-2">
              <Input
                placeholder="filename.txt"
                value={newFileName}
                onChange={(e) => setNewFileName(e.target.value)}
                onKeyDown={(e) => {
                  if (e.key === 'Enter' && newFileName) {
                    const path =
                      currentPath === '/' ? `/${newFileName}` : `${currentPath}/${newFileName}`;
                    createFileMutation.mutate({ path, data: '' });
                  }
                }}
              />
              <Button
                size="sm"
                onClick={() => {
                  if (!newFileName) return;
                  const path =
                    currentPath === '/' ? `/${newFileName}` : `${currentPath}/${newFileName}`;
                  createFileMutation.mutate({ path, data: '' });
                }}
              >
                Create
              </Button>
              <Button
                size="sm"
                variant="ghost"
                onClick={() => {
                  setShowNewFile(false);
                  setNewFileName('');
                }}
              >
                Cancel
              </Button>
            </div>
          )}

          <Card>
            <CardContent className="p-0">
              <div className="divide-y">
                {files.length === 0 && (
                  <div className="flex items-center justify-center py-12 text-muted-foreground">
                    This directory is empty
                  </div>
                )}
                {files.map((file) => (
                  <div
                    key={file.path}
                    className="flex cursor-pointer items-center justify-between px-4 py-2.5 hover:bg-muted/50"
                    onClick={() => openFile(file)}
                  >
                    <div className="flex items-center gap-3">
                      {file.isDirectory ? (
                        <Folder className="h-4 w-4 text-blue-400" />
                      ) : (
                        <FileText className="h-4 w-4 text-muted-foreground" />
                      )}
                      <span className="text-sm">{file.name}</span>
                    </div>
                    <div className="flex items-center gap-4">
                      {!file.isDirectory && (
                        <span className="text-xs text-muted-foreground">
                          {formatBytes(file.size)}
                        </span>
                      )}
                      <Button
                        size="icon"
                        variant="ghost"
                        className="h-7 w-7"
                        onClick={(e) => {
                          e.stopPropagation();
                          setDeleteTarget(file.path);
                        }}
                      >
                        <Trash2 className="h-3.5 w-3.5 text-muted-foreground" />
                      </Button>
                    </div>
                  </div>
                ))}
              </div>
            </CardContent>
          </Card>

          <Dialog open={!!deleteTarget} onOpenChange={() => setDeleteTarget(null)}>
            <DialogContent>
              <DialogHeader>
                <DialogTitle>Delete File</DialogTitle>
              </DialogHeader>
              <p className="text-sm text-muted-foreground">
                Are you sure you want to delete <code className="font-mono">{deleteTarget}</code>?
              </p>
              <DialogFooter>
                <DialogClose asChild>
                  <Button variant="outline">Cancel</Button>
                </DialogClose>
                <Button
                  variant="destructive"
                  onClick={() => deleteTarget && deleteMutation.mutate([deleteTarget])}
                  disabled={deleteMutation.isPending}
                >
                  Delete
                </Button>
              </DialogFooter>
            </DialogContent>
          </Dialog>
        </>
      )}
    </div>
  );
}
