import React, { useState, useEffect } from 'react';
import {
  Paper,
  Stack,
  Text,
  Divider,
  Box,
  ScrollArea,
} from '@mantine/core';
import { 
  FormSidebar, 
  FormField 
} from '@skybridge/web-components';
import Editor from '@monaco-editor/react';
import { functionApi, runtimeApi } from '../services/apiService';
import { FunctionDefinition, CreateFunctionRequest, UpdateFunctionRequest, RuntimeType } from '../types';

interface FunctionSidebarProps {
  opened: boolean;
  onClose: () => void;
  onSuccess: () => void;
  editFunction?: FunctionDefinition;
}

export const FunctionSidebar: React.FC<FunctionSidebarProps> = ({
  opened,
  onClose,
  onSuccess,
  editFunction,
}) => {
  const [runtimeOptions, setRuntimeOptions] = useState<Array<{value: string; label: string}>>([]);
  const [codeContent, setCodeContent] = useState('');

  // Default images for each runtime
  const DEFAULT_IMAGES: Record<string, string> = {
    'nodejs18': 'node:18-alpine',
    'python3.9': 'python:3.9-alpine',
    'go1.20': 'golang:1.20-alpine',
  };

  // Map runtime to Monaco editor language
  const getEditorLanguage = (runtime: string): string => {
    const languageMap: Record<string, string> = {
      'nodejs18': 'javascript',
      'python3.9': 'python',
      'go1.20': 'go',
    };
    return languageMap[runtime] || 'javascript';
  };

  // Get default code template based on runtime
  const getDefaultCode = (runtime: string): string => {
    const templates: Record<string, string> = {
      'nodejs18': `exports.handler = async (event, context) => {
  console.log('Event:', JSON.stringify(event, null, 2));
  
  return {
    statusCode: 200,
    body: JSON.stringify({
      message: 'Hello from Node.js!',
      timestamp: new Date().toISOString()
    })
  };
};`,
      'python3.9': `import json
from datetime import datetime

def handler(event, context):
    print('Event:', json.dumps(event, indent=2))
    
    return {
        'statusCode': 200,
        'body': json.dumps({
            'message': 'Hello from Python!',
            'timestamp': datetime.now().isoformat()
        })
    }`,
      'go1.20': `package main

import (
    "context"
    "encoding/json"
    "fmt"
    "time"
)

type Event map[string]interface{}

func Handler(ctx context.Context, event Event) (map[string]interface{}, error) {
    fmt.Printf("Event: %+v\\n", event)
    
    return map[string]interface{}{
        "statusCode": 200,
        "body": map[string]interface{}{
            "message": "Hello from Go!",
            "timestamp": time.Now().Format(time.RFC3339),
        },
    }, nil
}`
    };
    return templates[runtime] || templates['nodejs18'];
  };

  useEffect(() => {
    loadRuntimeOptions();
    if (editFunction) {
      setCodeContent(editFunction.code || '');
    }
  }, [editFunction]);

  const loadRuntimeOptions = async () => {
    try {
      const runtimes = await runtimeApi.listRuntimes();
      const options = runtimes.map((runtime: RuntimeType) => ({
        value: runtime.name,
        label: `${runtime.name} (${runtime.version})`
      }));
      setRuntimeOptions(options);
    } catch (error) {
      console.error('Failed to load runtimes:', error);
      // Fallback options
      setRuntimeOptions([
        { value: 'nodejs18', label: 'Node.js 18' },
        { value: 'python3.9', label: 'Python 3.9' },
        { value: 'go1.20', label: 'Go 1.20' }
      ]);
    }
  };

  const fields: FormField[] = [
    {
      name: 'name',
      label: 'Function Name',
      type: 'text',
      required: true,
      placeholder: 'my-function',
      validation: { pattern: /^[a-z0-9-]+$/ },
    },
    {
      name: 'description',
      label: 'Description',
      type: 'textarea',
      required: false,
      placeholder: 'Function description...',
    },
    {
      name: 'runtime',
      label: 'Runtime',
      type: 'select',
      required: true,
      options: runtimeOptions,
      defaultValue: 'nodejs18',
    },
    {
      name: 'timeout',
      label: 'Timeout (seconds)',
      type: 'number',
      required: true,
      defaultValue: 30,
    },
    {
      name: 'memory',
      label: 'Memory (MB)',
      type: 'number', 
      required: true,
      defaultValue: 128,
    },
    {
      name: 'environment_variables',
      label: 'Environment Variables',
      type: 'json',
      required: false,
      defaultValue: '{}',
    },
  ];

  const handleSubmit = async (values: any) => {
    const submitData = {
      ...values,
      code: codeContent,
      docker_image: DEFAULT_IMAGES[values.runtime] || DEFAULT_IMAGES['nodejs18'],
    };

    if (editFunction) {
      const updateRequest: UpdateFunctionRequest = {
        description: submitData.description,
        code: submitData.code,
        timeout: submitData.timeout,
        memory: submitData.memory,
        environment_variables: submitData.environment_variables,
        docker_image: submitData.docker_image,
      };
      await functionApi.updateFunction(editFunction.id, updateRequest);
    } else {
      const createRequest: CreateFunctionRequest = submitData;
      await functionApi.createFunction(createRequest);
    }
  };

  // Create a custom sidebar that includes the Monaco editor
  return (
    <Paper
      style={{
        position: 'fixed',
        top: 60,
        right: opened ? 0 : '-600px',
        bottom: 0,
        width: '600px',
        zIndex: 1000,
        borderRadius: 0,
        display: 'flex',
        flexDirection: 'column',
        borderLeft: '1px solid var(--mantine-color-gray-3)',
        backgroundColor: 'var(--mantine-color-body)',
        transition: 'right 0.3s ease',
      }}
    >
      <ScrollArea style={{ flex: 1 }}>
        <Stack gap="md" p="md">
          <FormSidebar
            opened={true} // Always open since we're embedding it
            onClose={() => {}} // Handled by parent
            onSuccess={onSuccess}
            title="Function"
            editMode={!!editFunction}
            editItem={editFunction}
            fields={fields}
            onSubmit={handleSubmit}
            width={600}
            style={{ position: 'relative', right: 'auto', top: 'auto', bottom: 'auto' }}
          />
          
          <Divider />
          
          <Box>
            <Text fw={500} mb="sm">Code Editor</Text>
            <Box h={300} style={{ border: '1px solid var(--mantine-color-gray-3)' }}>
              <Editor
                height="300px"
                language={getEditorLanguage(editFunction?.runtime || 'nodejs18')}
                value={codeContent}
                onChange={(value) => setCodeContent(value || '')}
                theme="vs-dark"
                options={{
                  minimap: { enabled: false },
                  scrollBeyondLastLine: false,
                  fontSize: 14,
                }}
              />
            </Box>
          </Box>
        </Stack>
      </ScrollArea>
    </Paper>
  );
};