<script setup lang="ts">
import type { FormInstance } from 'element-plus';

import { ref } from 'vue';
import { useRoute } from 'vue-router';

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

import { MoreFilled, View } from '@element-plus/icons-vue';
import {
  ElButton,
  ElDropdown,
  ElDropdownItem,
  ElDropdownMenu,
  ElForm,
  ElFormItem,
  ElIcon,
  ElInput,
  ElSelect,
  ElTable,
  ElTableColumn,
  ElTag,
} from 'element-plus';
import { tryit } from 'radash';

import { api } from '#/api/request';
import DictSelect from '#/components/dict/DictSelect.vue';
import ListPageShell from '#/components/page/ListPageShell.vue';
import PageData from '#/components/page/PageData.vue';
import {
  buildListRouteFullPath,
  mergeListRouteStateQuery,
  parseListRouteState,
  watchListRouteState,
} from '#/composables/useListRouteState';
import { $t } from '#/locales';
import { router } from '#/router';
import { withListReturnTo } from '#/router/list-return-context';

import { sysFeedbackListRouteSchema } from './sys-feedback-list-route-state';

const route = useRoute();
const initialListState = parseListRouteState(
  route.query,
  sysFeedbackListRouteSchema,
);

const feedbackTypeOptions = [
  {
    value: 1,
    label: $t('sysFeedback.functionalFailure'),
  },
  {
    value: 2,
    label: $t('sysFeedback.optimizationSuggestions'),
  },
  {
    value: 3,
    label: $t('sysFeedback.accountIssue'),
  },
  {
    value: 4,
    label: $t('sysFeedback.other'),
  },
];
const statusType: Record<number, any> = {
  0: {
    label: $t('sysFeedback.notViewed'),
    type: 'warning',
  },
  1: {
    label: $t('sysFeedback.viewed'),
    type: 'primary',
  },
  2: {
    label: $t('sysFeedback.processed'),
    type: 'success',
  },
  3: {
    label: $t('sysFeedback.closed/Invalid'),
    type: 'info',
  },
};

const formRef = ref<FormInstance>();
const formData = ref({
  feedbackType: initialListState.feedbackType
    ? Number(initialListState.feedbackType)
    : '',
  status: initialListState.status,
  feedbackContent: initialListState.feedbackContent,
});
const appliedFormData = ref({ ...formData.value });
const pageDataRef = ref();
const currentPageNumber = ref(initialListState.pageNumber);
const currentPageSize = ref(initialListState.pageSize);
watchListRouteState(route, sysFeedbackListRouteSchema, (state) => {
  const nextFormData = {
    feedbackContent: state.feedbackContent,
    feedbackType: state.feedbackType ? Number(state.feedbackType) : '',
    status: state.status,
  };
  formData.value = { ...nextFormData };
  appliedFormData.value = { ...nextFormData };
  currentPageNumber.value = state.pageNumber;
  currentPageSize.value = state.pageSize;
  pageDataRef.value?.restoreState?.({
    pageNumber: state.pageNumber,
    pageSize: state.pageSize,
    queryParams: {
      keyword: state.feedbackContent || undefined,
      feedbackType: state.feedbackType || undefined,
      status: state.status || undefined,
    },
  });
});

function search(formEl?: FormInstance) {
  formEl?.validate((valid) => {
    if (valid) {
      appliedFormData.value = { ...formData.value };
      pageDataRef.value.setQuery({
        feedbackType: appliedFormData.value.feedbackType || undefined,
        keyword: appliedFormData.value.feedbackContent.trim() || undefined,
        status: appliedFormData.value.status || undefined,
      });
    }
  });
}
function reset(formEl?: FormInstance) {
  formData.value = { feedbackContent: '', feedbackType: '', status: '' };
  appliedFormData.value = { ...formData.value };
  formEl?.clearValidate();
  pageDataRef.value.setQuery({});
}
function getFeedbackType(type: number) {
  const option = feedbackTypeOptions.find((option) => option.value === type);
  return option?.label;
}
async function markStatus(row: any, status: number) {
  const [, res] = await tryit(api.post)('/api/v1/sysUserFeedback/update', {
    ...row,
    status,
  });

  if (res && res.errorCode === 0) {
    pageDataRef.value.reload();
  }
}
function currentListState(
  pageNumber = currentPageNumber.value,
  pageSize = currentPageSize.value,
) {
  return {
    feedbackContent: appliedFormData.value.feedbackContent,
    feedbackType: String(appliedFormData.value.feedbackType || '') as
      | '1'
      | '2'
      | '3'
      | '4'
      | '',
    pageNumber,
    pageSize,
    status: String(appliedFormData.value.status || '') as
      | '0'
      | '1'
      | '2'
      | '3'
      | '',
  };
}
function currentListFullPath() {
  return buildListRouteFullPath(
    router,
    route.query,
    currentListState(),
    sysFeedbackListRouteSchema,
  );
}
function handlePageStateChange(state: {
  pageNumber: number;
  pageSize: number;
}) {
  currentPageNumber.value = state.pageNumber;
  currentPageSize.value = state.pageSize;
  const query = mergeListRouteStateQuery(
    route.query,
    currentListState(state.pageNumber, state.pageSize),
    sysFeedbackListRouteSchema,
  );
  const target = router.resolve({
    path: sysFeedbackListRouteSchema.path,
    query,
  });
  if (target.fullPath !== route.fullPath) void router.replace(target);
}
function openFeedbackDetail(row: any) {
  router.push({
    path: `/sys/sysFeedback/${row.id}`,
    query: withListReturnTo(currentListFullPath()),
  });
}
</script>

<template>
  <div class="flex h-full flex-col gap-1.5 p-6">
    <ListPageShell>
      <template #filters>
        <ElForm ref="formRef" inline :model="formData">
          <ElFormItem prop="feedbackType" class="!mr-3">
            <ElSelect
              v-model="formData.feedbackType"
              :options="feedbackTypeOptions"
              :placeholder="$t('sysFeedback.feedbackType')"
              clearable
              filterable
              immediate
            />
          </ElFormItem>
          <ElFormItem prop="status" class="!mr-3">
            <DictSelect
              v-model="formData.status"
              dict-code="feedbackType"
              :placeholder="$t('sysFeedback.processingStatus')"
            />
          </ElFormItem>
          <ElFormItem prop="feedbackContent" class="!mr-3">
            <ElInput
              v-model="formData.feedbackContent"
              :placeholder="$t('common.searchPlaceholder')"
            />
          </ElFormItem>
          <ElFormItem>
            <ElButton @click="search(formRef)" type="primary">
              {{ $t('button.query') }}
            </ElButton>
            <ElButton @click="reset(formRef)">
              {{ $t('button.reset') }}
            </ElButton>
          </ElFormItem>
        </ElForm>
      </template>
      <PageData
        ref="pageDataRef"
        page-url="/api/v1/sysUserFeedback/page"
        :page-size="initialListState.pageSize"
        :initial-page-number="initialListState.pageNumber"
        :initial-query-params="{
          keyword: initialListState.feedbackContent || undefined,
          feedbackType: initialListState.feedbackType || undefined,
          status: initialListState.status || undefined,
        }"
        @state-change="handlePageStateChange"
      >
        <template #default="{ pageList }">
          <ElTable border show-overflow-tooltip :data="pageList">
            <ElTableColumn prop="id" label="ID">
              <template #default="{ row }">
                {{ row.id }}
              </template>
            </ElTableColumn>
            <ElTableColumn
              prop="feedbackType"
              :label="$t('sysFeedback.category')"
            >
              <template #default="{ row }">
                {{ getFeedbackType(row.feedbackType) }}
              </template>
            </ElTableColumn>
            <ElTableColumn
              prop="feedbackContent"
              :label="$t('sysFeedback.description')"
            >
              <template #default="{ row }">
                {{ row.feedbackContent }}
              </template>
            </ElTableColumn>
            <ElTableColumn
              prop="contactInfo"
              :label="$t('sysFeedback.contactInformation')"
            >
              <template #default="{ row }">
                {{ row.contactInfo }}
              </template>
            </ElTableColumn>
            <ElTableColumn
              prop="created"
              :label="$t('sysFeedback.submittedAt')"
            >
              <template #default="{ row }">
                {{ row.created }}
              </template>
            </ElTableColumn>
            <ElTableColumn
              prop="status"
              :label="$t('sysFeedback.processingStatus')"
            >
              <template #default="{ row }">
                <ElTag :type="statusType[(row.status as number) ?? 0].type">
                  {{ statusType[row.status ?? 0].label }}
                </ElTag>
              </template>
            </ElTableColumn>
            <ElTableColumn
              :label="$t('common.handle')"
              width="90"
              align="right"
            >
              <template #default="{ row }">
                <div class="flex items-center gap-3">
                  <ElButton
                    link
                    type="primary"
                    @click="openFeedbackDetail(row)"
                  >
                    {{ $t('button.view') }}
                  </ElButton>

                  <ElDropdown>
                    <ElButton link :icon="MoreFilled" />

                    <template #dropdown>
                      <ElDropdownMenu>
                        <ElDropdownItem
                          :icon="View"
                          :disabled="(row.status ?? 0) >= 1"
                          @click="markStatus(row, 1)"
                        >
                          {{ $t('button.markAsRead') }}
                        </ElDropdownItem>
                        <ElDropdownItem
                          :disabled="(row.status ?? 0) >= 2"
                          @click="markStatus(row, 2)"
                        >
                          <ElIcon>
                            <IconifyIcon icon="svg:resolved" />
                          </ElIcon>
                          {{ $t('button.markAsResolved') }}
                        </ElDropdownItem>
                      </ElDropdownMenu>
                    </template>
                  </ElDropdown>
                </div>
              </template>
            </ElTableColumn>
          </ElTable>
        </template>
      </PageData>
    </ListPageShell>
  </div>
</template>
