<script lang="ts" setup>
/**
 * @Name: DataEntryTable.vue
 * @Description: 数据录入
 * @Author: xinyan
 */
import { computed, onMounted, reactive, ref } from 'vue';
import { VxeGridInstance, VXETable } from 'vxe-table';
import dayjs from 'dayjs';
import isoWeek from 'dayjs/plugin/isoWeek';
import { useRoute } from 'vue-router';
import {
  getDayBeforeData,
  getDayTaskData,
  getMonthBeforeData,
  getMonthTaskData,
  getWeekBeforeData,
  getWeekTaskData,
  postUpdateDayData,
  postUpdateMonthData,
  postUpdateWeekData
} from '/src/views/reportManage/dataCenter/api';
import enLocale from 'element-plus/es/locale/lang/en';
import Selector from '/@/views/reportManage/dataCenter/normalDisplay/components/Selector/index.vue';
import CreateDialog from '/src/views/reportManage/dataCenter/normalDisplay/components/DataEntryTable/components/CreateDialog.vue';
import { validateNumericFields } from '/@/views/reportManage/dataCenter/utils/tools';
import TipDialog from '/src/views/reportManage/dataCenter/normalDisplay/components/DataEntryTable/components/TipDialog.vue';
import { dayColumns, monthColumns, weekColumns } from '/@/views/reportManage/dataCenter/utils/columns';


dayjs.extend(isoWeek);

const route = useRoute();
const dateType = <string>route.query.dateType;

// 筛选查询
const selectorRef = ref(null);
const taskIds = ref({});

//日期选择
const dailySalesTime = ref(dayjs().subtract(1, 'day').format('YYYY-MM-DD'));

const weeklyEntryTime = ref(null);
const weeklyAdTime = ref(null);
let initialLoad = true;

const entryStartDate = ref('');
const entryEndDate = ref('');
const adStartDate = ref('');
const adEndDate = ref('');

const monthlyEntryTime = ref(null);
const startDate = ref(null);
const endDate = ref(null);
const shortcuts = [
  {
    text: '今天',
    value: new Date(),
  },
  {
    text: '昨天',
    value: () => {
      const date = new Date();
      date.setTime(date.getTime() - 3600 * 1000 * 24);
      return date;
    },
  },
  {
    text: '最近七天',
    value: () => {
      const date = new Date();
      date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
      return date;
    },
  },
];

const yDayDate = ref(null);
const yWeekDay = ref(null);
const yMonthDay = ref(null);

function handleDayChange(value) {
  dailySalesTime.value = dayjs(value).format('YYYY-MM-DD');
  yDayDate.value = dayjs(dailySalesTime.value).subtract(1, 'day').format('YYYY-MM-DD');
  fetchCurrentTaskData();
}

const handleWeekChange = () => {
  if (weeklyEntryTime.value) {
    entryStartDate.value = dayjs(weeklyEntryTime.value).locale('en').startOf('week').format('YYYY-MM-DD');
    entryEndDate.value = dayjs(weeklyEntryTime.value).locale('en').endOf('week').format('YYYY-MM-DD');
    const adDate = dayjs(weeklyEntryTime.value).locale('en').subtract(7, 'day');
    weeklyAdTime.value = adDate.format('YYYY-WW');
    adStartDate.value = adDate.startOf('week').format('YYYY-MM-DD');
    adEndDate.value = adDate.endOf('week').format('YYYY-MM-DD');
    yWeekDay.value = dayjs(entryEndDate.value).locale('en').endOf('week').subtract(1, 'week').format('YYYY-MM-DD');
  }
  if (initialLoad) {
    initialLoad = false; // 只在初次加载时避免多次调用
  } else {
    fetchCurrentTaskData();
  }
};

const handleMonthChange = (value) => {
  if (value) {
    const date = new Date(value);
    const year = date.getFullYear();
    const month = date.getMonth() + 1; // getMonth() 返回值为 0-11，需要加 1
    const lastDay = new Date(year, month, 0).getDate();
    startDate.value = `${ year }-${ String(month).padStart(2, '0') }-01`;
    endDate.value = `${ year }-${ String(month).padStart(2, '0') }-${ lastDay }`;
    yMonthDay.value = dayjs(endDate.value).subtract(1, 'month').endOf('month').format('YYYY-MM-DD');
    fetchCurrentTaskData();
  } else {
    startDate.value = null;
    endDate.value = null;
  }
};

const entryFormat = computed(() => `${ entryStartDate.value } to ${ entryEndDate.value }`);
const adFormat = computed(() => `${ adStartDate.value } to ${ adEndDate.value }`);
const monthlyEntryFormat = computed(() => `${ startDate.value } to ${ endDate.value }`);

const disabledDate = (time: Date) => {
  return time.getTime() > Date.now();
};

function setDefaultDate() {
  switch (dateType) {
    case 'day':
      dailySalesTime.value = dayjs().subtract(1, 'day').format('YYYY-MM-DD');
      yDayDate.value = dayjs(dailySalesTime.value).subtract(1, 'day').format('YYYY-MM-DD');
      break;
    case 'week':
      weeklyEntryTime.value = dayjs().locale('en').subtract(1, 'week').startOf('week').format('YYYY-MM-DD');
      handleWeekChange();
      break;
    case 'month':
      monthlyEntryTime.value = dayjs().subtract(1, 'month').format('YYYY-MM-DD');
      startDate.value = dayjs(monthlyEntryTime.value).startOf('month').format('YYYY-MM-DD');
      endDate.value = dayjs(monthlyEntryTime.value).endOf('month').format('YYYY-MM-DD');
      yMonthDay.value = dayjs(endDate.value).subtract(1, 'month').endOf('month').format('YYYY-MM-DD');
  }
}

const currentDate = ref({});

const createOpen = ref(false);
const openTip = ref(false);
const isROI = ref(false);

const ySalesData = ref({
  sales_original: '',
  total_sales_current_monthly_original: '',
});

//表格
const currentRow = ref({});
let dateParams;

const dayData = [];
const weekData = [];
const monthData = [];

interface RowVO {
  id: number;
  task: number;
  // ad_cost: number;
  sales_original: number,
  ad_sales_original: number,
  ad_cost_original: number,
  total_sales_current_monthly_original: number;
  impression: number;
  ad_click: number;
  ad_order: number;
  money_by_amazon: number;
  money_by_other: number;
  session: string;
  order: string;
  availableSalesDay: number;
  intransitInventory: number;
  overseasStorage: number;
  refundRate: number;
  currencyCodePlatform: string;
}

const xGrid = ref<VxeGridInstance<RowVO>>();
const originalDataMap = new Map();
const currentScrollLeft = ref(0);
const activeEditRow = ref(null);

const gridOptions = reactive({
  border: 'inner',
  height: 750,
  align: null,
  round: true,
  loading: false,
  showHeaderOverflow: true,
  //showOverflow: true,
  columnConfig: {
    resizable: true
  },
  rowConfig: {
    // isCurrent: true,
    isHover: true,
  },
  pagerConfig: {
    enabled: true,
    total: 20,
    currentPage: 1,
    pageSize: 20,
    pageSizes: [10, 20, 30],
  },
  editConfig: {
    trigger: 'manual',
    mode: 'row',
    showStatus: true,
    autoClear: false,
  },
  day: {
    columns: dayColumns,
    data: dayData
  },
  week: {
    columns: weekColumns,
    data: weekData
  },
  month: {
    columns: monthColumns,
    data: monthData
  }
});

const gridEvents = {
  pageChange({ currentPage, pageSize }) {
    if (gridOptions.pagerConfig) {
      gridOptions.pagerConfig.currentPage = currentPage;
      gridOptions.pagerConfig.pageSize = pageSize;
    }
    fetchCurrentTaskData();
  }
};

const hasActiveEditRow = (row: RowVO) => {
  const $grid = xGrid.value;
  if ($grid) {
    return $grid.isEditByRow(row);
  }
  return false;
};

const clearRowEvent = (row: RowVO) => {
  activeEditRow.value = false;
  const $grid = xGrid.value;
  if ($grid) {
    const originalData = originalDataMap.get(row.id);
    if (originalData) {
      Object.assign(row, originalData);
      originalDataMap.delete(row.id);
    }
    $grid.clearEdit();
  }
};

const handelEditRow = (row: RowVO) => {
  activeEditRow.value = true;
  const $grid = xGrid.value;
  if ($grid) {
    // 记录当前滚动条位置
    const bodyWrapper = $grid.$el.querySelector('.vxe-table--body-wrapper');
    currentScrollLeft.value = bodyWrapper.scrollLeft;
    originalDataMap.set(row.id, { ...row });
    $grid.setEditRow(row);
    // 强制恢复滚动条位置
    setTimeout(() => {
      bodyWrapper.scrollLeft = currentScrollLeft.value;
    }, 0);
  }
};

function updateDataChange(newId) {
  if (selectorRef.value) {
    if (gridOptions.pagerConfig) {
      gridOptions.pagerConfig.currentPage = 1;
    }
    taskIds.value = newId.value;
    fetchCurrentTaskData();
  }
}

// 获取表格数据
async function fetchTaskData(apiFunction) {
  try {
    gridOptions.loading = true;
    const resp = await apiFunction({
      page: gridOptions.pagerConfig.currentPage,
      limit: gridOptions.pagerConfig.pageSize,
      task_ids: taskIds.value,
      ...dateParams
    });
    gridOptions[dateType].data = resp.data;
    gridOptions.pagerConfig.total = resp.total;
  } catch (error) {
    console.error('Error fetching task data:', error);
  } finally {
    gridOptions.loading = false;
  }
}

async function fetchDayTaskData() {
  await fetchTaskData(getDayTaskData);
}

async function fetchWeekTaskData() {
  await fetchTaskData(getWeekTaskData);
}

async function fetchMonthTaskData() {
  await fetchTaskData(getMonthTaskData);
}

function fetchCurrentTaskData() {
  if (dateType === 'day') {
    dateParams = {
      day_start_date: dailySalesTime.value,
      day_end_date: dailySalesTime.value
    };
    fetchDayTaskData();
  } else if (dateType === 'week') {
    dateParams = {
      week_start_date: entryStartDate.value,
      week_end_date: entryEndDate.value
    };
    fetchWeekTaskData();
  } else if (dateType === 'month') {
    dateParams = {
      month_start_date: startDate.value,
      month_end_date: endDate.value
    };
    fetchMonthTaskData();
  }
  currentDate.value = {
    ...dateParams,
    ad_start_time: adStartDate.value,
    ad_end_time: adEndDate.value,
  };
}

const createEvent = async (row: RowVO) => {
  currentRow.value = row;
  // Object.assign(taskDataForm, row);
  await currentSalesTip();
  createOpen.value = true;
};

// 更新日数据
async function updateDayData(row: RowVO) {
  const $grid = xGrid.value;
  if ($grid) {

    const body = {
      id: row.id,
      sales_original: row.sales_original,
      ad_sales_original: row.ad_sales_original,
      ad_cost_original: row.ad_cost_original,
      data_datetime: dailySalesTime.value,
      task: row.task,
    };
    try {
      const resp = await postUpdateDayData(body);
      if (resp.code === 2000) {
        await fetchDayTaskData();
        await VXETable.modal.message({
          content: '更新成功',
          status: 'success',
        });
      }
    } catch (error) {
      console.log('error:', error);
    }
  }
}

//更新周数据
async function updateWeekData(row: RowVO) {
  const $grid = xGrid.value;
  if ($grid) {
    const body = {
      id: row.id,
      sales_original: row.sales_original,
      ad_sales_original: row.ad_sales_original,
      ad_cost_original: row.ad_cost_original,
      total_sales_current_monthly_original: row.total_sales_current_monthly_original,
      impression: row.impression,
      ad_click: row.ad_click,
      ad_order: row.ad_order,
      money_by_amazon: row.money_by_amazon,
      money_by_other: row.money_by_other,
      session: row.session,
      order: row.order,
      availableSalesDay: row.availableSalesDay,
      intransitInventory: row.intransitInventory,
      overseasStorage: row.overseasStorage,
      refundRate: row.refundRate,
      sales_start_time: entryStartDate.value,
      sales_end_time: entryEndDate.value,
      ad_start_time: adStartDate.value,
      ad_end_time: adEndDate.value,
      enter_start_datetime: entryStartDate.value,
      enter_end_datetime: entryEndDate.value,
      task: row.task,
    };
    try {
      const resp = await postUpdateWeekData(body);
      if (resp.code === 2000) {
        await fetchWeekTaskData();
        await VXETable.modal.message({
          content: '更新成功',
          status: 'success',
        });
      }
    } catch (error) {
      console.log('error:', error);
    }
  }
}

//更新月数据
async function updateMonthData(row: RowVO) {
  const $grid = xGrid.value;
  if ($grid) {
    const body = {
      id: row.id,
      sales_original: row.sales_original,
      ad_sales_original: row.ad_sales_original,
      ad_cost_original: row.ad_cost_original,
      impression: row.impression,
      ad_click: row.ad_click,
      ad_order: row.ad_order,
      data_start_time: startDate.value,
      data_end_time: endDate.value,
      enter_start_time: startDate.value,
      enter_end_time: endDate.value,
      task: row.task,
    };
    try {
      const resp = await postUpdateMonthData(body);
      if (resp.code === 2000) {
        await fetchMonthTaskData();
        await VXETable.modal.message({
          content: '更新成功',
          status: 'success',
        });
      }
    } catch (error) {
      console.log('error:', error);
    }
  }
}

const saveRow = async (row: any) => {
  currentRow.value = row;
  isROI.value = validateForm3(row);
  if (isROI.value) {
    openTip.value = true;
    return;
  }
  await updateRow(row);
};

const updateRow = async (row: RowVO) => {
  openTip.value = false;
  const $grid = xGrid.value;
  if ($grid) {
    if (dateType === 'day') {
      const fieldsToValidate = ['sales_original'];
      if (!validateNumericFields(row, fieldsToValidate)) return; // 验证字段
      await updateDayData(row);
    } else if (dateType === 'week') {
      const fieldsToValidate = ['sales_original', 'ad_sales_original', 'ad_cost_original', 'total_sales_current_monthly_original', 'impression', 'ad_click', 'ad_order', 'money_by_amazon', 'money_by_other', 'session', 'order', 'availableSalesDay', 'intransitInventory', 'overseasStorage', 'refundRate'];
      if (!validateNumericFields(row, fieldsToValidate)) return; // 验证字段
      await updateWeekData(row);
    } else if (dateType === 'month') {
      const fieldsToValidate = ['sales_original'];
      if (!validateNumericFields(row, fieldsToValidate)) return; // 验证字段
      await updateMonthData(row);
    }
    activeEditRow.value = false;
    await $grid.clearEdit();
  }
};

// 日数据提示
async function salesTip(apiFunction, dateTypeKey) {
  const dateMap = {
    day: yDayDate.value,
    week: yWeekDay.value,
    month: yMonthDay.value,
  };
  const resp = await apiFunction({
    task: currentRow.value.task,
    [`${ dateTypeKey }_end_date`]: dateMap[dateTypeKey],
  });
  if (dateType === 'week') {
    ySalesData.value = resp.data;
  } else {
    ySalesData.value = resp.data[0];
  }
  return ySalesData.value;
}

async function daySalesTip() {
  await salesTip(getDayBeforeData, 'day');
}

async function weekSalesTip() {
  await salesTip(getWeekBeforeData, 'week');
}

async function monthSalesTip() {
  await salesTip(getMonthBeforeData, 'month');
}

async function currentSalesTip() {
  if (dateType === 'week') {
    await weekSalesTip();
  } else if (dateType === 'month') {
    await monthSalesTip();
  } else {
    await daySalesTip();
  }
}

const currentGridOptions = computed(() => {
  const selectedGridOptions = gridOptions[dateType] || gridOptions['day'];
  return {
    ...gridOptions,
    ...selectedGridOptions
  };
});

const cellStyle = () => {
  return {
    fontSize: '13px',
    fontWeight: '500',
  };
};

const headerCellStyle = () => {
  return {
    fontSize: '13px',
  };
};

const validateForm3 = (row: RowVO) => {
  const adSalesValue = row.ad_sales_original;
  const adCostValue = row.ad_cost_original;

  if (adSalesValue != null && adCostValue != null && adCostValue !== 0) {
    const ratio = (adSalesValue - adCostValue) / adCostValue;
    return ratio < 0;
  }
};

onMounted(() => {
  setDefaultDate();
});
</script>

<template>
  <div>
    <el-card class=" my-3 mx-8 p-0">
      <div class="flex gap-1.5 justify-between mx-2 items-center">
        <Selector ref="selectorRef" @update:updateData="updateDataChange" />
        <div v-if="dateType === 'day'" class="demo-date-picker">
          <div class="block">
            <span class="demonstration">日数据时间:</span>
            <el-date-picker
                v-model="dailySalesTime"
                :clearable="false"
                :disabled-date="disabledDate"
                :shortcuts="shortcuts"
                style="width: 170px"
                type="Date"
                @change="handleDayChange"
            />
          </div>
        </div>
        <div v-if="dateType === 'week'" class="demo-date-picker">
          <el-config-provider :locale="enLocale">
            <div class="block mt-2">
              <span class="demonstration">周广告数据时间:</span>
              <el-date-picker
                  v-model="weeklyAdTime"
                  :clearable="false"
                  :format="adFormat"
                  disabled
                  placeholder="选择一周"
                  type="week"
              />
            </div>
            <div class="block">
              <span class="demonstration">周销售数据时间:</span>
              <el-date-picker
                  v-model="weeklyEntryTime"
                  :clearable="false"
                  :disabled-date="disabledDate"
                  :format="entryFormat"
                  placeholder="选择一周"
                  type="week"
                  @change="handleWeekChange"
              />
            </div>
          </el-config-provider>
        </div>
        <div v-if="dateType === 'month'" class="demo-date-picker">
          <div class="block">
            <span class="demonstration">月数据时间:</span>
            <el-date-picker
                v-model="monthlyEntryTime"
                :clearable="false"
                :disabled-date="disabledDate"
                :format="monthlyEntryFormat"
                placeholder="选择月份"
                type="month"
                @change="handleMonthChange"
            />
          </div>
        </div>
      </div>
    </el-card>
  </div>
  <el-card class="mx-8">
    <div style="position: relative">
      <vxe-grid ref="xGrid" :cell-style="cellStyle" :header-cell-style="headerCellStyle" stripe
                v-bind="currentGridOptions"
                v-on="gridEvents">
        <template #operate="{ row }">
          <template v-if="hasActiveEditRow(row)">
            <el-button link size="small" @click="clearRowEvent(row)">取消</el-button>
            <el-button link size="small" type="warning" @click="saveRow(row)">保存</el-button>
          </template>
          <template v-else>
            <el-button :disabled="!row.id||activeEditRow" link size="small" type="success" @click="handelEditRow(row)">
              修改
            </el-button>
          </template>
          <el-button v-if="!hasActiveEditRow(row)" :disabled="row.id||activeEditRow" link size="small" type="primary"
                     @click="createEvent(row)">创建
          </el-button>
        </template>
        <template #total_header="{ row }">
          <span>当月截止{{ entryEndDate }}销售额</span>
        </template>
        <template #sales_original_edit="{ row }">
          <vxe-input v-model="row.sales_original"></vxe-input>
        </template>
        <template #ad_sales_original_edit="{ row }">
          <vxe-input v-model="row.ad_sales_original"></vxe-input>
        </template>
        <template #ad_cost_original_edit="{ row }">
          <vxe-input v-model="row.ad_cost_original"></vxe-input>
        </template>
        <template #total_sales_current_monthly_edit="{ row }">
          <vxe-input v-model="row.total_sales_current_monthly_original"></vxe-input>
        </template>
        <template #impression_edit="{ row }">
          <vxe-input v-model="row.impression"></vxe-input>
        </template>
        <template #ad_click_edit="{ row }">
          <vxe-input v-model="row.ad_click"></vxe-input>
        </template>
        <template #ad_order_edit="{ row }">
          <vxe-input v-model="row.ad_order"></vxe-input>
        </template>
        <template #money_by_amazon_edit="{ row }">
          <vxe-input v-model="row.money_by_amazon"></vxe-input>
        </template>
        <template #money_by_other_edit="{ row }">
          <vxe-input v-model="row.money_by_other"></vxe-input>
        </template>
        <template #session_edit="{ row }">
          <vxe-input v-model="row.session"></vxe-input>
        </template>
        <template #order_edit="{ row }">
          <vxe-input v-model="row.order"></vxe-input>
        </template>
        <template #availableSalesDay_edit="{ row }">
          <vxe-input v-model="row.availableSalesDay"></vxe-input>
        </template>
        <template #intransitInventory_edit="{ row }">
          <vxe-input v-model="row.intransitInventory"></vxe-input>
        </template>
        <template #overseasStorage_edit="{ row }">
          <vxe-input v-model="row.overseasStorage"></vxe-input>
        </template>
        <template #refundRate_edit="{ row }">
          <vxe-input v-model="row.refundRate"></vxe-input>
        </template>
        <template #refundRate_default="{ row }">
          <span v-if="row.refundRate !== null && row.refundRate !== undefined">
              {{ row.refundRate }}%
          </span>
          <span v-else>
              {{ row.refundRate }}
          </span>
        </template>
      </vxe-grid>
    </div>
  </el-card>
  <CreateDialog v-if="createOpen" v-model="createOpen" :currentDate="currentDate" :currentRow="currentRow"
                :dateType="dateType" :ySalesData="ySalesData" @refresh="fetchCurrentTaskData"></CreateDialog>
  <TipDialog v-if="openTip" v-model="openTip" :isROI="isROI" @update="updateRow(currentRow)"></TipDialog>
</template>

<style lang="scss" scoped>
.demo-date-picker {
  display: flex;
  flex-direction: column-reverse;
}

.demo-date-picker .demonstration {
  color: var(--el-text-color-secondary);
  font-size: 14px;
  white-space: nowrap;
  margin-right: 8px;
}

.vxe-grid {
  border-radius: 10px;
  margin-bottom: 10px;
}

.el-card {
  border: none;
  box-shadow: none;
}

.el-card:hover {
  box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1),
  0 4px 6px -2px rgba(0, 0, 0, 0.05);
  border-color: #eee;
  transition: all 0.2s ease-in-out;
}
</style>
