<template>
  <div class="html-node-config">
    <div class="config-content">
      <!-- Header -->
      <div class="config-header">
        <h3 class="text-lg font-semibold text-gray-800">HTML Node Configuration</h3>
        <p class="text-sm text-gray-600">Configure custom HTML content for your process</p>
      </div>

      <!-- Basic Info Section -->
      <div class="config-section">
        <h4 class="section-title">Basic Information</h4>
        <div class="section-content">
          <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
            <FormKit
              type="text"
              label="HTML Node Name"
              name="label"
              v-model="localNodeData.label"
              help="Display name for this HTML node"
              :classes="{ outer: 'field-wrapper' }"
              placeholder="e.g., Custom Form, Information Display"
              validation="required"
            />
            
            <FormKit
              type="textarea"
              label="Description"
              name="description"
              v-model="localNodeData.description"
              help="Describe what this HTML content does"
              :classes="{ outer: 'field-wrapper' }"
              placeholder="e.g., Displays a custom form for user input"
              rows="2"
            />
          </div>
        </div>
      </div>

      <!-- HTML Content Section -->
      <div class="config-section">
        <h4 class="section-title">HTML Content</h4>
        <div class="section-content">
          <!-- Code Editor Tabs -->
          <div class="code-editor-tabs">
            <div class="tabs-header border-b border-gray-200">
              <div class="flex">
                <button 
                  @click="activeTab = 'html'" 
                  class="px-4 py-2 text-sm font-medium" 
                  :class="activeTab === 'html' ? 'text-blue-600 border-b-2 border-blue-500' : 'text-gray-600 hover:text-gray-800'"
                >
                  <span class="flex items-center">
                    <Icon name="material-symbols:code" class="w-4 h-4 mr-2" />
                    HTML
                  </span>
                </button>
                <button 
                  @click="activeTab = 'css'" 
                  class="px-4 py-2 text-sm font-medium" 
                  :class="activeTab === 'css' ? 'text-blue-600 border-b-2 border-blue-500' : 'text-gray-600 hover:text-gray-800'"
                >
                  <span class="flex items-center">
                    <Icon name="material-symbols:format-color-fill" class="w-4 h-4 mr-2" />
                    CSS
                  </span>
                </button>
                <button 
                  @click="activeTab = 'js'" 
                  class="px-4 py-2 text-sm font-medium" 
                  :class="activeTab === 'js' ? 'text-blue-600 border-b-2 border-blue-500' : 'text-gray-600 hover:text-gray-800'"
                >
                  <span class="flex items-center">
                    <Icon name="material-symbols:code-blocks" class="w-4 h-4 mr-2" />
                    JavaScript
                  </span>
                </button>
              </div>
            </div>
            
            <!-- HTML Tab -->
            <div v-show="activeTab === 'html'" class="tab-content py-4">
              <div class="html-editor-container">
                <RsCodeMirror
                  v-model="localNodeData.htmlCode"
                  :options="{
                    mode: 'htmlmixed',
                    theme: 'default',
                    lineNumbers: true,
                    lineWrapping: true,
                    autoCloseBrackets: true,
                    autoCloseTags: true,
                    matchBrackets: true,
                    matchTags: true,
                    indentUnit: 2,
                    tabSize: 2
                  }"
                  class="html-editor"
                  placeholder="<!-- Enter your HTML code here -->
<div class='custom-html-content'>
  <h2>Custom HTML Content</h2>
  <p>This is a custom HTML node that can display rich content.</p>
  <form>
    <div class='form-group'>
      <label>Name:</label>
      <input type='text' class='form-control' />
    </div>
    <button type='button' class='btn'>Submit</button>
  </form>
</div>"
                />
              </div>
              <p class="text-xs text-gray-500 mt-2">
                💡 You can use variables in your HTML with double curly braces: <code>{{ variableSyntaxExample }}</code>
              </p>
            </div>
            
            <!-- CSS Tab -->
            <div v-show="activeTab === 'css'" class="tab-content py-4">
              <div class="css-editor-container">
                <RsCodeMirror
                  v-model="localNodeData.cssCode"
                  :options="{
                    mode: 'css',
                    theme: 'default',
                    lineNumbers: true,
                    lineWrapping: true,
                    autoCloseBrackets: true,
                    matchBrackets: true,
                    indentUnit: 2,
                    tabSize: 2
                  }"
                  class="css-editor"
                  placeholder="/* Add your custom CSS styles here */
.custom-html-content {
  padding: 15px;
  border-radius: 5px;
  background-color: #f5f5f5;
}

.form-group {
  margin-bottom: 15px;
}

.form-control {
  width: 100%;
  padding: 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.btn {
  padding: 8px 16px;
  background-color: #4a6cf7;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}"
                />
              </div>
              <p class="text-xs text-gray-500 mt-2">
                💡 Add CSS to style your HTML content. These styles will be scoped to this HTML node only.
              </p>
            </div>
            
            <!-- JavaScript Tab -->
            <div v-show="activeTab === 'js'" class="tab-content py-4">
              <div class="js-editor-container">
                <RsCodeMirror
                  v-model="localNodeData.jsCode"
                  :options="{
                    mode: 'javascript',
                    theme: 'default',
                    lineNumbers: true,
                    lineWrapping: true,
                    autoCloseBrackets: true,
                    matchBrackets: true,
                    indentUnit: 2,
                    tabSize: 2
                  }"
                  class="js-editor"
                  placeholder="// Add your custom JavaScript here
// This will be executed when the HTML is rendered

document.addEventListener('DOMContentLoaded', function() {
  // Access elements in your custom HTML
  const button = document.querySelector('.btn');
  if (button) {
    button.addEventListener('click', function() {
      // Handle button click
      console.log('Button clicked!');
      
      // You can access process variables like this:
      // const value = processVariables.someVariable;
      
      // And update them like this:
      // processVariables.outputValue = 'New value';
    });
  }
});"
                />
              </div>
              <p class="text-xs text-gray-500 mt-2">
                💡 Use <code>processVariables</code> to access and modify process data.
                Available variables: {{ availableVariableNames.join(', ') || 'None' }}
              </p>
            </div>
          </div>

          <!-- Variable Integration -->
          <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-6">
            <FormKit
              type="checkbox"
              label="Allow Variable Access"
              name="allowVariableAccess"
              v-model="localNodeData.allowVariableAccess"
              help="If enabled, HTML can access and modify process variables"
              :classes="{ outer: 'field-wrapper' }"
            />
            
            <FormKit
              type="checkbox"
              label="Auto-refresh on Variable Change"
              name="autoRefresh"
              v-model="localNodeData.autoRefresh"
              help="If enabled, HTML content will refresh when variables change"
              :classes="{ outer: 'field-wrapper' }"
            />
          </div>
        </div>
      </div>

      <!-- Variables Section -->
      <div class="config-section">
        <h4 class="section-title">Variable Management</h4>
        <div class="section-content">
          <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
            <!-- Input Variables -->
            <div>
              <label class="block text-sm font-medium text-gray-700 mb-2">
                Input Variables
              </label>
              <div class="variable-list">
                <div 
                  v-for="variable in availableVariables" 
                  :key="variable.name"
                  class="variable-item"
                  :class="{ 'selected': isInputVariable(variable.name) }"
                  @click="toggleInputVariable(variable.name)"
                >
                  <div class="variable-info">
                    <span class="variable-name">{{ variable.name }}</span>
                    <span class="variable-type">{{ variable.type }}</span>
                  </div>
                  <span class="variable-description">{{ variable.description }}</span>
                </div>
              </div>
              <p class="text-xs text-gray-500 mt-2">
                Click to select variables this HTML node will read from
              </p>
            </div>

            <!-- Output Variables -->
            <div>
              <label class="block text-sm font-medium text-gray-700 mb-2">
                Output Variables
              </label>
              <div class="space-y-2">
                <div
                  v-for="(output, index) in localNodeData.outputVariables"
                  :key="index"
                  class="flex items-center space-x-2"
                >
                  <FormKit
                    type="text"
                    v-model="output.name"
                    placeholder="Variable name"
                    :classes="{ outer: 'flex-1' }"
                  />
                  <FormKit
                    type="select"
                    v-model="output.type"
                    :options="[
                      { label: 'String', value: 'string' },
                      { label: 'Number', value: 'number' },
                      { label: 'Boolean', value: 'boolean' },
                      { label: 'Object', value: 'object' },
                      { label: 'Array', value: 'array' }
                    ]"
                    :classes="{ outer: 'flex-1' }"
                  />
                  <button
                    @click="removeOutputVariable(index)"
                    class="p-2 text-red-600 hover:bg-red-50 rounded"
                  >
                    <Icon name="material-symbols:delete-outline" class="w-4 h-4" />
                  </button>
                </div>
                
                <button
                  @click="addOutputVariable"
                  class="flex items-center space-x-2 px-3 py-2 text-blue-600 hover:bg-blue-50 rounded border border-dashed border-blue-300"
                >
                  <Icon name="material-symbols:add" class="w-4 h-4" />
                  <span class="text-sm">Add Output Variable</span>
                </button>
              </div>
              <p class="text-xs text-gray-500 mt-2">
                Define variables this HTML node will create or modify
              </p>
            </div>
          </div>
        </div>
      </div>

      <!-- HTML Preview Section -->
      <div class="config-section">
        <h4 class="section-title">Preview</h4>
        <div class="section-content">
          <div class="preview-container p-4 bg-gray-50 rounded-lg">
            <div class="flex items-center justify-between mb-3">
              <h5 class="font-medium text-gray-700">HTML Preview</h5>
              <div class="flex items-center space-x-2">
                <span class="text-xs text-gray-500">Auto-refresh</span>
                <label class="switch">
                  <input type="checkbox" v-model="autoPreview">
                  <span class="slider round"></span>
                </label>
                <button
                  @click="previewHtml"
                  :disabled="!localNodeData.htmlCode.trim()"
                  class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed text-sm"
                >
                  <Icon name="material-symbols:refresh" class="w-4 h-4 mr-1" />
                  Refresh Preview
                </button>
              </div>
            </div>
            
            <div class="preview-frame border border-gray-200 rounded bg-white p-4 min-h-[250px]">
              <div v-if="!previewContent" class="flex items-center justify-center h-full text-gray-400">
                <div class="text-center">
                  <Icon name="material-symbols:preview" class="w-8 h-8 mb-2 mx-auto" />
                  <p>Click "Refresh Preview" to see your HTML content</p>
                </div>
              </div>
              <div v-else v-html="previewContent" class="html-preview"></div>
            </div>
            
            <div v-if="previewError" class="error-details mt-3 p-3 bg-red-50 border border-red-200 rounded text-sm text-red-700">
              <div class="flex items-start">
                <Icon name="material-symbols:error" class="w-5 h-5 mr-2 flex-shrink-0 text-red-500" />
                <div>{{ previewError }}</div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted, nextTick } from 'vue'

// Props and emits
const props = defineProps({
  nodeData: {
    type: Object,
    default: () => ({})
  },
  availableVariables: {
    type: Array,
    default: () => []
  }
})

const emit = defineEmits(['update'])

// Local state
const localNodeData = ref({
  label: '',
  description: '',
  htmlCode: '<!-- Enter your HTML code here -->\n<div class="custom-html-content">\n  <h2>Custom HTML Content</h2>\n  <p>This is a custom HTML node that can display rich content.</p>\n</div>',
  cssCode: '',
  jsCode: '',
  inputVariables: [],
  outputVariables: [],
  allowVariableAccess: true,
  autoRefresh: false
})

// Tab state
const activeTab = ref('html')

// Preview state
const autoPreview = ref(true)
const previewContent = ref(null)
const previewError = ref(null)

// Computed property to avoid template syntax issues
const variableSyntaxExample = computed(() => '{{ variableName }}')

// Computed properties
const availableVariableNames = computed(() => {
  return props.availableVariables.map(v => v.name)
})

// Methods
const isInputVariable = (variableName) => {
  return localNodeData.value.inputVariables.includes(variableName)
}

const toggleInputVariable = (variableName) => {
  const index = localNodeData.value.inputVariables.indexOf(variableName)
  if (index > -1) {
    localNodeData.value.inputVariables.splice(index, 1)
  } else {
    localNodeData.value.inputVariables.push(variableName)
  }
  emitUpdate()
}

const addOutputVariable = () => {
  localNodeData.value.outputVariables.push({
    name: '',
    type: 'string',
    description: ''
  })
  emitUpdate()
}

const removeOutputVariable = (index) => {
  localNodeData.value.outputVariables.splice(index, 1)
  emitUpdate()
}

const previewHtml = () => {
  try {
    previewError.value = null
    
    // Combine HTML, CSS and JS for preview
    let htmlContent = localNodeData.value.htmlCode || ''
    const cssCode = localNodeData.value.cssCode || ''
    const jsCode = localNodeData.value.jsCode || ''
    
    // Add CSS if provided
    if (cssCode) {
      htmlContent = `<style>${cssCode}</style>${htmlContent}`
    }
    
    // Add JS if provided (in a safe way)
    if (jsCode) {
      // We don't actually execute JS in the preview for security reasons
      // Just show a placeholder that JS will be included
      htmlContent += `<div class="js-indicator text-xs text-gray-500 mt-4 p-2 bg-gray-100 rounded">
        <strong>Note:</strong> JavaScript functionality will be available when deployed.
      </div>`
    }
    
    // Replace variable placeholders with mock values
    if (localNodeData.value.allowVariableAccess) {
      const variableRegex = /\{\{\s*([a-zA-Z0-9_\.]+)\s*\}\}/g
      htmlContent = htmlContent.replace(variableRegex, (match, varName) => {
        const variable = props.availableVariables.find(v => v.name === varName)
        if (variable) {
          return getMockValueForType(variable.type)
        }
        return `[${varName}]`
      })
    }
    
    previewContent.value = htmlContent
  } catch (error) {
    previewError.value = `Preview error: ${error.message}`
    previewContent.value = null
  }
}

const getMockValueForType = (type) => {
  switch (type) {
    case 'string': return 'Sample Text'
    case 'number': return '42'
    case 'boolean': return 'true'
    case 'object': return '{object}'
    case 'array': return '[array]'
    default: return 'value'
  }
}

// Add a flag to prevent recursive updates
const isUpdatingFromProps = ref(false)

const emitUpdate = () => {
  emit('update', localNodeData.value)
}

// Watch for prop changes
watch(
  () => props.nodeData,
  (newData) => {
    if (newData && Object.keys(newData).length > 0) {
      isUpdatingFromProps.value = true
      localNodeData.value = {
        label: newData.label || 'HTML Node',
        description: newData.description || '',
        htmlCode: newData.htmlCode || '<!-- Enter your HTML code here -->\n<div class="custom-html-content">\n  <h2>Custom HTML Content</h2>\n  <p>This is a custom HTML node that can display rich content.</p>\n</div>',
        cssCode: newData.cssCode || '',
        jsCode: newData.jsCode || '',
        inputVariables: newData.inputVariables || [],
        outputVariables: newData.outputVariables || [],
        allowVariableAccess: newData.allowVariableAccess !== undefined ? newData.allowVariableAccess : true,
        autoRefresh: newData.autoRefresh || false
      }
      // Reset the flag after the update
      nextTick(() => {
        isUpdatingFromProps.value = false
      })
    }
  },
  { immediate: true, deep: true }
)

// Watch for changes in localNodeData and emit updates
watch(
  localNodeData,
  () => {
    // Only emit if we're not currently updating from props
    if (!isUpdatingFromProps.value) {
      emitUpdate()
    }
  },
  { deep: true }
)

// Watch for HTML, CSS, or JS changes to auto-refresh preview
watch(
  [
    () => localNodeData.value.htmlCode,
    () => localNodeData.value.cssCode,
    () => localNodeData.value.jsCode
  ],
  () => {
    if (autoPreview.value) {
      previewHtml()
    }
  }
)

// Initialize preview on component mount
onMounted(() => {
  if (autoPreview.value && localNodeData.value.htmlCode) {
    previewHtml()
  }
})
</script>

<style scoped>
.html-node-config {
  @apply max-w-6xl mx-auto bg-white;
}

.config-content {
  @apply p-6 space-y-8;
}

.config-header {
  @apply border-b border-gray-200 pb-4;
}

.config-section {
  @apply space-y-4;
}

.section-title {
  @apply text-base font-semibold text-gray-800 mb-3;
}

.section-content {
  @apply space-y-4;
}

.code-editor-tabs {
  @apply border border-gray-200 rounded-lg overflow-hidden bg-white;
}

.tabs-header {
  @apply bg-gray-50;
}

.tab-content {
  @apply p-0;
}

.html-editor-container,
.css-editor-container,
.js-editor-container {
  @apply border-0;
}

.html-editor,
.css-editor,
.js-editor {
  min-height: 250px;
}

/* Toggle Switch */
.switch {
  position: relative;
  display: inline-block;
  width: 36px;
  height: 20px;
}

.switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #ccc;
  transition: .4s;
}

.slider:before {
  position: absolute;
  content: "";
  height: 16px;
  width: 16px;
  left: 2px;
  bottom: 2px;
  background-color: white;
  transition: .4s;
}

input:checked + .slider {
  background-color: #3b82f6;
}

input:focus + .slider {
  box-shadow: 0 0 1px #3b82f6;
}

input:checked + .slider:before {
  transform: translateX(16px);
}

.slider.round {
  border-radius: 20px;
}

.slider.round:before {
  border-radius: 50%;
}

.variable-list {
  @apply space-y-1 max-h-48 overflow-y-auto border border-gray-200 rounded-lg p-2;
}

.variable-item {
  @apply p-2 rounded cursor-pointer hover:bg-gray-50 border border-transparent;
}

.variable-item.selected {
  @apply bg-blue-50 border-blue-200;
}

.variable-info {
  @apply flex items-center justify-between;
}

.variable-name {
  @apply font-medium text-gray-800;
}

.variable-type {
  @apply text-xs text-gray-500 bg-gray-100 px-2 py-1 rounded;
}

.variable-description {
  @apply text-xs text-gray-600 mt-1;
}

.preview-container {
  @apply border border-gray-200;
}

.preview-frame {
  min-height: 200px;
}

.field-wrapper {
  @apply mb-0;
}

code {
  @apply bg-gray-100 px-1 py-0.5 rounded text-xs font-mono;
}

.html-preview :deep(*) {
  max-width: 100%;
}
</style> 