'use client';

import React, { useState, useEffect } from 'react';
import { EdgeFunction } from '@/lib/vfs/types';
import {
  Plus, Loader2, AlertCircle, Code2, MoreVertical, Pencil, Trash2,
  ToggleLeft, ToggleRight, Copy, ExternalLink, CheckCircle2
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { FunctionEditor } from './function-editor';
import { cn } from '@/lib/utils';
import type { FunctionsDataProvider } from './data-providers';

interface FunctionsManagerProps {
  deploymentId?: string;
  dataProvider?: FunctionsDataProvider;
  hideRuntimeFeatures?: boolean;
  workspaceId?: string;
}

export function FunctionsManager({ deploymentId, dataProvider, hideRuntimeFeatures, workspaceId }: FunctionsManagerProps) {
  const apiBase = workspaceId ? `/api/w/${workspaceId}` : '/api';
  const [functions, setFunctions] = useState<EdgeFunction[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [editingFunction, setEditingFunction] = useState<EdgeFunction | null>(null);
  const [isCreating, setIsCreating] = useState(false);
  const [copiedUrl, setCopiedUrl] = useState<string | null>(null);

  useEffect(() => {
    loadFunctions();
  }, [deploymentId, dataProvider]);

  const loadFunctions = async () => {
    try {
      setLoading(true);
      setError(null);
      if (dataProvider) {
        setFunctions(await dataProvider.list());
      } else if (deploymentId) {
        const res = await fetch(`${apiBase}/admin/deployments/${deploymentId}/functions`);
        if (!res.ok) {
          const data = await res.json();
          throw new Error(data.error || 'Failed to load functions');
        }
        const data = await res.json();
        setFunctions(data.functions);
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load functions');
    } finally {
      setLoading(false);
    }
  };

  const toggleEnabled = async (fn: EdgeFunction) => {
    try {
      if (dataProvider) {
        await dataProvider.toggle(fn.id, !fn.enabled);
      } else if (deploymentId) {
        const res = await fetch(`${apiBase}/admin/deployments/${deploymentId}/functions/${fn.id}`, {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ enabled: !fn.enabled }),
        });
        if (!res.ok) throw new Error('Failed to update function');
      } else {
        return;
      }
      await loadFunctions();
    } catch (err) {
      console.error('Failed to toggle function:', err);
    }
  };

  const deleteFunction = async (fn: EdgeFunction) => {
    if (!confirm(`Delete function "${fn.name}"? This cannot be undone.`)) return;

    try {
      if (dataProvider) {
        await dataProvider.remove(fn.id);
      } else if (deploymentId) {
        const res = await fetch(`${apiBase}/admin/deployments/${deploymentId}/functions/${fn.id}`, {
          method: 'DELETE',
        });
        if (!res.ok) throw new Error('Failed to delete function');
      } else {
        return;
      }
      await loadFunctions();
    } catch (err) {
      console.error('Failed to delete function:', err);
    }
  };

  const copyUrl = (fn: EdgeFunction) => {
    if (!deploymentId) return;
    const url = `${window.location.origin}${apiBase}/deployments/${deploymentId}/functions/${fn.name}`;
    navigator.clipboard.writeText(url);
    setCopiedUrl(fn.id);
    setTimeout(() => setCopiedUrl(null), 2000);
  };

  const handleSave = async (data: Partial<EdgeFunction>) => {
    try {
      if (dataProvider) {
        await dataProvider.save(editingFunction?.id || null, data);
      } else if (!deploymentId) {
        throw new Error('No deployment ID available');
      } else if (editingFunction) {
        const res = await fetch(`${apiBase}/admin/deployments/${deploymentId}/functions/${editingFunction.id}`, {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(data),
        });
        if (!res.ok) {
          const err = await res.json();
          throw new Error(err.error || 'Failed to update function');
        }
      } else {
        const res = await fetch(`${apiBase}/admin/deployments/${deploymentId}/functions`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(data),
        });
        if (!res.ok) {
          const err = await res.json();
          throw new Error(err.error || 'Failed to create function');
        }
      }

      setEditingFunction(null);
      setIsCreating(false);
      await loadFunctions();
    } catch (err) {
      throw err;
    }
  };

  if (loading) {
    return (
      <div className="flex items-center justify-center h-full">
        <Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
      </div>
    );
  }

  if (error) {
    return (
      <div className="flex flex-col items-center justify-center h-full gap-4">
        <AlertCircle className="h-8 w-8 text-destructive" />
        <p className="text-sm text-muted-foreground">{error}</p>
        <Button variant="outline" onClick={loadFunctions}>
          Retry
        </Button>
      </div>
    );
  }

  return (
    <div className="h-full flex flex-col">
      <div className="flex items-center justify-between mb-4">
        <h3 className="text-sm font-medium">Edge Functions</h3>
        <Button size="sm" onClick={() => setIsCreating(true)}>
          <Plus className="h-4 w-4 mr-1" />
          New Function
        </Button>
      </div>

      <div className="flex-1 overflow-auto">
        {functions.length === 0 ? (
          <div className="flex flex-col items-center justify-center h-full p-8 text-center border rounded-lg">
            <Code2 className="h-8 w-8 text-muted-foreground mb-2" />
            <p className="text-sm text-muted-foreground">No edge functions yet</p>
            <p className="text-xs text-muted-foreground mt-1 mb-4">
              Create your first API endpoint
            </p>
            <Button size="sm" onClick={() => setIsCreating(true)}>
              <Plus className="h-4 w-4 mr-1" />
              Create Function
            </Button>
          </div>
        ) : (
          <div className="grid gap-3">
            {functions.map(fn => (
              <div
                key={fn.id}
                className={cn(
                  "border rounded-lg p-4 transition-colors",
                  !fn.enabled && "opacity-60 bg-muted/30"
                )}
              >
                <div className="flex items-start justify-between gap-2">
                  <div className="flex-1 min-w-0 overflow-hidden">
                    <div className="flex items-center gap-2 flex-wrap">
                      <Code2 className="h-4 w-4 text-blue-500 shrink-0" />
                      <span className="font-mono font-medium truncate">{fn.name}</span>
                      <span className={cn(
                        "text-xs px-1.5 py-0.5 rounded shrink-0",
                        fn.method === 'ANY' ? "bg-purple-500/20 text-purple-600" :
                        fn.method === 'GET' ? "bg-green-500/20 text-green-600" :
                        fn.method === 'POST' ? "bg-blue-500/20 text-blue-600" :
                        fn.method === 'PUT' ? "bg-yellow-500/20 text-yellow-600" :
                        "bg-red-500/20 text-red-600"
                      )}>
                        {fn.method}
                      </span>
                      {!fn.enabled && (
                        <span className="text-xs bg-muted px-1.5 py-0.5 rounded shrink-0">disabled</span>
                      )}
                    </div>
                    {fn.description && (
                      <p className="text-sm text-muted-foreground mt-1 truncate">
                        {fn.description}
                      </p>
                    )}
                    <div className="flex items-center gap-4 mt-2 text-xs text-muted-foreground">
                      <span className="shrink-0">Timeout: {fn.timeoutMs / 1000}s</span>
                      {!hideRuntimeFeatures && deploymentId && (
                        <button
                          onClick={() => copyUrl(fn)}
                          className="flex items-center gap-1 hover:text-foreground transition-colors shrink-0"
                        >
                          {copiedUrl === fn.id ? (
                            <>
                              <CheckCircle2 className="h-3 w-3 text-green-500" />
                              Copied!
                            </>
                          ) : (
                            <>
                              <Copy className="h-3 w-3" />
                              Copy URL
                            </>
                          )}
                        </button>
                      )}
                    </div>
                  </div>

                  <DropdownMenu>
                    <DropdownMenuTrigger asChild>
                      <Button variant="ghost" size="sm">
                        <MoreVertical className="h-4 w-4" />
                      </Button>
                    </DropdownMenuTrigger>
                    <DropdownMenuContent align="end">
                      <DropdownMenuItem onClick={() => setEditingFunction(fn)}>
                        <Pencil className="h-4 w-4 mr-2" />
                        Edit
                      </DropdownMenuItem>
                      <DropdownMenuItem onClick={() => toggleEnabled(fn)}>
                        {fn.enabled ? (
                          <>
                            <ToggleLeft className="h-4 w-4 mr-2" />
                            Disable
                          </>
                        ) : (
                          <>
                            <ToggleRight className="h-4 w-4 mr-2" />
                            Enable
                          </>
                        )}
                      </DropdownMenuItem>
                      {!hideRuntimeFeatures && deploymentId && (
                        <DropdownMenuItem
                          onClick={() => window.open(`${apiBase}/deployments/${deploymentId}/functions/${fn.name}`, '_blank')}
                        >
                          <ExternalLink className="h-4 w-4 mr-2" />
                          Open in Browser
                        </DropdownMenuItem>
                      )}
                      <DropdownMenuItem
                        onClick={() => deleteFunction(fn)}
                        className="text-destructive"
                      >
                        <Trash2 className="h-4 w-4 mr-2" />
                        Delete
                      </DropdownMenuItem>
                    </DropdownMenuContent>
                  </DropdownMenu>
                </div>
              </div>
            ))}
          </div>
        )}
      </div>

      {/* Function Editor Dialog */}
      {(isCreating || editingFunction) && (
        <FunctionEditor
          deploymentId={deploymentId || ''}
          function={editingFunction}
          isOpen={true}
          onClose={() => {
            setIsCreating(false);
            setEditingFunction(null);
          }}
          onSave={handleSave}
        />
      )}
    </div>
  );
}
