<script setup lang="ts">
import { computed, ref } from 'vue';
import dayjs from 'dayjs';
import { fetchRemindTeamReport } from '@/service/api';
import { formatIsoWeekRangeLabel } from '../utils';
import { formatWeeklyPeriodLabel } from '../types';

defineOptions({ name: 'TeamReportSummary' });

interface Props {
  reportType: Api.WorkReport.Common.ReportType;
  periodKeys?: string[];
  periodLabel?: string;
  loading?: boolean;
  summary?: Api.WorkReport.Common.TeamReportSummary | null;
}

const props = withDefaults(defineProps<Props>(), {
  periodKeys: () => [],
  periodLabel: '',
  loading: false,
  summary: null
});

const emit = defineEmits<{
  reminded: [];
}>();

const remindingAll = ref(false);
const remindingItemKey = ref('');
const canRemind = computed(() => props.periodKeys.length > 0);

function formatSummaryPeriodLabel() {
  if (!props.summary?.periodStartDate || !props.summary?.periodEndDate) {
    return props.periodLabel;
  }

  const start = dayjs(props.summary.periodStartDate);
  const end = dayjs(props.summary.periodEndDate);

  if (!start.isValid() || !end.isValid()) {
    return `${props.summary.periodStartDate} 至 ${props.summary.periodEndDate}`;
  }

  if (props.reportType === 'monthly' || props.reportType === 'project') {
    const startMonth = start.format('YYYY-MM');
    const endMonth = end.format('YYYY-MM');
    return startMonth === endMonth ? startMonth : `${startMonth} 至 ${endMonth}`;
  }

  if (props.reportType === 'weekly') {
    return formatIsoWeekRangeLabel(props.summary.periodStartDate, props.summary.periodEndDate);
  }

  return `${start.format('YYYY-MM-DD')} 至 ${end.format('YYYY-MM-DD')}`;
}

const displayPeriodLabel = computed(() => formatSummaryPeriodLabel());

const cards = computed(() => [
  { label: '应填报告数', value: props.summary?.expectedReportCount ?? 0 },
  { label: '已提交报告数', value: props.summary?.submittedReportCount ?? 0 },
  { label: '未提交报告数', value: props.summary?.unsubmittedReportCount ?? 0, key: 'unsubmitted' as const },
  { label: '待审批报告数', value: props.summary?.pendingApprovalReportCount ?? 0 }
]);

function getUnsubmittedReportSecondaryText(item: Api.WorkReport.Common.TeamReportUnsubmittedReport) {
  if (props.reportType === 'project') {
    return item.projectName ? `${item.projectName} · ${item.periodLabel}` : item.periodLabel;
  }

  if (props.reportType === 'weekly') {
    const weeklyPeriodMatch = item.periodKey.match(/^weekly-(\d{4}-\d{2}-\d{2})-(\d{4}-\d{2}-\d{2})$/u);

    if (weeklyPeriodMatch) {
      return formatWeeklyPeriodLabel(weeklyPeriodMatch[1], weeklyPeriodMatch[2], item.periodLabel);
    }

    const weeklyRangeMatch = item.periodLabel.match(/^(\d{4}-\d{2}-\d{2})\s*至\s*(\d{4}-\d{2}-\d{2})$/u);

    if (weeklyRangeMatch) {
      return formatWeeklyPeriodLabel(weeklyRangeMatch[1], weeklyRangeMatch[2], item.periodLabel);
    }

    return formatWeeklyPeriodLabel(undefined, undefined, item.periodLabel);
  }

  return item.periodLabel;
}

function getUnsubmittedReportKey(item: Api.WorkReport.Common.TeamReportUnsubmittedReport) {
  return `${item.userId}-${item.projectId || 'none'}-${item.periodKey}`;
}

function getSingleRemindSuccessText(remindedCount: number, preciseProjectReminder: boolean) {
  if (preciseProjectReminder) {
    return `已发送 ${remindedCount} 条催办提醒`;
  }

  return `已催办 ${remindedCount} 人`;
}

async function handleRemind(userIds?: string[]) {
  if (!props.periodKeys.length) return;

  const isSingleUserReminder = userIds?.length === 1;

  remindingAll.value = true;

  const results = await Promise.all(
    props.periodKeys.map(periodKey =>
      fetchRemindTeamReport({
        reportType: props.reportType,
        periodKey,
        userIds
      })
    )
  );

  remindingAll.value = false;

  const remindedCount = results.reduce((total, result) => {
    if (result.error) return total;
    return total + (result.data?.remindedCount ?? 0);
  }, 0);

  if (!remindedCount) return;

  window.$message?.success(
    props.periodKeys.length > 1
      ? '已按所选区间发送催办提醒'
      : getSingleRemindSuccessText(remindedCount, props.reportType === 'project' && isSingleUserReminder)
  );
  emit('reminded');
}

async function handleRemindItem(item: Api.WorkReport.Common.TeamReportUnsubmittedReport) {
  const itemKey = getUnsubmittedReportKey(item);
  remindingItemKey.value = itemKey;

  const result = await fetchRemindTeamReport({
    reportType: props.reportType,
    periodKey: item.periodKey,
    userIds: [item.userId],
    projectId: props.reportType === 'project' ? item.projectId : undefined
  });

  remindingItemKey.value = '';

  if (result.error) return;

  const remindedCount = result.data?.remindedCount ?? 0;
  if (!remindedCount) return;

  window.$message?.success(getSingleRemindSuccessText(remindedCount, props.reportType === 'project'));
  emit('reminded');
}
</script>

<template>
  <div v-loading="props.loading" class="team-report-summary">
    <div v-if="displayPeriodLabel" class="team-report-summary__period">{{ displayPeriodLabel }}</div>

    <div class="team-report-summary__grid">
      <div v-for="card in cards" :key="card.label" class="team-report-summary__item">
        <div class="team-report-summary__label">{{ card.label }}</div>
        <div class="team-report-summary__value">
          <template v-if="card.key === 'unsubmitted'">
            <ElPopover placement="bottom" :width="300" trigger="hover">
              <template #reference>
                <button type="button" class="team-report-summary__link-button">{{ card.value }}</button>
              </template>

              <div class="team-report-summary__popover">
                <div class="team-report-summary__popover-title">未提交报告</div>
                <div v-if="props.summary?.unsubmittedReports?.length" class="team-report-summary__user-list">
                  <div
                    v-for="item in props.summary.unsubmittedReports"
                    :key="getUnsubmittedReportKey(item)"
                    class="team-report-summary__user-item"
                  >
                    <div class="team-report-summary__user-content">
                      <div class="team-report-summary__user-name">{{ item.userNickname }}</div>
                      <div class="team-report-summary__user-meta">
                        {{ getUnsubmittedReportSecondaryText(item) }}
                      </div>
                    </div>
                    <ElButton
                      v-if="canRemind"
                      link
                      type="primary"
                      :loading="remindingItemKey === getUnsubmittedReportKey(item)"
                      @click="handleRemindItem(item)"
                    >
                      催办
                    </ElButton>
                  </div>
                </div>
                <ElEmpty v-else :image-size="60" description="暂无未提交报告" />

                <div v-if="canRemind" class="team-report-summary__popover-footer">
                  <ElButton
                    size="small"
                    type="primary"
                    plain
                    :loading="remindingAll"
                    :disabled="!props.summary?.unsubmittedReports?.length"
                    @click="handleRemind()"
                  >
                    一键催办全部
                  </ElButton>
                </div>
              </div>
            </ElPopover>
          </template>
          <template v-else>
            {{ card.value }}
          </template>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
.team-report-summary {
  display: grid;
  gap: 12px;
}

.team-report-summary__period {
  color: var(--el-text-color-secondary);
  font-size: 12px;
}

.team-report-summary__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
}

.team-report-summary__item {
  display: grid;
  gap: 8px;
  padding: 14px 16px;
  border: 1px solid var(--el-border-color-light);
  border-radius: 8px;
  background: var(--el-fill-color-blank);
}

.team-report-summary__label {
  color: var(--el-text-color-secondary);
  font-size: 12px;
}

.team-report-summary__value {
  color: var(--el-text-color-primary);
  font-size: 22px;
  font-weight: 600;
  line-height: 1.2;
}

.team-report-summary__link-button {
  padding: 0;
  border: none;
  background: transparent;
  color: var(--el-color-primary);
  font: inherit;
  cursor: pointer;
}

.team-report-summary__popover {
  display: grid;
  gap: 10px;
}

.team-report-summary__popover-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--el-text-color-primary);
}

.team-report-summary__user-list {
  display: grid;
  gap: 8px;
  max-height: 240px;
  overflow: auto;
}

.team-report-summary__user-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 10px;
  border-radius: 8px;
  background: var(--el-fill-color-light);
}

.team-report-summary__user-name {
  min-width: 0;
  color: var(--el-text-color-regular);
  font-weight: 500;
}

.team-report-summary__user-content {
  min-width: 0;
  display: grid;
  gap: 4px;
}

.team-report-summary__user-meta {
  min-width: 0;
  color: var(--el-text-color-secondary);
  font-size: 12px;
  line-height: 1.4;
  word-break: break-all;
}

.team-report-summary__popover-footer {
  display: flex;
  justify-content: flex-end;
}

@media (width <= 1200px) {
  .team-report-summary__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (width <= 768px) {
  .team-report-summary__grid {
    grid-template-columns: 1fr;
  }
}
</style>
