<script setup lang="ts">
import { computed, onMounted, ref, watch } from "vue";
import { taskApi } from "../../../generated/api";
import type { Task, TaskListParams } from "../../../generated/models";
import { useModelApi } from "../../../shared/composables/useModelApi";
import RemoteImage from "../../../shared/components/RemoteImage.vue";

const props = defineProps<{
  contractId: number;
}>();

const {
  items: tasks,
  loading,
  error,
  load,
} = useModelApi(taskApi, {
  loadErrorMessage: "Не удалось загрузить поручения",
  autoLoad: false,
  autoLoadOnFilterChange: false,
});

const expandedTasks = ref<Record<number, boolean>>({});

const hasTasks = computed(() => tasks.value.length > 0);

function taskTitle(task: Task) {
  return task.text?.trim() || task.result?.trim() || `Задача #${task.id}`;
}

function personName(
  person: { short_name?: string | null; name?: string | null } | null,
) {
  if (!person) {
    return "не указан";
  }

  return person.short_name ?? person.name ?? "не указан";
}

function personAvatar(person: { avatar_small?: string | null } | null) {
  return person?.avatar_small ?? "";
}

function isHistoryExpanded(taskId: number) {
  return expandedTasks.value[taskId] ?? false;
}

function toggleHistory(taskId: number) {
  expandedTasks.value = {
    ...expandedTasks.value,
    [taskId]: !isHistoryExpanded(taskId),
  };
}

function visibleMessages(task: Task) {
  const messages = task.message_set ?? [];

  if (isHistoryExpanded(task.id)) {
    return messages;
  }

  return messages.length > 0 ? [messages[messages.length - 1]] : [];
}

function statusType(statusClass: string) {
  if (/success|done|complete|green/i.test(statusClass)) {
    return "success";
  }

  if (/warning|pending|wait|yellow|orange/i.test(statusClass)) {
    return "warning";
  }

  if (/danger|error|red|fail/i.test(statusClass)) {
    return "danger";
  }

  return "primary";
}

function statusTone(statusClass: string) {
  if (/success|done|complete|green/i.test(statusClass)) {
    return "success";
  }

  if (/warning|pending|wait|yellow|orange/i.test(statusClass)) {
    return "warning";
  }

  if (/danger|error|red|fail/i.test(statusClass)) {
    return "danger";
  }

  return "primary";
}

function loadTasks() {
  const params = {
    contract: props.contractId,
    ordering: "-id",
  } as TaskListParams;

  return load(params);
}

watch(
  () => props.contractId,
  () => {
    void loadTasks();
  },
);

onMounted(() => {
  void loadTasks();
});
</script>

<template>
  <section class="approval-tasks">
    <van-notice-bar
      v-if="error"
      class="approval-tasks__error"
      color="#991b1b"
      background="#fee2e2"
      left-icon="warning-o"
      wrapable
      :scrollable="false"
      :text="error"
    />

    <van-loading v-if="loading" class="approval-tasks__state" type="spinner">
      Загрузка поручений...
    </van-loading>

    <van-empty v-else-if="!hasTasks" description="Поручений пока нет" />

    <div v-else class="approval-task-list">
      <article
        v-for="task in tasks"
        :key="task.id"
        :class="[
          'approval-task-card',
          `approval-task-card--${statusTone(task.get_status_class)}`,
        ]"
      >
        <div class="approval-task-head">
          <div class="approval-task-head__main">
            <div class="approval-task-title">{{ taskTitle(task) }}</div>
            <div class="approval-task-meta">
              ID {{ task.id }} · {{ task.deadline }}
            </div>
          </div>
          <van-tag plain :type="statusType(task.get_status_class)">
            {{ task.get_status }}
          </van-tag>
        </div>

        <van-cell-group inset>
          <div class="approval-person-list">
            <div class="approval-person-item">
              <RemoteImage
                class="approval-person-avatar"
                round
                width="32"
                height="32"
                :src="personAvatar(task.doer)"
              />
              <div class="approval-person-body">
                <div class="approval-person-role">Исполнитель</div>
                <div class="approval-person-name">
                  {{ personName(task.doer) }}
                </div>
              </div>
            </div>

            <div class="approval-person-item">
              <RemoteImage
                class="approval-person-avatar"
                round
                width="32"
                height="32"
                :src="personAvatar(task.author)"
              />
              <div class="approval-person-body">
                <div class="approval-person-role">Автор</div>
                <div class="approval-person-name">
                  {{ personName(task.author) }}
                </div>
              </div>
            </div>

            <div class="approval-person-item">
              <RemoteImage
                class="approval-person-avatar"
                round
                width="32"
                height="32"
                :src="personAvatar(task.responsible)"
              />
              <div class="approval-person-body">
                <div class="approval-person-role">Ответственный</div>
                <div class="approval-person-name">
                  {{ personName(task.responsible) }}
                </div>
              </div>
            </div>
          </div>
        </van-cell-group>

        <div class="approval-task-messages">
          <div class="approval-task-messages__title">Сообщения</div>

          <van-empty
            v-if="!task.message_set?.length"
            description="Сообщений пока нет"
            image-size="64"
          />

          <div v-else class="approval-message-list">
            <article
              v-for="message in visibleMessages(task)"
              :key="message.id"
              :class="[
                'approval-message-item',
                !isHistoryExpanded(task.id) &&
                message.id ===
                  task.message_set?.[task.message_set.length - 1]?.id
                  ? 'approval-message-item--latest'
                  : '',
              ]"
              @click="
                message.id ===
                  task.message_set?.[task.message_set.length - 1]?.id &&
                !isHistoryExpanded(task.id)
                  ? toggleHistory(task.id)
                  : undefined
              "
            >
              <RemoteImage
                class="approval-message-avatar"
                round
                width="36"
                height="36"
                :src="message.author.avatar_small"
              />

              <div class="approval-message-body">
                <div class="approval-message-head">
                  <div class="approval-message-author">
                    {{ personName(message.author) }}
                  </div>
                  <div class="approval-message-meta">
                    {{ message.date }} · {{ message.status }}
                  </div>
                </div>
                <div class="approval-message-text">{{ message.text }}</div>
                <div class="approval-message-recipient">
                  Кому: {{ personName(message.recipient) }}
                </div>
              </div>
            </article>

            <van-button
              v-if="(task.message_set?.length ?? 0) > 1"
              class="approval-message-toggle"
              size="small"
              round
              plain
              type="primary"
              @click.stop="toggleHistory(task.id)"
            >
              <van-icon
                :name="isHistoryExpanded(task.id) ? 'arrow-up' : 'arrow-down'"
              />
            </van-button>
          </div>
        </div>
      </article>
    </div>
  </section>
</template>

<style scoped>
.approval-tasks {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 8px 0 0;
}

.approval-tasks__state {
  display: flex;
  justify-content: center;
  padding: 24px 0;
}

.approval-task-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.approval-task-card {
  overflow: hidden;
  border-radius: 16px;
  background: #fff;
  box-shadow: 0 8px 24px rgba(36, 42, 56, 0.08);
}

.approval-task-card--success {
  background: #f0fdf4;
}

.approval-task-card--warning {
  background: #fffbeb;
}

.approval-task-card--danger {
  background: #fef2f2;
}

.approval-task-card--primary {
  background: #eff6ff;
}

.approval-task-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px 10px;
}

.approval-task-head__main {
  min-width: 0;
}

.approval-task-title {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.35;
  word-break: break-word;
}

.approval-task-meta {
  margin-top: 4px;
  color: #6b7280;
  font-size: 12px;
}

.approval-task-messages {
  padding: 12px 16px 16px;
}

.approval-person-list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
  padding: 8px 10px;
}

.approval-person-item {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.approval-person-avatar {
  flex: none;
}

.approval-person-body {
  min-width: 0;
  flex: 1;
}

.approval-person-role {
  color: #6b7280;
  font-size: 10px;
  line-height: 1.2;
}

.approval-person-name {
  margin-top: 1px;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.35;
  word-break: break-word;
}

.approval-task-messages__title {
  margin-bottom: 10px;
  color: #374151;
  font-size: 13px;
  font-weight: 600;
}

.approval-message-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.approval-message-item {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}

.approval-message-item--latest {
  cursor: pointer;
}

.approval-message-avatar {
  flex: none;
  margin-top: 2px;
}

.approval-message-body {
  min-width: 0;
  flex: 1;
}

.approval-message-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}

.approval-message-author {
  font-weight: 600;
  font-size: 13px;
}

.approval-message-meta,
.approval-message-recipient {
  color: #6b7280;
  font-size: 11px;
}

.approval-message-toggle {
  width: 28px;
  height: 28px;
  margin-top: 8px;
  padding: 0;
}

.approval-message-text {
  margin-top: 4px;
  white-space: pre-wrap;
  word-break: break-word;
  font-size: 13px;
  line-height: 1.45;
}
</style>
