<template>
  <el-dialog v-model="visible" :title="t('providers.workflowDialogTitle')" width="720px" destroy-on-close @closed="reset">
    <el-form label-width="100px">
      <el-form-item :label="t('providers.ingressModelId')" required>
        <el-input v-model="form.model_id" placeholder="luminary/flux-sdxl" />
        <p class="form-hint">{{ t('providers.ingressModelIdHint') }}</p>
      </el-form-item>
      <el-form-item :label="t('providers.displayName')">
        <el-input v-model="form.display_name" />
      </el-form-item>
      <el-form-item :label="t('providers.workflowType')">
        <el-select v-model="form.workflow_type" @change="onTypeChange">
          <el-option :label="t('providers.txt2img')" value="txt2img" />
          <el-option :label="t('providers.img2img')" value="img2img" />
        </el-select>
      </el-form-item>
      <el-form-item :label="t('providers.workflowJson')">
        <el-input v-model="form.workflow_json" type="textarea" :rows="8" placeholder="{ ... ComfyUI API Format ... }" />
      </el-form-item>
      <el-form-item>
        <el-button :loading="analyzing" @click="analyze">{{ t('providers.analyzeWorkflow') }}</el-button>
      </el-form-item>
    </el-form>

    <el-table v-if="bindings.length" :data="bindings" size="small" class="u-mt-2">
      <el-table-column prop="param" :label="t('providers.paramName')" width="140" />
      <el-table-column :label="t('providers.bindEnabled')" width="90">
        <template #default="{ row }">
          <el-switch v-model="row.enabled" :disabled="row.required" />
        </template>
      </el-table-column>
      <el-table-column :label="t('providers.targetNode')">
        <template #default="{ row }">
          <el-select v-model="row.node" clearable filterable :disabled="!row.enabled" @change="onNodeChange(row)">
            <el-option
              v-for="n in nodes"
              :key="n.id"
              :label="`${n.id} — ${n.class_type}`"
              :value="n.id"
            />
          </el-select>
        </template>
      </el-table-column>
      <el-table-column :label="t('providers.targetField')">
        <template #default="{ row }">
          <el-select v-model="row.field" clearable :disabled="!row.enabled || !row.node">
            <el-option v-for="f in fieldsFor(row.node)" :key="f" :label="f" :value="f" />
          </el-select>
        </template>
      </el-table-column>
    </el-table>

    <template #footer>
      <el-button @click="visible = false">{{ t('common.cancel') }}</el-button>
      <el-button type="primary" :loading="saving" @click="save">{{ t('common.save') }}</el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { ElMessage } from 'element-plus'
import api from '@/api/client'

const { t } = useI18n()

interface WorkflowNode {
  id: string
  class_type: string
  injectable_fields: string[]
}

interface BindingRow {
  param: string
  required: boolean
  enabled: boolean
  node: string
  field: string
}

const props = defineProps<{ providerId: number }>()
const emit = defineEmits<{ saved: [] }>()

const visible = defineModel<boolean>({ required: true })
const analyzing = ref(false)
const saving = ref(false)
const nodes = ref<WorkflowNode[]>([])
const bindings = ref<BindingRow[]>([])

const form = ref({
  model_id: '',
  display_name: '',
  workflow_type: 'txt2img',
  workflow_json: '',
})

const requiredParams = computed(() =>
  form.value.workflow_type === 'img2img' ? ['prompt', 'image'] : ['prompt'],
)

function reset() {
  form.value = { model_id: '', display_name: '', workflow_type: 'txt2img', workflow_json: '' }
  nodes.value = []
  bindings.value = []
}

function fieldsFor(nodeId: string) {
  return nodes.value.find(n => n.id === nodeId)?.injectable_fields || []
}

function onNodeChange(row: BindingRow) {
  const fields = fieldsFor(row.node)
  if (!fields.includes(row.field)) row.field = fields[0] || ''
}

async function onTypeChange() {
  if (form.value.workflow_json) await analyze()
}

async function analyze() {
  if (!form.value.workflow_json.trim()) {
    ElMessage.warning(t('providers.workflowJsonRequired'))
    return
  }
  analyzing.value = true
  try {
    const res = await api.post('/workflows/analyze', {
      workflow_json: form.value.workflow_json,
      workflow_type: form.value.workflow_type,
    })
    nodes.value = res.data.nodes || []
    bindings.value = (res.data.suggestions || []).map((s: any) => ({
      param: s.param,
      required: requiredParams.value.includes(s.param),
      enabled: requiredParams.value.includes(s.param) || !!(s.node && s.field),
      node: s.node || '',
      field: s.field || '',
    }))
  } catch (e: any) {
    ElMessage.error(e.response?.data?.error || t('providers.analyzeFailed'))
  } finally {
    analyzing.value = false
  }
}

function buildBinding() {
  const out: Record<string, { node: string; field: string }> = {}
  for (const row of bindings.value) {
    if (!row.enabled || !row.node || !row.field) continue
    out[row.param] = { node: row.node, field: row.field }
  }
  return out
}

async function save() {
  if (!form.value.model_id.trim()) {
    ElMessage.warning(t('providers.ingressModelIdRequired'))
    return
  }
  saving.value = true
  try {
    await api.post(`/providers/${props.providerId}/models`, {
      model_id: form.value.model_id.trim(),
      display_name: form.value.display_name || form.value.model_id,
      workflow_type: form.value.workflow_type,
      workflow_json: form.value.workflow_json,
      input_binding: buildBinding(),
    })
    ElMessage.success(t('providers.workflowSaved'))
    visible.value = false
    emit('saved')
  } catch (e: any) {
    ElMessage.error(e.response?.data?.error || t('providers.updateFailed'))
  } finally {
    saving.value = false
  }
}

watch(visible, (v) => {
  if (v) reset()
})
</script>
