<script setup lang="ts">
import type { llmType } from '#/api';
import type { ModelAbilityItem } from '#/views/ai/model/modelUtils/model-ability';
import type { VerifyButtonStatus } from '#/views/ai/model/modelUtils/model-verification';

import { computed, onMounted, reactive, ref } from 'vue';

import {
  CircleCheck,
  CircleClose,
  Delete,
  Edit,
  Loading,
  Select,
  Warning,
} from '@element-plus/icons-vue';
import {
  ElButton,
  ElEmpty,
  ElIcon,
  ElInput,
  ElMessage,
  ElMessageBox,
  ElOption,
  ElSelect,
  ElTable,
  ElTableColumn,
  ElTag,
} from 'element-plus';

import { deleteLlm, getModelList, verifyModelConfig } from '#/api/ai/llm';
import { $t } from '#/locales';
import ModelProviderBadge from '#/views/ai/model/ModelProviderBadge.vue';
import { getDefaultModelAbility } from '#/views/ai/model/modelUtils/model-ability';
import { mapLlmToModelAbility } from '#/views/ai/model/modelUtils/model-ability-utils';
import {
  getVerifyButtonText as getStatusButtonText,
  resolveModelVerificationFeedback,
} from '#/views/ai/model/modelUtils/model-verification';

interface ProviderOption {
  id: string;
  providerName: string;
}

interface FilterState {
  keyword: string;
  modelType: string;
  providerId: string;
}

interface BatchDeleteResult {
  failed: Array<{ id: string; message: string }>;
  successIds: string[];
}

const props = defineProps<{
  providers: ProviderOption[];
}>();

const emit = defineEmits<{
  (e: 'createModel', modelType?: string): void;
  (e: 'editModel', id: string): void;
  (e: 'refreshProviderStats'): void;
}>();

const isLoading = ref(false);
const isActionLoading = ref(false);
const modelRows = ref<llmType[]>([]);
const selectedRows = ref<llmType[]>([]);
const lastErrorMessage = ref('');
const verifyStatusMap = ref<Record<string, VerifyButtonStatus>>({});

const filterState = reactive<FilterState>({
  keyword: '',
  modelType: '',
  providerId: '',
});

const modelTypeOptions = [
  {
    label: $t('llmProvider.chatModel'),
    value: 'chatModel',
  },
  {
    label: $t('llmProvider.embeddingModel'),
    value: 'embeddingModel',
  },
  {
    label: $t('llmProvider.rerankModel'),
    value: 'rerankModel',
  },
];

const modelTypeLabelMap: Record<string, string> = {
  chatModel: $t('llmProvider.chatModel'),
  embeddingModel: $t('llmProvider.embeddingModel'),
  rerankModel: $t('llmProvider.rerankModel'),
};

const getProviderName = (row: llmType) =>
  row.modelProvider?.providerName || row.aiLlmProvider?.providerName || '-';

const getProviderType = (row: llmType) =>
  row.modelProvider?.providerType || row.aiLlmProvider?.providerType || '';

const getProviderIcon = (row: llmType) =>
  row.modelProvider?.icon || row.aiLlmProvider?.icon || '';

const getModelName = (row: llmType) =>
  row.llmModel || (row as any).modelName || '-';

const getModelTypeLabel = (row: llmType) =>
  modelTypeLabelMap[row.modelType] || row.modelType || '-';

const canVerify = (row: llmType) => row.modelType !== 'rerankModel';
const getModelId = (row: llmType) =>
  String((row as any).id || (row as any).llmId || (row as any).modelId || '');
const getVerifyStatus = (row: llmType): VerifyButtonStatus =>
  verifyStatusMap.value[getModelId(row)] || 'idle';
const setVerifyStatus = (id: string, status: VerifyButtonStatus) => {
  if (!id) {
    return;
  }
  verifyStatusMap.value[id] = status;
};
const isVerifying = (row: llmType) => getVerifyStatus(row) === 'loading';
const getVerifyButtonText = (row: llmType) => {
  return getStatusButtonText(getVerifyStatus(row));
};
const getVerifyButtonIcon = (row: llmType) => {
  const status = getVerifyStatus(row);
  if (status === 'loading') {
    return Loading;
  }
  if (status === 'success') {
    return CircleCheck;
  }
  if (status === 'warning') {
    return Warning;
  }
  if (status === 'error') {
    return CircleClose;
  }
  return Select;
};

const getAbilityTags = (row: llmType): ModelAbilityItem[] =>
  mapLlmToModelAbility(row, getDefaultModelAbility()).filter(
    (tag) => tag.selected,
  );

const totalCount = computed(() => modelRows.value.length);

const filteredRows = computed(() => {
  const keyword = filterState.keyword.trim().toLowerCase();

  return modelRows.value.filter((item) => {
    if (
      filterState.providerId &&
      String((item as any).providerId) !== filterState.providerId
    ) {
      return false;
    }

    if (filterState.modelType && item.modelType !== filterState.modelType) {
      return false;
    }

    if (!keyword) {
      return true;
    }

    const searchTargets = [
      item.title,
      getModelName(item),
      item.groupName,
      getProviderName(item),
    ]
      .filter(Boolean)
      .map((text) => String(text).toLowerCase());

    return searchTargets.some((text) => text.includes(keyword));
  });
});

const selectableRowCount = computed(() => selectedRows.value.length);

const loadModels = async () => {
  isLoading.value = true;
  lastErrorMessage.value = '';

  try {
    const res = await getModelList();

    if (res.errorCode === 0) {
      modelRows.value = res.data || [];
      verifyStatusMap.value = {};
    } else {
      modelRows.value = [];
      verifyStatusMap.value = {};
      lastErrorMessage.value =
        res.message || $t('ui.actionMessage.operationFailed');
    }
  } catch (error) {
    modelRows.value = [];
    verifyStatusMap.value = {};
    lastErrorMessage.value =
      (error as Error)?.message || $t('ui.actionMessage.operationFailed');
  } finally {
    isLoading.value = false;
  }
};

const reloadAndNotify = async () => {
  await loadModels();
  emit('refreshProviderStats');
  selectedRows.value = [];
};

const handleSelectionChange = (rows: llmType[]) => {
  selectedRows.value = rows;
};

const handleEdit = (row: llmType) => {
  const modelId = getModelId(row);
  if (!modelId) {
    ElMessage.warning('当前模型缺少ID，无法编辑');
    return;
  }
  emit('editModel', modelId);
};

const handleDelete = async (row: llmType) => {
  const modelId = getModelId(row);
  if (!modelId) {
    ElMessage.warning('当前模型缺少ID，无法删除');
    return;
  }

  try {
    await ElMessageBox.confirm(
      `确认删除模型「${row.title}」吗？该操作不可恢复。`,
      $t('message.noticeTitle'),
      {
        cancelButtonText: $t('message.cancel'),
        confirmButtonText: $t('message.ok'),
        type: 'warning',
      },
    );
  } catch {
    return;
  }

  isActionLoading.value = true;

  try {
    const res = await deleteLlm({ id: modelId });

    if (res.errorCode === 0) {
      ElMessage.success(res.message || '模型已删除');
      await reloadAndNotify();
    } else {
      ElMessage.error(res.message || $t('ui.actionMessage.operationFailed'));
    }
  } finally {
    isActionLoading.value = false;
  }
};

const handleVerify = async (row: llmType) => {
  const modelId = getModelId(row);

  if (!canVerify(row) || !modelId || isVerifying(row)) {
    if (!modelId) {
      ElMessage.warning('当前模型缺少ID，无法验证配置');
    }
    return;
  }

  setVerifyStatus(modelId, 'loading');

  try {
    const res = await verifyModelConfig(modelId);

    const feedback = resolveModelVerificationFeedback(res, row.modelType);
    setVerifyStatus(modelId, feedback.status);

    if (feedback.status === 'success') {
      ElMessage.success(feedback.message);
    } else if (feedback.status === 'warning') {
      ElMessage.warning(feedback.message);
    } else {
      if (!res.message) {
        ElMessage.error(feedback.message);
      }
    }
  } catch {
    setVerifyStatus(modelId, 'error');
    // error toast is already handled by global response interceptors
  } finally {
    // keep final status to show explicit success/failure state
  }
};

const runBatchDelete = async (
  ids: string[],
  concurrency = 5,
): Promise<BatchDeleteResult> => {
  const queue = [...ids];
  const successIds: string[] = [];
  const failed: Array<{ id: string; message: string }> = [];

  const worker = async () => {
    while (queue.length > 0) {
      const id = queue.shift();
      if (!id) {
        return;
      }

      try {
        const res = await deleteLlm({ id });
        if (res.errorCode === 0) {
          successIds.push(id);
        } else {
          failed.push({ id, message: res.message || '删除失败' });
        }
      } catch (error) {
        failed.push({ id, message: (error as Error)?.message || '网络错误' });
      }
    }
  };

  const workerCount = Math.max(1, Math.min(concurrency, ids.length || 1));
  await Promise.all(Array.from({ length: workerCount }, () => worker()));

  return {
    failed,
    successIds,
  };
};

const handleBatchDelete = async () => {
  const ids = selectedRows.value
    .map((item) => getModelId(item))
    .filter(Boolean);

  if (ids.length === 0) {
    ElMessage.warning('请先选择要删除的模型');
    return;
  }

  try {
    await ElMessageBox.confirm(
      `确认批量删除 ${ids.length} 个模型吗？该操作不可恢复。`,
      $t('message.noticeTitle'),
      {
        cancelButtonText: $t('message.cancel'),
        confirmButtonText: $t('message.ok'),
        type: 'warning',
      },
    );
  } catch {
    return;
  }

  isActionLoading.value = true;

  try {
    const result = await runBatchDelete(ids, 5);
    const successCount = result.successIds.length;
    const failCount = result.failed.length;

    if (failCount === 0) {
      ElMessage.success(`批量删除完成，共 ${successCount} 个模型`);
    } else {
      ElMessage.warning(
        `批量删除完成，成功 ${successCount} 个，失败 ${failCount} 个`,
      );
    }

    await reloadAndNotify();
  } finally {
    isActionLoading.value = false;
  }
};

const resetFilters = () => {
  filterState.keyword = '';
  filterState.providerId = '';
  filterState.modelType = '';
};

onMounted(loadModels);

defineExpose({
  async reloadData() {
    await loadModels();
  },
});
</script>

<template>
  <section class="active-workspace">
    <header class="active-workspace__header">
      <div class="active-workspace__summary">
        <h3>已配置模型</h3>
        <p>共 {{ totalCount }} 个模型</p>
      </div>
    </header>

    <div class="active-workspace__filters">
      <ElInput
        v-model.trim="filterState.keyword"
        clearable
        placeholder="搜索模型名、模型ID、服务商、分组"
      />
      <ElSelect
        v-model="filterState.providerId"
        clearable
        placeholder="全部服务商"
      >
        <ElOption
          v-for="provider in props.providers"
          :key="provider.id"
          :label="provider.providerName"
          :value="provider.id"
        />
      </ElSelect>
      <ElSelect
        v-model="filterState.modelType"
        clearable
        placeholder="全部模型类型"
      >
        <ElOption
          v-for="type in modelTypeOptions"
          :key="type.value"
          :label="type.label"
          :value="type.value"
        />
      </ElSelect>
      <ElButton @click="resetFilters">重置</ElButton>
    </div>

    <div v-if="selectableRowCount > 0" class="active-workspace__batch-bar">
      <span>已选 {{ selectableRowCount }} 项</span>
      <div class="active-workspace__batch-actions">
        <ElButton
          class="is-danger"
          :disabled="isActionLoading"
          @click="handleBatchDelete"
        >
          批量删除
        </ElButton>
      </div>
    </div>

    <div v-if="isLoading" class="active-workspace__state">
      正在加载模型数据...
    </div>

    <div v-else-if="lastErrorMessage" class="active-workspace__state is-error">
      {{ lastErrorMessage }}
    </div>

    <div v-else-if="modelRows.length === 0" class="active-workspace__empty">
      <ElEmpty description="还没有模型，先添加一个模型开始使用。">
        <ElButton type="primary" @click="emit('createModel', 'chatModel')">
          添加模型
        </ElButton>
      </ElEmpty>
    </div>

    <div v-else-if="filteredRows.length === 0" class="active-workspace__empty">
      <ElEmpty description="没有符合筛选条件的模型，试试调整筛选项。" />
    </div>

    <ElTable
      v-else
      row-key="id"
      :data="filteredRows"
      class="active-workspace__table"
      @selection-change="handleSelectionChange"
    >
      <ElTableColumn type="selection" width="48" />

      <ElTableColumn label="模型 ID" min-width="220">
        <template #default="{ row }">
          <div class="active-workspace__name-with-logo">
            <ModelProviderBadge
              :icon="getProviderIcon(row)"
              :provider-name="getProviderName(row)"
              :provider-type="getProviderType(row)"
              :size="30"
            />
            <div class="active-workspace__name-cell">
              <strong>{{ row.title }}</strong>
              <span>{{ getModelName(row) }}</span>
            </div>
          </div>
        </template>
      </ElTableColumn>

      <ElTableColumn label="服务商" min-width="140">
        <template #default="{ row }">
          {{ getProviderName(row) }}
        </template>
      </ElTableColumn>

      <ElTableColumn label="类型" width="110">
        <template #default="{ row }">
          {{ getModelTypeLabel(row) }}
        </template>
      </ElTableColumn>

      <ElTableColumn label="分组" min-width="120">
        <template #default="{ row }">
          {{ row.groupName || '-' }}
        </template>
      </ElTableColumn>

      <ElTableColumn label="能力" min-width="220">
        <template #default="{ row }">
          <div class="active-workspace__ability">
            <ElTag
              v-for="tag in getAbilityTags(row)"
              :key="tag.value"
              effect="plain"
              size="small"
            >
              {{ tag.label }}
            </ElTag>
            <span v-if="getAbilityTags(row).length === 0">-</span>
          </div>
        </template>
      </ElTableColumn>

      <ElTableColumn label="操作" min-width="290" fixed="right">
        <template #default="{ row }">
          <div class="active-workspace__actions">
            <ElButton
              v-if="canVerify(row)"
              text
              size="small"
              class="active-workspace__verify-btn"
              :class="`is-${getVerifyStatus(row)}`"
              :disabled="
                isVerifying(row) || isActionLoading || !getModelId(row)
              "
              @click="handleVerify(row)"
            >
              <template #icon>
                <ElIcon
                  class="active-workspace__verify-icon"
                  :class="`is-${getVerifyStatus(row)}`"
                >
                  <component :is="getVerifyButtonIcon(row)" />
                </ElIcon>
              </template>
              {{ getVerifyButtonText(row) }}
            </ElButton>
            <ElButton text size="small" :icon="Edit" @click="handleEdit(row)">
              编辑
            </ElButton>
            <ElButton
              text
              size="small"
              class="is-danger"
              :icon="Delete"
              @click="handleDelete(row)"
            >
              删除
            </ElButton>
          </div>
        </template>
      </ElTableColumn>
    </ElTable>
  </section>
</template>

<style scoped>
.active-workspace {
  display: flex;
  flex-direction: column;
  gap: 16px;
  height: 100%;
  min-height: 0;
}

.active-workspace__header {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  justify-content: space-between;
  padding-bottom: 12px;
  border-bottom: 1px solid hsl(var(--divider-faint) / 58%);
}

.active-workspace__summary h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: hsl(var(--text-strong));
}

.active-workspace__summary p,
.active-workspace__state {
  margin: 6px 0 0;
  font-size: 13px;
  line-height: 1.6;
  color: hsl(var(--text-muted));
}

.active-workspace__filters {
  display: grid;
  grid-template-columns: minmax(220px, 1.6fr) repeat(2, minmax(0, 1fr)) auto;
  gap: 12px;
}

.active-workspace__batch-bar {
  display: flex;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px;
  background: hsl(var(--surface-contrast-soft) / 68%);
  border: 1px solid hsl(var(--divider-faint) / 58%);
  border-radius: 12px;
}

.active-workspace__batch-bar span {
  font-size: 13px;
  color: hsl(var(--text-muted));
}

.active-workspace__batch-actions {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 8px;
}

.active-workspace__batch-actions .is-danger,
.active-workspace__actions .is-danger {
  color: hsl(var(--destructive));
}

.active-workspace__state {
  padding: 14px 0;
}

.active-workspace__state.is-error {
  color: hsl(var(--destructive));
}

.active-workspace__empty {
  display: flex;
  flex: 1;
}

.active-workspace__empty :deep(.el-empty) {
  margin: auto;
}

.active-workspace__table {
  flex: 1;
}

.active-workspace__name-cell {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.active-workspace__name-with-logo {
  display: flex;
  gap: 10px;
  align-items: center;
}

.active-workspace__name-cell strong {
  font-size: 14px;
  font-weight: 600;
  color: hsl(var(--text-strong));
}

.active-workspace__name-cell span {
  font-size: 12px;
  color: hsl(var(--text-muted));
}

.active-workspace__ability {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}

.active-workspace__actions {
  display: inline-flex;
  gap: 4px;
  align-items: center;
}

.active-workspace__verify-btn.is-idle {
  color: hsl(var(--text-muted));
}

.active-workspace__verify-btn.is-loading {
  color: hsl(var(--primary));
}

.active-workspace__verify-btn.is-success {
  color: hsl(var(--success));
}

.active-workspace__verify-btn.is-warning {
  color: hsl(var(--warning));
}

.active-workspace__verify-btn.is-error {
  color: hsl(var(--destructive));
}

.active-workspace__verify-icon {
  transition:
    color 0.24s ease,
    transform 0.24s ease;
}

.active-workspace__verify-icon.is-loading {
  animation: active-workspace-verify-spin 0.9s linear infinite;
}

.active-workspace__verify-icon.is-success,
.active-workspace__verify-icon.is-warning,
.active-workspace__verify-icon.is-error {
  animation: active-workspace-verify-pop 0.32s ease;
}

@keyframes active-workspace-verify-spin {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

@keyframes active-workspace-verify-pop {
  0% {
    opacity: 0.72;
    transform: scale(0.82);
  }

  100% {
    opacity: 1;
    transform: scale(1);
  }
}

@media (max-width: 1024px) {
  .active-workspace__filters {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 768px) {
  .active-workspace__header {
    flex-direction: column;
  }

  .active-workspace__filters {
    grid-template-columns: minmax(0, 1fr);
  }

  .active-workspace__batch-bar {
    flex-direction: column;
    align-items: flex-start;
  }
}
</style>
