<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import { ElMessageBox } from 'element-plus';
import {
  fetchCompletePersonalItem,
  fetchCreatePersonalItemWorklog,
  fetchDeletePersonalItemWorklog,
  fetchGetPersonalItemDetail,
  fetchGetPersonalItemWorklogPage,
  fetchUpdatePersonalItemWorklog
} from '@/service/api';
import { useAuthStore } from '@/store/modules/auth';
import BusinessFormDialog from '@/components/custom/business-form-dialog.vue';
import TaskWorklogPanel from '@/views/project/project/execution/modules/task-worklog-panel.vue';
import {
  formatPersonalItemDate,
  formatPersonalItemOwnerName,
  formatPersonalItemProgress,
  getPersonalItemStatusLabel,
  resolvePersonalItemStatusTagType
} from './personal-item-shared';

defineOptions({ name: 'PersonalItemDetailDialog' });

type TabName = 'worklog';

interface Props {
  rowData?: Api.PersonalItem.PersonalItem | null;
  defaultTab?: TabName;
}

const props = withDefaults(defineProps<Props>(), {
  rowData: null,
  defaultTab: 'worklog'
});

const emit = defineEmits<{
  changed: [item: Api.PersonalItem.PersonalItem];
}>();

const visible = defineModel<boolean>('visible', {
  default: false
});

const activeTab = ref<TabName>('worklog');
const detailData = ref<Api.PersonalItem.PersonalItem | null>(null);
const authStore = useAuthStore();
const currentUserId = computed(() => authStore.userInfo.userId || '');
const currentUserName = computed(
  () => authStore.userInfo.nickname?.trim() || authStore.userInfo.userName?.trim() || ''
);

const COMPLETED_STATUS_CODE: Api.PersonalItem.PersonalItemStatusCode = 'completed';
const COMPLETE_ACTION_CODE = 'complete';

const ownerName = computed(() => {
  if (!detailData.value) return '--';

  const displayName = formatPersonalItemOwnerName(detailData.value);

  if (displayName !== detailData.value.ownerId) {
    return displayName;
  }

  return detailData.value.ownerId === currentUserId.value && currentUserName.value
    ? currentUserName.value
    : displayName;
});
const statusName = computed(() => (detailData.value ? getPersonalItemStatusLabel(detailData.value.statusCode) : '--'));
const statusTagType = computed(() =>
  detailData.value ? resolvePersonalItemStatusTagType(detailData.value.statusCode) : 'info'
);
const progressText = computed(() => formatPersonalItemProgress(detailData.value?.progressRate));
const plannedStartText = computed(() => formatPersonalItemDate(detailData.value?.plannedStartDate));
const plannedEndText = computed(() => formatPersonalItemDate(detailData.value?.plannedEndDate));
const actualStartText = computed(() => formatPersonalItemDate(detailData.value?.actualStartDate));
const actualEndText = computed(() => formatPersonalItemDate(detailData.value?.actualEndDate));
const totalHoursText = computed(() => {
  const total = detailData.value?.totalSpentHours;
  return `${typeof total === 'number' && Number.isFinite(total) ? total.toFixed(1) : '0.0'}h`;
});
const canSubmitWorklog = computed(() =>
  Boolean(
    detailData.value?.id && (detailData.value.statusCode === 'pending' || detailData.value.statusCode === 'active')
  )
);

function syncDetailFromPageRow() {
  detailData.value = props.rowData ?? null;
}

async function refreshDetail() {
  if (!detailData.value?.id) {
    return;
  }

  const { error, data } = await fetchGetPersonalItemDetail(detailData.value.id);

  if (!error && data) {
    detailData.value = data;
  }
}

function canPromptCompleteItem(item: Api.PersonalItem.PersonalItem) {
  if (item.statusCode === COMPLETED_STATUS_CODE || item.terminal) {
    return false;
  }

  return (
    item.progressRate >= 100 && (item.availableActions ?? []).some(action => action.actionCode === COMPLETE_ACTION_CODE)
  );
}

async function promptCompleteItemIfNeeded() {
  if (!detailData.value || !canPromptCompleteItem(detailData.value)) {
    return;
  }

  try {
    await ElMessageBox.confirm('事项进度已达 100%，是否完成当前事项？', '完成确认', {
      confirmButtonText: '完成事项',
      cancelButtonText: '仅保留工时',
      type: 'info'
    });
  } catch {
    return;
  }

  const { error } = await fetchCompletePersonalItem(detailData.value.id);

  if (!error) {
    window.$message?.success('我的事项已完成');
    await refreshDetail();
  }
}

async function handleWorklogChanged() {
  await refreshDetail();
  await promptCompleteItemIfNeeded();

  if (detailData.value) {
    emit('changed', detailData.value);
  }
}

function fetchPersonalWorklogPage(params: Api.Project.TaskWorklogSearchParams) {
  return fetchGetPersonalItemWorklogPage(detailData.value!.id, params);
}

function createPersonalWorklog(data: Api.Project.SaveTaskWorklogParams) {
  return fetchCreatePersonalItemWorklog(detailData.value!.id, data);
}

function updatePersonalWorklog(payload: { worklogId: string; data: Api.Project.SaveTaskWorklogParams }) {
  return fetchUpdatePersonalItemWorklog(detailData.value!.id, payload);
}

function deletePersonalWorklog(worklogId: string) {
  return fetchDeletePersonalItemWorklog(detailData.value!.id, worklogId);
}

watch(
  () => visible.value,
  value => {
    if (value) {
      activeTab.value = props.defaultTab;
      syncDetailFromPageRow();
    }
  }
);

watch(
  () => props.rowData,
  () => {
    if (visible.value) {
      syncDetailFromPageRow();
    }
  }
);

watch(
  () => props.defaultTab,
  value => {
    if (visible.value) {
      activeTab.value = value;
    }
  }
);
</script>

<template>
  <BusinessFormDialog
    v-model="visible"
    title="工作日志"
    width="1100px"
    max-body-height="78vh"
    :show-footer="false"
    :scrollbar="false"
  >
    <ElTabs v-model="activeTab" class="personal-item-detail-dialog__tabs">
      <ElTabPane label="工作日志" name="worklog" lazy>
        <div v-if="detailData" class="personal-item-worklog-content">
          <div class="personal-item-worklog-content__cards">
            <div class="personal-item-worklog-content__card">
              <span class="personal-item-worklog-content__card-label">负责人</span>
              <span class="personal-item-worklog-content__card-value" :title="ownerName">{{ ownerName }}</span>
            </div>
            <div class="personal-item-worklog-content__card">
              <span class="personal-item-worklog-content__card-label">当前状态</span>
              <ElTag :type="statusTagType" size="small" effect="light" class="personal-item-worklog-content__card-tag">
                {{ statusName }}
              </ElTag>
            </div>
            <div class="personal-item-worklog-content__card">
              <span class="personal-item-worklog-content__card-label">计划开始</span>
              <span class="personal-item-worklog-content__card-value">{{ plannedStartText }}</span>
            </div>
            <div class="personal-item-worklog-content__card">
              <span class="personal-item-worklog-content__card-label">计划结束</span>
              <span class="personal-item-worklog-content__card-value">{{ plannedEndText }}</span>
            </div>
            <div class="personal-item-worklog-content__card">
              <span class="personal-item-worklog-content__card-label">当前进度</span>
              <span class="personal-item-worklog-content__card-value">{{ progressText }}</span>
            </div>
            <div class="personal-item-worklog-content__card">
              <span class="personal-item-worklog-content__card-label">累计工时</span>
              <span class="personal-item-worklog-content__card-value personal-item-worklog-content__card-value--accent">
                {{ totalHoursText }}
              </span>
            </div>
            <div class="personal-item-worklog-content__card">
              <span class="personal-item-worklog-content__card-label">实际开始</span>
              <span class="personal-item-worklog-content__card-value">{{ actualStartText }}</span>
            </div>
            <div class="personal-item-worklog-content__card">
              <span class="personal-item-worklog-content__card-label">实际结束</span>
              <span class="personal-item-worklog-content__card-value">{{ actualEndText }}</span>
            </div>
          </div>

          <TaskWorklogPanel
            project-id=""
            execution-id=""
            :task-id="detailData.id"
            :task-owner-id="currentUserId"
            :task-status-code="detailData.statusCode"
            :task-progress-rate="detailData.progressRate"
            :can-submit="canSubmitWorklog"
            :active="activeTab === 'worklog' && visible"
            :fetch-worklog-page="fetchPersonalWorklogPage"
            :create-worklog="createPersonalWorklog"
            :update-worklog="updatePersonalWorklog"
            :delete-worklog="deletePersonalWorklog"
            attachment-directory="personal-item-worklog"
            create-success-message="工作日志新增成功"
            update-success-message="工作日志修改成功"
            delete-success-message="工作日志删除成功"
            @changed="handleWorklogChanged"
          />
        </div>
      </ElTabPane>
    </ElTabs>
  </BusinessFormDialog>
</template>

<style scoped lang="scss">
.personal-item-detail-dialog__tabs {
  --el-tabs-header-height: 40px;
}

.personal-item-detail-dialog__tabs :deep(.el-tabs__content),
.personal-item-detail-dialog__tabs :deep(.el-tab-pane) {
  min-height: 640px;
}

.personal-item-worklog-content {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.personal-item-worklog-content__cards {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
}

.personal-item-worklog-content__card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
  padding: 12px 14px;
  background: var(--el-fill-color-light);
  border: 1px solid var(--el-border-color-lighter);
  border-radius: 6px;
}

.personal-item-worklog-content__card-label {
  color: var(--el-text-color-secondary);
  font-size: 12px;
  line-height: 1.2;
}

.personal-item-worklog-content__card-value {
  overflow: hidden;
  color: var(--el-text-color-primary);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.3;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.personal-item-worklog-content__card-value--accent {
  color: var(--el-color-primary);
}

.personal-item-worklog-content__card-tag {
  align-self: flex-start;
}
</style>
