<script setup lang="ts">
import { computed, onMounted, ref } from 'vue';
import { useRoute } from 'vue-router';

import { IconifyIcon } from '@easyflow/icons';

import { ArrowLeft } from '@element-plus/icons-vue';
import {
  ElButton,
  ElDescriptions,
  ElDescriptionsItem,
  ElEmpty,
  ElMessage,
  ElMessageBox,
  ElTable,
  ElTableColumn,
  ElTag,
} from 'element-plus';

import { api } from '#/api/request';
import { $t } from '#/locales';
import { router } from '#/router';
import BotApprovalSnapshotPreview from '#/views/system/approval/components/BotApprovalSnapshotPreview.vue';
import KnowledgeApprovalSnapshotPreview from '#/views/system/approval/components/KnowledgeApprovalSnapshotPreview.vue';
import WorkflowApprovalSnapshotPreview from '#/views/system/approval/components/WorkflowApprovalSnapshotPreview.vue';

const route = useRoute();
const loading = ref(false);
const detail = ref<any>(null);

const resourceLabelMap: Record<string, string> = {
  BOT: $t('approval.resource.bot'),
  KNOWLEDGE: $t('approval.resource.knowledge'),
  WORKFLOW: $t('approval.resource.workflow'),
};

const actionLabelMap: Record<string, string> = {
  DELETE: $t('approval.action.delete'),
  OFFLINE: $t('approval.action.offline'),
  PUBLISH: $t('approval.action.publish'),
};

const canOperate = computed(() => {
  return (
    !!detail.value?.canApprove ||
    !!detail.value?.canReject ||
    !!detail.value?.canRevoke
  );
});

const workflowSnapshot = computed(() => {
  if (detail.value?.resourceType !== 'WORKFLOW') {
    return null;
  }
  const snapshot = detail.value?.snapshotJson?.resourceSnapshot;
  return {
    title: snapshot?.title || '',
    description: snapshot?.description || '',
    content: snapshot?.content || '',
  };
});

const knowledgeSnapshot = computed(() => {
  if (detail.value?.resourceType !== 'KNOWLEDGE') {
    return null;
  }
  return detail.value?.snapshotJson?.resourceSnapshot || null;
});

const botSnapshot = computed(() => {
  if (detail.value?.resourceType !== 'BOT') {
    return null;
  }
  return detail.value?.snapshotJson?.resourceSnapshot || null;
});

onMounted(() => {
  void loadDetail();
});

async function loadDetail() {
  loading.value = true;
  try {
    const res = await api.get('/api/v1/approvalInstance/detail', {
      params: {
        id: route.params.id,
      },
    });
    if (res.errorCode !== 0) {
      return;
    }
    detail.value = res.data;
  } finally {
    loading.value = false;
  }
}

async function submitApprovalAction(action: 'approve' | 'reject' | 'revoke') {
  const titleMap = {
    approve: $t('approval.action.approve'),
    reject: $t('approval.action.reject'),
    revoke: $t('approval.action.revoke'),
  };
  const { value } = await ElMessageBox.prompt(
    $t('approval.placeholder.actionComment'),
    titleMap[action],
    {
      inputValue: '',
      inputType: 'textarea',
    },
  );
  const res = await api.post(`/api/v1/approvalInstance/${action}`, {
    comment: value || '',
    instanceId: detail.value?.id,
  });
  if (res.errorCode !== 0) {
    return;
  }
  ElMessage.success($t('approval.message.actionSuccess'));
  await loadDetail();
}

function getStatusType(status: string) {
  const map: Record<string, any> = {
    APPROVED: 'success',
    PENDING: 'warning',
    PROCESSING: 'primary',
    REJECTED: 'danger',
    REVOKED: 'info',
  };
  return map[status] || 'info';
}

function getStatusLabel(status: string) {
  return $t(`approval.status.${String(status || '').toLowerCase()}`);
}

function formatPayload(payload: Record<string, any>) {
  return JSON.stringify(payload || {}, null, 2);
}

function formatAccountDisplay(
  name?: string,
  account?: null | string,
  fallbackId?: null | number | string,
) {
  if (name && account) {
    return `${name}（${account}）`;
  }
  if (name) {
    return name;
  }
  if (account) {
    return account;
  }
  return fallbackId || '-';
}

function formatOperatorId(
  account?: null | string,
  fallbackId?: null | number | string,
) {
  return account || fallbackId || '-';
}

function formatOperatorName(name?: null | string) {
  return name || '-';
}

function formatAssigneeDisplay(row: Record<string, any>) {
  if (!row?.assigneeType || !row?.assigneeTargetName) {
    return '-';
  }
  if (row.assigneeType === 'ROLE') {
    return `${$t('approval.assignee.role')}：${row.assigneeTargetName}`;
  }
  return `${$t('approval.assignee.user')}：${row.assigneeTargetName}`;
}

function getEventTypeLabel(eventType?: string) {
  const eventTypeMap: Record<string, string> = {
    APPROVED: $t('approval.event.approved'),
    REJECTED: $t('approval.event.rejected'),
    REVOKED: $t('approval.event.revoked'),
    STEP_CREATED: $t('approval.event.stepCreated'),
    SUBMITTED: $t('approval.event.submitted'),
  };
  return eventTypeMap[String(eventType || '')] || eventType || '-';
}

function formatEventInfo(row: Record<string, any>) {
  const payload = row?.payloadJson || {};
  const eventType = String(row?.eventType || '');

  switch (eventType) {
    case 'APPROVED': {
      return payload.stepNo
        ? $t('approval.message.eventApprovedStep', { value: payload.stepNo })
        : $t('approval.message.eventApproved');
    }
    case 'REJECTED': {
      return payload.stepNo
        ? $t('approval.message.eventRejectedStep', { value: payload.stepNo })
        : $t('approval.message.eventRejected');
    }
    case 'REVOKED': {
      return payload.stepNo
        ? $t('approval.message.eventRevokedStep', { value: payload.stepNo })
        : $t('approval.message.eventRevoked');
    }
    case 'STEP_CREATED': {
      return payload.stepName || '-';
    }
    case 'SUBMITTED': {
      return payload.summary || detail.value?.summary || '-';
    }
    default: {
      return payload.stepName || payload.summary || row?.eventType || '-';
    }
  }
}
</script>

<template>
  <div class="flex h-full flex-col gap-4 p-6" v-loading="loading">
    <div class="flex flex-wrap items-center justify-between gap-3">
      <div class="flex items-center gap-3">
        <ElButton :icon="ArrowLeft" @click="router.back()">
          {{ $t('button.back') }}
        </ElButton>
        <div class="flex items-center gap-2 text-lg font-semibold">
          <IconifyIcon icon="svg:approval" class="size-5" />
          <span>{{ $t('approval.title') }}</span>
        </div>
      </div>

      <div v-if="canOperate" class="flex items-center gap-3">
        <ElButton
          v-if="detail?.canApprove"
          type="success"
          @click="submitApprovalAction('approve')"
        >
          {{ $t('approval.action.approve') }}
        </ElButton>
        <ElButton
          v-if="detail?.canReject"
          type="danger"
          @click="submitApprovalAction('reject')"
        >
          {{ $t('approval.action.reject') }}
        </ElButton>
        <ElButton
          v-if="detail?.canRevoke"
          @click="submitApprovalAction('revoke')"
        >
          {{ $t('approval.action.revoke') }}
        </ElButton>
      </div>
    </div>

    <template v-if="detail">
      <section class="approval-detail__panel">
        <div class="approval-detail__panel-header">
          <h3>{{ $t('approval.section.basic') }}</h3>
          <ElTag :type="getStatusType(detail.status)">
            {{ getStatusLabel(detail.status) }}
          </ElTag>
        </div>
        <ElDescriptions :column="2" border>
          <ElDescriptionsItem :label="$t('approval.fields.summary')">
            {{ detail.summary || '-' }}
          </ElDescriptionsItem>
          <ElDescriptionsItem :label="$t('approval.fields.currentStep')">
            {{ detail.currentStepNo || '-' }}
          </ElDescriptionsItem>
          <ElDescriptionsItem :label="$t('approval.fields.resourceType')">
            {{
              resourceLabelMap[detail.resourceType] ||
              detail.resourceType ||
              '-'
            }}
          </ElDescriptionsItem>
          <ElDescriptionsItem :label="$t('approval.fields.actionType')">
            {{ actionLabelMap[detail.actionType] || detail.actionType || '-' }}
          </ElDescriptionsItem>
          <ElDescriptionsItem :label="$t('approval.fields.taskId')">
            {{ detail.id || '-' }}
          </ElDescriptionsItem>
          <ElDescriptionsItem :label="$t('approval.fields.applicant')">
            {{
              formatAccountDisplay(
                detail.applicantName,
                detail.applicantAccount,
                detail.applicantId,
              )
            }}
          </ElDescriptionsItem>
          <ElDescriptionsItem :label="$t('approval.fields.submittedAt')">
            {{ detail.submittedAt || '-' }}
          </ElDescriptionsItem>
          <ElDescriptionsItem :label="$t('approval.fields.finishedAt')">
            {{ detail.finishedAt || '-' }}
          </ElDescriptionsItem>
        </ElDescriptions>
      </section>

      <section class="approval-detail__panel">
        <div class="approval-detail__panel-header">
          <h3>{{ $t('approval.section.tasks') }}</h3>
        </div>
        <ElTable :data="detail.tasks || []" show-overflow-tooltip>
          <ElTableColumn
            prop="stepNo"
            :label="$t('approval.fields.stepNoLabel')"
            width="100"
          />
          <ElTableColumn
            prop="stepName"
            :label="$t('approval.fields.stepName')"
            min-width="180"
          />
          <ElTableColumn :label="$t('approval.fields.status')" width="120">
            <template #default="{ row }">
              <ElTag :type="getStatusType(row.status)">
                {{ getStatusLabel(row.status) }}
              </ElTag>
            </template>
          </ElTableColumn>
          <ElTableColumn
            :label="$t('approval.fields.assigneeTarget')"
            width="220"
          >
            <template #default="{ row }">
              {{ formatAssigneeDisplay(row) }}
            </template>
          </ElTableColumn>
          <ElTableColumn :label="$t('approval.fields.actedBy')" width="180">
            <template #default="{ row }">
              {{ formatAccountDisplay(row.actedByName, row.actedBy) }}
            </template>
          </ElTableColumn>
          <ElTableColumn
            prop="actedAt"
            :label="$t('approval.fields.actedAt')"
            width="180"
          />
          <ElTableColumn
            prop="comment"
            :label="$t('approval.fields.comment')"
            min-width="200"
          />
        </ElTable>
      </section>

      <section class="approval-detail__panel">
        <div class="approval-detail__panel-header">
          <h3>{{ $t('approval.section.logs') }}</h3>
        </div>
        <ElTable :data="detail.logs || []" show-overflow-tooltip>
          <ElTableColumn :label="$t('approval.fields.eventType')" width="160">
            <template #default="{ row }">
              {{ getEventTypeLabel(row.eventType) }}
            </template>
          </ElTableColumn>
          <ElTableColumn :label="$t('approval.fields.operatorId')" width="140">
            <template #default="{ row }">
              {{ formatOperatorId(row.operatorAccount, row.operatorId) }}
            </template>
          </ElTableColumn>
          <ElTableColumn
            :label="$t('approval.fields.operatorName')"
            width="180"
          >
            <template #default="{ row }">
              {{ formatOperatorName(row.operatorName) }}
            </template>
          </ElTableColumn>
          <ElTableColumn
            prop="created"
            :label="$t('approval.fields.createdAt')"
            width="180"
          />
          <ElTableColumn
            :label="$t('approval.fields.eventInfo')"
            min-width="280"
          >
            <template #default="{ row }">
              <div class="approval-detail__event-info">
                {{ formatEventInfo(row) }}
              </div>
            </template>
          </ElTableColumn>
        </ElTable>
      </section>

      <section class="approval-detail__panel">
        <div class="approval-detail__panel-header">
          <h3>{{ $t('approval.section.snapshot') }}</h3>
        </div>
        <WorkflowApprovalSnapshotPreview
          v-if="workflowSnapshot"
          :title="workflowSnapshot.title"
          :description="workflowSnapshot.description"
          :content="workflowSnapshot.content"
        />
        <KnowledgeApprovalSnapshotPreview
          v-else-if="knowledgeSnapshot"
          :snapshot="knowledgeSnapshot"
        />
        <BotApprovalSnapshotPreview
          v-else-if="botSnapshot"
          :snapshot="botSnapshot"
        />
        <pre v-else class="approval-detail__snapshot">{{
          formatPayload(detail.snapshotJson)
        }}</pre>
      </section>
    </template>

    <ElEmpty v-else />
  </div>
</template>

<style scoped>
.approval-detail__panel {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 20px;
  background: linear-gradient(
    180deg,
    hsl(var(--glass-border) / 72%) 0%,
    hsl(var(--surface-panel) / 95%) 100%
  );
  border: 1px solid hsl(var(--divider-faint) / 50%);
  border-radius: 24px;
  box-shadow:
    inset 0 1px 0 hsl(var(--glass-border) / 72%),
    0 18px 36px -32px hsl(var(--primary) / 20%);
}

.approval-detail__panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.approval-detail__panel-header h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
}

.approval-detail__snapshot,
.approval-detail__payload {
  margin: 0;
  white-space: pre-wrap;
  word-break: break-all;
  padding: 14px 16px;
  background: hsl(var(--surface-contrast-soft) / 0.9);
  border: 1px solid hsl(var(--divider-faint) / 0.54);
  border-radius: 16px;
  font-size: 12px;
  line-height: 1.6;
}

.approval-detail__event-info {
  line-height: 1.6;
  color: hsl(var(--foreground));
}
</style>
