<script setup lang="ts">
import { ref, watch } from 'vue';

import { Maximize2, Plus, Trash2 } from '@vben/icons';
import { $t } from '@vben/locales';

import {
  ElAlert,
  ElButton,
  ElForm,
  ElFormItem,
  ElInput,
  ElOption,
  ElRadioButton,
  ElRadioGroup,
  ElSelect,
  ElTooltip,
} from 'element-plus';

import { ZqDialog } from '#/components/zq-dialog';
import { getParamTypeOptions } from '#/views/_core/data-source/data';

import SmartInput from '../components/SmartInput.vue';
import DbConfigSummary from '../components/DbConfigSummary.vue';
import DbConnectionSelect from '../components/DbConnectionSelect.vue';

interface SqlParam {
  name: string;
  type: string;
  value: string;
}

const props = defineProps<{ data: any; nodeId: string; nodeType?: string }>();
const emit = defineEmits(['update']);

const paramTypeOptions = getParamTypeOptions();

const initialDbConfig = {
  dbName: 'default',
  dbType: 'postgresql',
  ...(props.data?.db_config || {}),
};

function normalizeParam(raw: Partial<SqlParam> & { default?: string }): SqlParam {
  return {
    name: raw.name ?? '',
    type: raw.type ?? 'string',
    value: raw.value ?? raw.default ?? '',
  };
}

const form = ref({
  label: $t('ai-platform.workflow.panels.dbSql.label'),
  sql_type: 'query',
  sql: '',
  params: [] as SqlParam[],
  output_variable: 'sql_result',
  ...props.data,
  db_config: initialDbConfig,
});

form.value.params = (form.value.params || []).map(normalizeParam);
if (!form.value.db_config) {
  form.value.db_config = initialDbConfig;
}

watch(
  form,
  (val) => {
    emit('update', val);
  },
  { deep: true },
);

const sqlEditorVisible = ref(false);

const addParam = () => {
  form.value.params.push({
    name: '',
    type: 'string',
    value: '',
  });
};

const removeParam = (index: number) => {
  form.value.params.splice(index, 1);
};

const sqlExamples = [
  {
    label: $t('ai-platform.workflow.panels.dbSql.queryExample'),
    value: 'SELECT * FROM users WHERE status = :status LIMIT :limit',
  },
  {
    label: $t('ai-platform.workflow.panels.dbSql.insertExample'),
    value:
      'INSERT INTO logs (user_id, action, created_at) VALUES (:user_id, :action, NOW())',
  },
  {
    label: $t('ai-platform.workflow.panels.dbSql.updateExample'),
    value: 'UPDATE orders SET status = :status WHERE id = :id',
  },
  {
    label: $t('ai-platform.workflow.panels.dbSql.statsExample'),
    value: 'SELECT COUNT(*) as total, status FROM orders GROUP BY status',
  },
];

const insertExample = (sql: string) => {
  form.value.sql = sql;
};

function handleConnectionChange(payload: { dbName: string; dbType: string }) {
  form.value.db_config = {
    ...form.value.db_config,
    dbName: payload.dbName,
    dbType: payload.dbType,
  };
}
</script>

<template>
  <ElForm label-position="top" size="small" class="space-y-4">
    <ElAlert type="warning" :closable="false" show-icon>
      <template #title>
        <span class="text-xs font-medium">{{
          $t('ai-platform.workflow.panels.dbSql.cautionWarning')
        }}</span>
      </template>
    </ElAlert>

    <ElFormItem :label="$t('ai-platform.workflow.panels.common.nodeName')">
      <ElInput
        v-model="form.label"
        :placeholder="$t('ai-platform.workflow.panels.dbSql.placeholder')"
      />
    </ElFormItem>

    <DbConnectionSelect
      v-model="form.db_config.dbName"
      :write-mode="form.sql_type === 'execute'"
      @change="handleConnectionChange"
    />
    <DbConfigSummary
      :db-config="form.db_config"
      :show-default-write-warning="form.sql_type === 'execute'"
    />

    <ElFormItem :label="$t('ai-platform.workflow.panels.dbSql.execType')">
      <ElRadioGroup v-model="form.sql_type">
        <ElRadioButton value="query">
          {{ $t('ai-platform.workflow.panels.dbSql.queryType') }}
        </ElRadioButton>
        <ElRadioButton value="execute">
          {{ $t('ai-platform.workflow.panels.dbSql.executeType') }}
        </ElRadioButton>
      </ElRadioGroup>
    </ElFormItem>

    <div>
      <div class="mb-2 flex items-center justify-between">
        <span class="text-foreground text-xs">{{
          $t('ai-platform.workflow.panels.dbSql.sqlStatement')
        }}</span>
        <ElTooltip
          :content="$t('ai-platform.workflow.panels.code.expandEditor')"
        >
          <ElButton link type="primary" @click="sqlEditorVisible = true">
            <Maximize2 class="size-4" />
          </ElButton>
        </ElTooltip>
      </div>
      <ElInput
        v-model="form.sql"
        type="textarea"
        :rows="12"
        resize="vertical"
        :placeholder="$t('ai-platform.workflow.panels.dbSql.sqlPlaceholder')"
        class="workflow-code-textarea"
      />
      <div class="mt-2 flex flex-wrap items-center gap-1">
        <span class="text-muted-foreground mr-2 text-xs">
          {{ $t('ai-platform.workflow.panels.dbSql.examples') }}:
        </span>
        <button
          v-for="example in sqlExamples"
          :key="example.label"
          type="button"
          class="text-xs text-blue-500 hover:text-blue-700 hover:underline"
          @click="insertExample(example.value)"
        >
          {{ example.label }}
        </button>
      </div>
      <div class="text-muted-foreground mt-1 text-xs">
        {{ $t('ai-platform.workflow.panels.dbSql.sqlParamHint') }}
      </div>
    </div>

    <div>
      <div class="flex items-center justify-between">
        <span class="text-foreground text-sm font-medium">{{
          $t('ai-platform.workflow.panels.dbSql.paramList')
        }}</span>
        <ElButton link type="primary" :icon="Plus" @click="addParam">
          {{ $t('ai-platform.workflow.panels.dbSql.addParam') }}
        </ElButton>
      </div>

      <div
        v-if="form.params.length === 0"
        class="text-muted-foreground py-4 text-center text-xs"
      >
        {{ $t('ai-platform.workflow.panels.dbSql.noParams') }}
      </div>

      <div v-else class="mt-3 space-y-3">
        <div
          v-for="(param, index) in form.params"
          :key="index"
          class="border-border bg-muted rounded border p-3"
        >
          <div class="flex items-center gap-2">
            <ElInput
              v-model="param.name"
              :placeholder="$t('ai-platform.workflow.panels.dbSql.paramName')"
              size="small"
              style="width: 138px"
            />
            <ElSelect
              v-model="param.type"
              :placeholder="$t('ai-platform.workflow.panels.dbSql.paramType')"
              size="small"
              style="width: 158px"
            >
              <ElOption
                v-for="opt in paramTypeOptions"
                :key="opt.value"
                :label="opt.label"
                :value="opt.value"
              />
            </ElSelect>
            <div class="db-sql-param-value shrink-0">
              <SmartInput
                v-model="param.value"
                :current-node-id="nodeId"
                :placeholder="
                  $t('ai-platform.workflow.panels.dbSql.paramValuePlaceholder')
                "
                size="small"
              />
            </div>
            <ElButton
              link
              type="danger"
              :icon="Trash2"
              @click="removeParam(index)"
            />
          </div>
        </div>
      </div>

      <div class="text-muted-foreground mt-2 text-xs">
        {{ $t('ai-platform.workflow.panels.dbSql.paramsHint') }}
      </div>
    </div>

    <ElFormItem :label="$t('ai-platform.workflow.panels.common.outputVarName')">
      <ElInput v-model="form.output_variable" placeholder="sql_result" />
      <div class="text-muted-foreground mt-1 text-xs">
        <span v-if="form.sql_type === 'query'">{{
          $t('ai-platform.workflow.panels.dbSql.queryResultHint')
        }}</span>
        <span v-else>{{
          $t('ai-platform.workflow.panels.dbSql.affectedRowsHint')
        }}</span>
      </div>
    </ElFormItem>
  </ElForm>

  <ZqDialog
    v-model="sqlEditorVisible"
    class="code-editor-dialog"
    :title="$t('ai-platform.workflow.panels.dbSql.sqlStatement')"
    width="960px"
    :show-footer="false"
  >
    <div class="code-editor-dialog-content">
      <ElInput
        v-model="form.sql"
        type="textarea"
        resize="none"
        :placeholder="$t('ai-platform.workflow.panels.dbSql.sqlPlaceholder')"
        class="workflow-code-textarea workflow-code-textarea--dialog"
      />
    </div>
  </ZqDialog>
</template>

<style scoped>
.db-sql-param-value {
  width: 142px;
}

.db-sql-param-value :deep(> div) {
  width: 100%;
  min-width: 0;
}

:deep(.workflow-code-textarea textarea) {
  font-family:
    ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono',
    'Courier New', monospace;
  font-size: 12px;
  line-height: 1.6;
}
</style>

<style>
/* 与 CodePanel 共用：编辑器弹窗占满 dialog（含全屏） */
.code-editor-dialog .zq-dialog-body .el-scrollbar,
.code-editor-dialog .zq-dialog-body .el-scrollbar__wrap,
.code-editor-dialog .zq-dialog-body .el-scrollbar__view,
.code-editor-dialog .zq-dialog-body .el-scrollbar__view > div,
.code-editor-dialog .code-editor-dialog-content {
  height: 100%;
}

.code-editor-dialog:not(.is-fullscreen) .zq-dialog-body {
  height: 70vh;
}

.code-editor-dialog:not(.is-fullscreen) .zq-dialog-body .el-scrollbar {
  height: 100%;
}

.code-editor-dialog .code-editor-dialog-content {
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.code-editor-dialog.is-fullscreen .el-dialog__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
}

.code-editor-dialog.is-fullscreen .zq-dialog-body {
  flex: 1;
  min-height: 0;
}

.code-editor-dialog.is-fullscreen .zq-dialog-body .el-scrollbar {
  height: 100% !important;
}

.workflow-code-textarea--dialog,
.workflow-code-textarea--dialog textarea {
  height: 100%;
}
</style>
