<template>
  <div class="p-4">
    <!-- 标题 -->
    <div class="mb-8 flex justify-between items-center">
      <div class="text-2xl font-semibold">流水账</div>
      <div class="flex items-center">
        <a-button type="primary" v-if="!morning" @click="punch(0)"> 早打卡 </a-button>
        <a-button type="primary" v-else>
          {{ dayjs(+morning).format('HH:mm') }}
        </a-button>
        <a-button class="mx-5" type="primary" v-if="!night" @click="punch(1)"> 晚打卡 </a-button>
        <a-button class="mx-5" type="primary" v-else>
          {{ dayjs(+night).format('HH:mm') }}
        </a-button>
        <FullscreenExitOutlined v-if="isFullScreen" class="text-lg" style="color: #777" @click="changeIsFullScreen(false)" />
        <FullscreenOutlined v-else class="text-lg" style="color: #777" @click="changeIsFullScreen(true)" />
      </div>
    </div>

    <!-- 筛选 -->
    <a-form class="flex flex-wrap" :model="formState">
      <a-form-item name="timeRange" label="时间" style="width: 280px; margin-right: 20px; margin-bottom: 12px">
        <a-range-picker v-model:value="formState.timeRange" />
      </a-form-item>

      <a-form-item name="staffRange" label="员工" style="width: 280px; margin-right: 20px; margin-bottom: 12px">
        <a-select
          v-model:value="formState.staffRange"
          :options="memberList"
          :field-names="{ label: 'empName', value: 'empName' }"
          mode="multiple"
          placeholder="请选择员工"
        ></a-select>
      </a-form-item>

      <a-form-item name="programName" label="项目" style="width: 280px; margin-right: 20px; margin-bottom: 12px">
        <a-select
          v-model:value="formState.programName"
          :options="proList"
          :field-names="{ label: 'projectName', value: 'projectName' }"
          mode="multiple"
          placeholder="请输入项目名称"
        ></a-select>
      </a-form-item>

      <div class="block w-full">
        <a-button type="primary" html-type="submit" @click="handleSubmit">筛选</a-button>
        <a-button class="mx-3" type="primary" @click="handleExport">导出</a-button>
        <a-button @click="resetData">重置</a-button>
      </div>
    </a-form>

    <!-- 表格 -->
    <a-table class="mt-6" :columns="columns" :data-source="columnDatas" bordered :pagination="false" :scroll="{ x: 1400 }">
      <template #bodyCell="{ column, text, record }">
        <div
          style="height: 100px"
          :class="{ 'text-left': column.dataIndex === 'program' }"
          class="overflow-y-auto task-today"
          @dblclick="showModal(record, column.proId)"
        >
          <template v-if="column.dataIndex === 'program'">
            <template v-for="item in text">
              <template v-if="column.proId === item.proId">
                <div class="mb-3" v-for="(task, key) in item.tasks" :key="key">
                  <PushpinOutlined class="mr-2" v-if="task.cooperation === 1" title="协作任务" />
                  <span>
                    我今日计划结果{{ key + 1 }}是：{{ task.taskName }}，交付物是：{{ task.deliverName }}，截止时间：{{
                      dayjs(+task.deadline).format('MM-DD')
                    }}，时长：{{ task.duration / 3600000 }}，检查人：{{ task.checker }}
                  </span>
                </div>
              </template>
            </template>
          </template>
          <template v-else>
            {{ text }}
          </template>
        </div>
      </template>
    </a-table>

    <a-pagination
      class="text-right"
      v-model:current="current"
      v-model:pageSize="pageSize"
      :total="dataTotal"
      @change="handlePage"
      show-less-items
    />
  </div>

  <a-modal
    v-model:visible="visible"
    title="今日计划"
    centered
    :footer="null"
    width="800px"
    style="padding: 0; max-height: 800px; overflow-y: auto"
  >
    <div style="padding: 0 96px">
      <div class="mb-4">当前操作项目：{{ currProName }}，当前操作成员：{{ currEmpName }}</div>

      <a-form :model="modalFormState">
        <div v-for="(item, index) in modalFormState" :key="index">
          <div class="flex justify-between items-center text-gray-400">
            <div class="mb-5 text-right" style="width: 120px">计划结果{{ index + 1 }}：</div>
            <DeleteOutlined v-if="modalFormState.length > 1" @click="delFormItem(index)" />
          </div>

          <a-form-item name="taskName" style="margin-bottom: 20px">
            <div class="flex">
              <label class="flex-shrink-0 text-right" style="width: 120px; line-height: 32px">
                <span style="color: #ff5353; margin-right: 5px">*</span>今日计划结果{{ index + 1 }}：
              </label>
              <a-textarea v-model:value="item.taskName" :disabled="isDisabled" placeholder="请输入今日计划" />
            </div>
          </a-form-item>

          <a-form-item name="deliverName" style="margin-bottom: 20px">
            <div class="flex">
              <label class="flex-shrink-0 text-right" style="width: 120px; line-height: 32px">
                <span style="color: #ff5353; margin-right: 5px">*</span>交付物：
              </label>
              <a-input v-model:value="item.deliverName" :disabled="isDisabled" placeholder="请输入交付物" />
            </div>
          </a-form-item>

          <a-form-item name="showDeadLine" style="margin-bottom: 20px">
            <div class="flex">
              <label class="flex-shrink-0 text-right" style="width: 120px; line-height: 32px">
                <span style="color: #ff5353; margin-right: 5px">*</span>截止时间：
              </label>
              <a-date-picker class="w-full" v-model:value="item.showDeadLine" :disabled="isDisabled" />
            </div>
          </a-form-item>

          <a-form-item name="showDuration" style="margin-bottom: 20px">
            <div class="flex">
              <label class="flex-shrink-0 text-right" style="width: 120px; line-height: 32px">
                <span style="color: #ff5353; margin-right: 5px">*</span>时长：
              </label>

              <a-input-group compact class="items-center" style="width: 100%; display: flex">
                <a-auto-complete
                  style="width: calc(100% - 35px)"
                  v-model:value="item.showDuration"
                  :options="workDurations"
                  placeholder="请输入工作时长"
                  :disabled="isDisabled"
                  @change="handleDuration($event, index)"
                />

                <div style="width: 35px; border: none" class="text-right">小时</div>
              </a-input-group>
            </div>
          </a-form-item>

          <a-form-item name="checker" style="margin-bottom: 20px">
            <div class="flex">
              <label class="flex-shrink-0 text-right" style="width: 120px; line-height: 32px">
                <span style="color: #ff5353; margin-right: 5px">*</span>检查人：
              </label>
              <a-select
                v-model:value="item.checker"
                :options="memberList"
                :field-names="{ label: 'empName', value: 'empName' }"
                show-search
                placeholder="请选择检查人"
                :disabled="isDisabled"
                :filter-option="filterOption"
                @change="handleInspector($event, index)"
              ></a-select>
            </div>
          </a-form-item>

          <a-form-item name="cooperation" style="margin-bottom: 20px">
            <div class="flex">
              <label class="flex-shrink-0 text-right" style="width: 120px; line-height: 32px"> 是否协作： </label>
              <a-radio-group v-model:value="item.cooperation" class="w-full items-center" style="display: flex">
                <a-radio class="items-center" style="display: flex" :value="1" :disabled="isDisabled">是</a-radio>
                <a-radio class="items-center" style="display: flex" :value="0" :disabled="isDisabled">否</a-radio>
              </a-radio-group>
            </div>
          </a-form-item>

          <a-form-item name="deliverLink" style="margin-bottom: 20px">
            <div class="flex">
              <label class="flex-shrink-0 text-right" style="width: 120px; line-height: 32px"> 交付物链接： </label>
              <a-textarea v-model:value="item.deliverLink" :disabled="isDisabled" placeholder="请输入交付物链接" />
            </div>
          </a-form-item>
        </div>

        <a-form-item v-if="!isDisabled">
          <div class="flex">
            <label class="flex-shrink-0 text-right" style="width: 120px"></label>
            <a-button style="color: #1890ff; border-color: #1890ff" type="dashed" @click="addFormItem">+ 添加</a-button>
          </div>
        </a-form-item>

        <a-form-item v-if="!isDisabled">
          <div class="flex items-center">
            <label class="flex-shrink-0 text-right" style="width: 120px"></label>
            <a-button class="mr-4" type="primary" @click="submitForm">提交</a-button>
            <a-button @click="cancleModal">取消</a-button>
          </div>
        </a-form-item>
      </a-form>
    </div>
  </a-modal>
</template>

<script setup>
import { useStore } from 'vuex';
import { reactive, ref, onMounted, computed, watch } from 'vue';
import dayjs from 'dayjs';
import { FullscreenExitOutlined, FullscreenOutlined, DeleteOutlined, PushpinOutlined } from '@ant-design/icons-vue';
import { getBasicInfo, queryTasks, submitTask, clockQuery, clockPunch, exportQuery } from 'apis';
import { message } from 'ant-design-vue';

const store = useStore();
const projectId = computed(() => store.getters['project/projectId']);
const sessionProjectId = sessionStorage.getItem('projectId');
const roleId = computed(() => store.state.role.roleId);
const members = computed(() => store.state.role.members);
const userId = computed(() => store.getters['user/userId']); // 用户id
const isFullScreen = computed(() => store.state.layout.isFullScreen); // 是否全屏
const visible = ref(false); // 是否显示弹框表单
const isDisabled = ref(false); // 是否允许编辑
const morning = ref(false); // 早打卡
const night = ref(false); // 晚打卡
const checkerId = ref(null); // 打卡审核人id
const recordId = ref(null); // 记录id
const memberId = ref(null); // 成员id

// 筛选表单
const formState = reactive({
  timeRange: [dayjs(+new Date().getTime()), dayjs(+new Date().getTime()).add(1, 'day')], // 时间范围
  staffRange: [], // 员工
  programName: [], // 项目名称
});
const startTime = dayjs(+new Date().getTime());
const endTime = dayjs(+new Date().getTime()).add(1, 'day');

// 下拉选选项
const memberList = ref([]); // 成员列表
const proList = ref([]); // 项目列表
const emps = ref([]); // 选中的筛选成员
const proDatas = ref([]); // 选中的筛选项目

// 表格元素
const columns = ref();
const current = ref(1); // 当前页数
const pageSize = ref(10); // 每页条数
const dataTotal = ref(0); // 数据总量

// 表格数据
const columnDatas = ref([]);

// 今日计划表单
const modalFormState = ref([]);
// 工作时长
const workDurations = [...Array(8)].map((_, i) => ({ value: `${i + 1}` }));
const isSubmitDeliver = ref(false); // 是否提交交付物
const currEmpId = ref(null); // 当前点击的用户id
const currEmpName = ref(null); // 当前点击的用户名
const currProId = ref(null); // 当前点击的项目id
const currProName = ref(null); // 当前点击的项目名

onMounted(async () => {
  getClockQuery();
  await getInfo();
  await getQueryTasks();
});

// 改变全屏状态
function changeIsFullScreen(data) {
  store.commit('layout/setIsFullScreen', data);
}

// 获取基本信息（成员列表、项目列表）
async function getInfo() {
  try {
    const { url } = store.state.projects.project;
    const data = await getBasicInfo(url);
    memberList.value = data.emps;
    pageSize.value = data.emps.length;
    proList.value = data.pros;
  } catch (error) {
    message.info(error);
    throw new Error(error);
  }
}

// 获取任务列表
async function getQueryTasks() {
  try {
    const { url } = store.state.projects.project;
    const params = {
      param: {
        startTime: startTime.value || formState.timeRange[0].startOf('day').valueOf(),
        endTime: endTime.value || formState.timeRange[1].startOf('day').valueOf(),
        emps: emps.value || [],
        pros: proDatas.value || [],
      },
    };

    // 相差天数
    const days = dayjs(+formState.timeRange[1].startOf('day')).diff(+formState.timeRange[0].startOf('day'), 'day');
    dataTotal.value = pageSize.value * days; // 分页数据总量

    const data = await queryTasks(params, url);

    columns.value = [
      {
        title: '时间',
        width: 100,
        dataIndex: 'time',
        key: 'time',
        fixed: 'left',
        align: 'center',
      },
      {
        title: '员工',
        width: 100,
        dataIndex: 'staff',
        key: 'staff',
        fixed: 'left',
        align: 'center',
      },
    ];

    columnDatas.value = [];

    data.pros.forEach((proId, index) => {
      const proInfo = proList.value.find(item => item.id === proId);
      columns.value.push({
        title: proInfo.projectName,
        dataIndex: 'program',
        key: `${index}`,
        proId,
        width: 300,
        align: 'center',
      });
    });

    memberList.value.forEach((member, key) => {
      const obj = {
        empId: member.id,
        key,
        time: dayjs(+params.param.startTime).format('MM-DD'),
        staff: `${member.empName}`,
        program: [],
      };

      const currMember = data.recs.filter(item => member.id === item.empId);

      if (currMember.length > 0) {
        const { pros } = currMember[0];
        obj.program = pros;
      }

      columnDatas.value.push(obj);
    });
  } catch (error) {
    message.info(error);
    throw new Error(error);
  }
}

// 筛选
function handleSubmit() {
  emps.value = [];
  proDatas.value = [];
  memberList.value.forEach(item => {
    const index = formState.staffRange.findIndex(emp => emp === item.empName);
    if (index > -1) emps.value.push(item.id);
  });

  proList.value.forEach(item => {
    const index = formState.programName.findIndex(pro => pro === item.projectName);
    if (index > -1) proDatas.value.push(item.id);
  });

  const end = dayjs(+formState.timeRange[0].startOf('day')).add(1, 'day');
  endTime.value = dayjs(+end).valueOf();
  getQueryTasks();
}

// 重置
function resetData() {
  formState.timeRange = [dayjs(+new Date().getTime()), dayjs(+new Date().getTime()).add(1, 'day')];
  formState.staffRange = [];
  formState.programName = [];
  emps.value = [];
  proDatas.value = [];
}

// 导出
async function handleExport() {
  try {
    const start = formState.timeRange[0].startOf('day').valueOf();
    const end = formState.timeRange[1].startOf('day').valueOf();
    const params = {
      param: {
        projectId: projectId.value || sessionProjectId,
        roleId: roleId.value,
        memberIdList: [],
        startTime: start,
        endTime: end,
      },
    };

    const { url } = store.state.projects.project;
    const data = await exportQuery(params, url);
    window.open(data, '_blank');
  } catch (error) {
    message.info(error);
    throw new Error(error);
  }
}

// 分页改变
function handlePage(e) {
  const start = dayjs(+formState.timeRange[0].startOf('day')).add(e - 1, 'day');
  const end = dayjs(+start).add(1, 'day');
  startTime.value = dayjs(+start).valueOf();
  endTime.value = dayjs(+end).valueOf();
  getQueryTasks();
}

// 打开今日计划编辑框
function showModal(data, proId) {
  currEmpId.value = data.empId;
  currProId.value = proId;
  const currEmpInfo = memberList.value.find(item => item.id === data.empId);
  currEmpName.value = currEmpInfo.empName;
  const currProInfo = proList.value.find(item => item.id === proId);
  currProName.value = currProInfo.projectName;

  isDisabled.value = dayjs(+new Date().getTime()).format('MM-DD') !== data.time;
  visible.value = true;

  modalFormState.value = [
    {
      taskName: '',
      deliverName: '',
      showDeadLine: dayjs(+new Date().getTime()),
      deadline: '',
      showDuration: '2',
      duration: '',
      checker: '',
      cooperation: 0,
      deliverLink: '',
      sequence: 0,
    },
  ];
  data.program.forEach(item => {
    if (proId === item.proId) {
      modalFormState.value = [...item.tasks];
    }
  });

  modalFormState.value.forEach((item, index) => {
    item.showDeadLine = item.deadline ? dayjs(+item.deadline) : dayjs(+new Date().getTime());
    item.showDuration = item.duration ? `${item.duration / 3600000}` : '2';
    item.sequence = index;
  });
}

// 检查人筛选
function filterOption(input, option) {
  return option.empName.indexOf(input) >= 0;
}

// 选择工作时长
function handleDuration(e, index) {
  modalFormState.value[index].duration = e;
}

// 选择检查人
function handleInspector(e, index) {
  modalFormState.value[index].checker = e;
}

// 添加计划
function addFormItem() {
  const len = modalFormState.value.length;
  modalFormState.value.push({
    taskName: '',
    deliverName: '',
    showDeadLine: dayjs(+new Date().getTime()),
    deadline: '',
    showDuration: '2',
    duration: '',
    checker: '',
    cooperation: 0,
    deliverLink: '',
    sequence: len,
  });
}

// 删除计划
const delFormItem = index => {
  modalFormState.value.splice(index, 1);
};

// 取消任务弹框
function cancleModal() {
  visible.value = false;
}

// 提交表单
async function submitForm() {
  let flag = false;
  for (let i = 0; i < modalFormState.value.length; i++) {
    const data = modalFormState.value[i];
    data.deadline = dayjs(+data.showDeadLine).valueOf();
    data.duration = data.showDuration * 3600000;

    if (!data.taskName) {
      message.info(`请输入今日计划结果${i + 1}`);
      return false;
    }

    if (!data.deliverName) {
      message.info(`请输入交付物`);
      return false;
    }

    if (!data.duration) {
      message.info(`请输入时长`);
      return false;
    }

    if (!data.checker) {
      message.info(`请选择检查人`);
      return false;
    }

    const reg = /[a-zA-z]+:\/\/[^\s]*/;
    if (data.deliverLink && !reg.test(data.deliverLink)) {
      message.info(`请输入正确的链接`);
      return false;
    }
    flag = true;
  }

  if (flag) {
    isSubmitDeliver.value = true;
  }

  const params = {
    param: {
      time: new Date().getTime(),
      empId: currEmpId.value,
      proId: currProId.value,
      tasks: modalFormState.value,
    },
  };

  try {
    const { url } = store.state.projects.project;
    const data = await submitTask(params, url);
    visible.value = false;
    // punch();
    getQueryTasks();
  } catch (error) {
    message.info(error);
    throw new Error(error);
  }
}

// 获取当前打卡信息
async function getClockQuery() {
  const start = dayjs(+new Date().getTime())
    .startOf('day')
    .valueOf();
  const end = dayjs(+new Date().getTime())
    .endOf('day')
    .valueOf();

  const params = {
    param: {
      projectId: projectId.value || sessionProjectId,
      roleId: roleId.value,
      memberIdList: [],
      startTime: start,
      endTime: end,
    },
  };

  try {
    const { url } = store.state.projects.project;
    const data = await clockQuery(params, url);

    // 审核人
    if (data[0].recordList[0].lastCheckerId) {
      checkerId.value = data[0].recordList[0].lastCheckerId;
    } else if (data[0].recordList[0].checkerId) {
      checkerId.value = data[0].recordList[0].checkerId;
    } else {
      checkerId.value = members.value.length ? members.value[0].memberId : '';
    }

    // 成员id
    if (data[0].recordList[0].isMine === 1) {
      memberId.value = data[0].recordList[0].memberId;
    }

    recordId.value = data[0].recordList[0].id;

    morning.value = data[0].recordList[0].morning; // 早打卡状态
    night.value = data[0].recordList[0].night; // 晚打卡状态
  } catch (error) {
    message.info(error);
    throw new Error(error);
  }
}

async function punch(clockType) {
  if ((clockType === 0 && morning.value) || (clockType === 1 && night.value)) return;

  const dateTime = dayjs(+new Date().getTime()).valueOf(); // 打卡时间

  const params = { param: { checkerId: checkerId.value, memberId: memberId.value, id: recordId.value, clockType, dateTime } };
  try {
    const { url } = store.state.projects.project;
    const data = await clockPunch(params, url);

    getClockQuery();
  } catch (error) {
    message.info(`打卡失败，${error}`);
    throw new Error(error);
  }
}
</script>

<style scoped>
.task-today::-webkit-scrollbar {
  width: 0 !important;
}
</style>
