<script lang="ts" setup>
import type { VxeGridProps, VxeGridListeners } from '#/adapter/vxe-table';
import { Button, notification, Image, Popover } from 'ant-design-vue';
import { Page } from '@vben/common-ui';
import { getLanguageList, saveLanguageList, deleteLanguageItem } from '#/api/core/statistics';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import addLanguage from './addLanguage.vue';
import type { VbenFormProps } from '#/adapter/form';
import type { languageType, languageRecord } from '#/model/type';
import type { languageParam } from '#/api/core/statistics';
import { useVbenModal } from '@vben/common-ui';
import { $t } from '#/locales'
import dayjs from 'dayjs';
import { AccessControl } from '@vben/access';
import { useAccess } from '@vben/access';
import GlossaryData from '#/store/glossary.json';
const { hasAccessByRoles } = useAccess();
const [AddLanguageModal, AddLanguageModalApi] = useVbenModal({
  connectedComponent: addLanguage,
});
let oldData: languageType[] = [];
let newData: languageType[] = [];
let op: languageRecord[] = [];
let lastOp: languageRecord[] = [];
let lastUpdate: string = '';
let columnStr: string = "";
let keyVisible: boolean = true;
let en_USVisible: boolean = true;
let chineseVisible: boolean = true;
let pt_BRVisible: boolean = true;
let actionVisible: boolean = true;
let es_LATAMVisible: boolean = true;
let total: languageType = {
  Id: 1,
  key: '',
  en_US: '',
  zh_CN: '',
  pt_BR: '',
  es_LATAM: '',
};
const startDate = dayjs().subtract(7, 'day').startOf('day');
const endDate = dayjs().endOf('day');
const formOptions: VbenFormProps = {
  // 默认展开
  collapsed: false,
  schema: [
    {
      component: 'Select',
      componentProps: {
        filterOption: true,
        options: [
          { label: 'key', value: 'key' },
          { label: 'en_US', value: 'en_US' },
          { label: 'zh_CN', value: 'zh_CN' },
          { label: 'pt_BR', value: 'pt_BR' },
          { label: 'es_LATAM', value: 'es_LATAM' },
        ],
        placeholder: 'key',
        showSearch: true,
      },
      fieldName: 'SearchField',
      label: $t('page.common.searchField') + '：',
    },
    {
      component: 'Input',
      componentProps: {
        filterOption: true,
        placeholder: 'Merge',
        showSearch: true,
      },
      fieldName: 'SearchValue',
      label: $t('page.common.value') + '：',
    },
    {
      component: 'DatePicker',
      defaultValue: startDate,
      componentProps: {
        showTime: true,
        valueFormat: 'YYYY-MM-DD HH:mm:ss',
      },
      fieldName: 'StartTime',
      label: $t('page.common.startTime'),
      formItemClass: 'col-start-1',
    },
    {
      component: 'DatePicker',
      defaultValue: endDate,
      componentProps: {
        showTime: true,
        valueFormat: 'YYYY-MM-DD HH:mm:ss',
      },
      fieldName: 'EndTime',
      label: $t('page.common.endTime'),

    },
  ],
  // 控制表单是否显示折叠按钮
  showCollapseButton: true,
  submitButtonOptions: {
    content: $t('page.common.search'),
  },
  wrapperClass: 'grid-cols-1 md:grid-cols-5',
  // 是否在字段值改变时提交表单
  submitOnChange: false,
  // 按下回车时是否提交表单
  submitOnEnter: false,
}
const gridOptions: VxeGridProps<languageType> = {
  border: true,
  columns: [
    { title: 'Id', field: 'Id', width: 100 },
    { editRender: { name: 'input' }, field: 'key', title: 'key', filters: [{ data: "" }], filterRender: { name: "input" }, visible: keyVisible, sortBy: 'key' },
    {
      field: 'imageUrl',
      slots: { default: 'image-url' },
      title: 'Image',
      width: 60,
    },
    { editRender: { name: 'input' }, field: 'en_US', title: 'en_US', filters: [{ data: "" }], filterRender: { name: "input" }, visible: en_USVisible },
    {
      editRender: { name: 'input' },
      field: 'zh_CN',
      title: 'zh_CN', filters: [{ data: "" }], filterRender: { name: "input" }, visible: chineseVisible
    },
    { editRender: { name: 'input' }, field: 'pt_BR', title: 'pt_BR', filters: [{ data: "" }], filterRender: { name: "input" }, visible: pt_BRVisible },
    { editRender: { name: 'input' }, field: 'es_LATAM', title: 'es_LATAM', filters: [{ data: "" }], filterRender: { name: "input" }, visible: es_LATAMVisible },

    { slots: { default: 'action' }, title: $t('page.common.action'), width: 150 },
  ],
  scrollY: {
    enabled: true,
    gt: 0
  },
  toolbarConfig: {
    custom: true,
    refresh: true,
    zoom: true,
  },
  rowClassName: ({ rowIndex }: { rowIndex: number }) => {
    const i = oldData[rowIndex];
    if (!i) {
      return 'row-yellow';
    }
    const info = lastOp.find((item) => String(item.LanguageId) == String(i.Id) && item.Type === 'Add');
    if (info) {
      return 'row-yellow';
    }
  },
  cellClassName: ({ row, column }) => {
    const info = oldData.find((item) => item.Id === row.Id);
    if (info) {
      const prop = (column.field || column.field) as keyof languageType;
      const oldValue = info[prop];
      const newValue = row[prop];
      if (oldValue != newValue) {
        console.log('Cell changed2:', prop, 'from', oldValue, 'to', newValue);
        return 'row-green';
      }
      if (lastOp.find(opItem => opItem.LanguageId === row.Id && opItem.Field === prop && opItem.Type === 'Edit')) {
        return 'row-green';
      }
    }
  },
  proxyConfig: {
    response: {
      total: "total",
      result: "data"
    },
    ajax: {
      query: async ({ page }, formValues) => {
        const response = await getLanguageList({
          PageSize: page.pageSize,
          CurrentPage: page.currentPage,
          StartTime: formValues.StartTime ? Math.floor(new Date(formValues.StartTime).getTime() / 1000) : undefined,
          EndTime: formValues.EndTime ? Math.floor(new Date(formValues.EndTime).getTime() / 1000) : undefined,
          SearchField: formValues.SearchField,
          SearchValue: formValues.SearchValue,
        } as languageParam);
        newData = response.data || [];
        columnStr = response.column || "";
        if (columnStr && columnStr.length > 0) {
          const cols = columnStr.split(',');
          keyVisible = cols.includes('key');
          en_USVisible = cols.includes('en_US');
          chineseVisible = cols.includes('zh_CN');
          pt_BRVisible = cols.includes('pt_BR');

        }
        oldData = newData.map(item => ({ ...item }));
        console.log('API response:', response);
        lastOp = response.op || [];
        // 设置 lastUpdate 为 lastOp 最后一条记录的 update 字段（格式：YYYY - MM - DD HH: mm: ss）
        if (lastOp && lastOp.length > 0) {
          const last = lastOp[lastOp.length - 1];
          const raw = last?.Update;
          if (raw != null) {
            let ts: any = raw;
            // 如果是数字字符串，转为数字
            if (typeof ts === 'string' && /^\d+$/.test(ts)) ts = Number(ts);
            // 如果是 10 位时间戳（秒），转换为毫秒
            if (typeof ts === 'number' && String(ts).length === 10) ts = ts * 1000;
            lastUpdate = dayjs(ts).format('YYYY-MM-DD HH:mm:ss');
          } else {
            lastUpdate = '';
          }
        } else {
          lastUpdate = '';
        }
        // 统计 response.data 中 en_US 字段包含的单词数量（单词由字母、连字符或撇号组成，如 don't、mother-in-law）
        const en_USCount = (response.data || []).reduce((sum: number, item: languageType) => {
          const s = item?.en_US || '';
          const matches = s.match(/[A-Za-z]+(?:['-][A-Za-z]+)*/g);
          return sum + (matches ? matches.length : 0);
        }, 0);
        // 更新 total 变量和 footerData 显示
        total.en_US = String(en_USCount);
        if (gridOptions && Array.isArray(gridOptions.footerData) && gridOptions.footerData.length > 0) {
          (gridOptions.footerData[0] as any).en_US = String(en_USCount);
        }
        // 统计 zh_CN 中中文字符总数（只统计汉字）
        const countHan = (str: string) => {
          try {
            const m = str.match(/\p{Script=Han}/gu);
            return m ? m.length : 0;
          } catch (e) {
            const m = str.match(/[\u3400-\u4DBF\u4E00-\u9FFF\uF900-\uFAFF]/g);
            return m ? m.length : 0;
          }
        };

        // 统计 pt_BR 空单元格数量
        const emptyPtBRCount = (response.data || []).reduce((sum: number, item: languageType) => {
          const s = item?.pt_BR || '';
          return sum + (s.trim() === '' ? 1 : 0);
        }, 0);
        const emptyEsLATAMCount = (response.data || []).reduce((sum: number, item: languageType) => {
          const s = item?.es_LATAM || '';
          return sum + (s.trim() === '' ? 1 : 0);
        }, 0);
        const emptyZhCnCount = (response.data || []).reduce((sum: number, item: languageType) => {
          const s = item?.zh_CN || '';
          return sum + (s.trim() === '' ? 1 : 0);
        }, 0);
        const chineseCount = (response.data || []).reduce((sum: number, item: languageType) => {
          return sum + countHan(item?.zh_CN || '');
        }, 0);

        total.zh_CN = String(chineseCount);
        if (gridOptions && Array.isArray(gridOptions.footerData) && gridOptions.footerData.length > 0) {
          (gridOptions.footerData[0] as any).zh_CN = String(chineseCount);
        }
        if (hasAccessByRoles(['super', 'admin'])) {
          actionVisible = true;
        } else {
          actionVisible = false;
        }

        let length = response.data ? response.data.length : 0;
        GridApi.setGridOptions({
          columns: [
            { editRender: { name: 'input' }, field: 'key', title: 'key', filters: [{ data: "" }], filterRender: { name: "input" }, visible: keyVisible, sortBy: 'key', sortable: true, },
            {
              field: 'imageUrl',
              slots: { default: 'image-url' },
              title: 'Image',
              width: 60,
            },
            { editRender: { name: 'input' }, field: 'en_US', title: 'en_US', filters: [{ data: "" }], filterRender: { name: "input" }, visible: en_USVisible },
            {
              editRender: { name: 'input' },
              field: 'zh_CN',
              title: 'zh_CN', filters: [{ data: "" }], filterRender: { name: "input" }, visible: chineseVisible
            },
            { editRender: { name: 'input' }, field: 'pt_BR', title: 'pt_BR', filters: [{ data: "" }], filterRender: { name: "input" }, visible: pt_BRVisible },
            { editRender: { name: 'input' }, field: 'es_LATAM', title: 'es_LATAM', filters: [{ data: "" }], filterRender: { name: "input" }, visible: es_LATAMVisible },
            { slots: { default: 'glossary' }, title: 'Glossary', width: 150 },
            { slots: { default: 'action' }, title: $t('page.common.action'), width: 150, visible: actionVisible },
          ],
          pagerConfig: {
            enabled: true,
            pageSize: page.pageSize,
            pageSizes: [40, 80, 100, 200, 500, 1000, 3000, 10000],
          },
          footerData: [{
            Id: 'Word',
            key: '-',
            en_US: total.en_US,
            zh_CN: emptyZhCnCount + '/' + length + ' empty cells',
            pt_BR: emptyPtBRCount + '/' + length + ' empty cells',
            es_LATAM: emptyEsLATAMCount + '/' + length + ' empty cells',
          }],
        });
        return {
          data: newData,
          total: response.total || 0,
        };
      }
    }
  },
  keepSource: true,
  keyboardConfig: {
    isArrow: true,
    isTab: true,
    isEnter: true,
    isEdit: true,
  },
  mouseConfig: {
    selected: true,
  },
  footerData: [{
    Id: '字符数统计',
    key: '-',
    en_US: total.en_US,
    zh_CN: '',
    pt_BR: '',
  }, {
    Id: '空格数统计',
    key: 'empty',
    en_US: '',
    zh_CN: '',
    pt_BR: '',
  }],
  showFooter: true,
  editConfig: {
    mode: 'cell',
    trigger: 'dblclick',
    showStatus: true,
  },
  pagerConfig: {
    enabled: true,
    pageSizes: [40, 80, 100, 200, 500, 1000],
  },
  height: 'auto',
  showOverflow: false,
};
const gridEvents: VxeGridListeners<languageType> = {
  editClosed: ({ row, column }) => {
    const info = oldData.find((item) => item.Id === row.Id);
    if (info) {
      const prop = (column.field || column.field) as keyof languageType;
      const oldValue = info[prop];
      const newValue = row[prop];

      if (oldValue !== newValue) {
        console.log('Cell changed:', prop, 'from', oldValue, 'to', newValue);
        // 更新 newData 中的记录（若存在则替换，否则新增）
        const newItem = newData.find((item) => item.Id === row.Id);
        if (newItem) {
          op.push({
            LanguageId: row.Id,
            Field: String(prop),
            OldValue: oldValue,
            NewValue: newValue,
            Type: 'Edit',
          } as languageRecord);
          Object.assign(newItem, row);
        } else {
          newData.push({ ...(row as languageType) });
        }
        saveAll();
      } else {
        console.log('Cell not changed:', prop);
      }
    }
    //console.log('editClosed:', row, column);
  },
};
const [Grid, GridApi] = useVbenVxeGrid({ formOptions, gridOptions, gridEvents });

function addRow() {
  AddLanguageModalApi.open();
  AddLanguageModalApi.setState({
    title: $t('page.language.newLineContent'),
  });
}
function saveAll() {
  if (op.length === 0) {
    notification.info({
      duration: 10,
      message: $t('page.language.noChangesToSave'),
    });
    return;
  }
  saveLanguageList(op).then((response) => {
    console.log('Save response:', response);
    op = [];
    // GridApi.reload();
  });
}


function deleteRow(row: languageType) {
  deleteLanguageItem({ key: row.key }).then((response) => {
    const code = response.code || 0;
    const msg = response.msg || '';
    if (code !== 0) {
      notification.error({
        duration: 10,
        message: msg,
      });
      return;
    }
    notification.success({
      duration: 10,
      message: $t('page.language.deleteSuccess'),
    });
    GridApi.reload();
  });
}

function getGlossary(row: languageType) {
  const glossaryItems: string[] = [];
  let head = 'en';
  if (chineseVisible) {
    head += ' | zh';
  }
  if (pt_BRVisible) {
    head += ' | pt';
  }
  if (es_LATAMVisible) {
    head += ' | es';
  }

  Object.entries(GlossaryData).forEach(([key, value]: [string, any]) => {
    const inGameGlossary = value.term || '';
    if (row.en_US && new RegExp(`\\b${inGameGlossary.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, 'i').test(row.en_US)) {
      let content = `${inGameGlossary}`;
      if (chineseVisible) {
        const zhCN = value.zh_CN || '';
        content += ` | ${zhCN}`;
      }
      if (pt_BRVisible) {
        const ptBR = value.pt_BR || '';
        content += ` | ${ptBR}`;
      }
      if (es_LATAMVisible) {
        const esLATAM = value.es_LATAM || '';
        content += ` | ${esLATAM}`;
      }
      glossaryItems.push(content);
    }
  });
  if (glossaryItems.length > 0) {
    glossaryItems.unshift(head);
    return glossaryItems.join('\n');
  }
  return '';
}
</script>

<style lang="css">
.row-green {
  background-color: #0ea800;
}

.row-yellow {
  background-color: #c9bc04;
}
</style>
<template>
  <div class="min-h-screen flex flex-col">
    <Page auto-content-height>
      <AddLanguageModal width="800px" height="800px"></AddLanguageModal />
      <Grid>
        <template #toolbar-tools>
          <span class="mr-4 font-bold">{{ $t('page.language.lastUpdate') }}：{{ lastUpdate }}</span>
          <Button class="mr-2" type="primary" @click="addRow">
            {{ $t('page.common.addLine') }}
          </Button>
          <Button type="primary" @click="saveAll" class="mr-2"> {{ $t('page.common.save') }} </Button>
          <!-- <Button type="primary" @click="exportLang"> {{ $t('page.common.gitCommit') }} </Button> -->
        </template>
        <template #image-url="{ row }">
          <!-- <Image src="./public/merge/Launcher_A_LV1.png" height="50" width="50" /> -->
          <Image v-if="row.url" :src="row.url" height="40" width="40" />
        </template>
        <template #glossary="{ row }">
          <span style="font-size: 11px;">{{ getGlossary(row) }} </span>
        </template>
        <template #action="{ row }">
          <AccessControl :codes="['super', 'admin']" type="role">
            <Button type="primary" @click="deleteRow(row)">删除</Button>
          </AccessControl>
        </template>
      </Grid>
    </Page>
  </div>
</template>
