<script setup lang="ts">
import { computed, ref } from "vue";
import { showToast } from "vant";
import { messageApi } from "../../generated/api";
import type { Employee, MessageCreate, Task } from "../../generated/models";
import RemoteImage from "./RemoteImage.vue";

type ApprovalMessage = {
  id: number;
  author: Employee;
  recipient: Employee;
  text: string;
  date: string;
  status: string;
  task: number;
};

type ApprovalTask = Omit<Task, "message_set"> & {
  message_set?: ApprovalMessage[] | null;
};

type ReplyMode = "success" | "failure";

const props = defineProps<{
  task: ApprovalTask;
  currentEmployeeId: number | null;
}>();

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

const executorSuccessReplies = ["Согласовано", "Ознакомлен", "Выполнено"];
const executorFailureReplies = [
  "Прошу дать объяснение",
  "Обосновать цену",
  "На доработку",
  "Отказ",
];

const expanded = ref(false);
const sendingActionKey = ref("");
const activeReplyForm = ref<ReplyMode | undefined>();
const replyText = ref("");

const isTaskDoer = computed(() =>
  Boolean(props.currentEmployeeId && props.task.doer?.id === props.currentEmployeeId),
);

const isTaskAuthor = computed(() =>
  Boolean(props.currentEmployeeId && props.task.author?.id === props.currentEmployeeId),
);

const hasActionForm = computed(() => isTaskDoer.value && activeReplyForm.value);

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 actionKey(status: string) {
  return `${props.task.id}:${status}`;
}

function taskRecipientId() {
  if (isTaskDoer.value) {
    return props.task.author?.id ?? null;
  }

  if (isTaskAuthor.value) {
    return props.task.doer?.id ?? null;
  }

  return null;
}

function taskMessages() {
  return props.task.message_set ?? [];
}

function visibleMessages() {
  const messages = taskMessages();

  if (expanded.value) {
    return messages;
  }

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

function toggleHistory() {
  expanded.value = !expanded.value;
}

function openReplyForm(mode: ReplyMode) {
  activeReplyForm.value = activeReplyForm.value === mode ? undefined : mode;
  if (!replyText.value) {
    replyText.value = "";
  }
}

function closeReplyForm() {
  activeReplyForm.value = undefined;
  replyText.value = "";
}

function quickReplies(mode: ReplyMode) {
  return mode === "success" ? executorSuccessReplies : executorFailureReplies;
}

function employeeName(employee: Employee | null | undefined) {
  return employee?.name || employee?.short_name || "не указан";
}

function showEmployeeName(employee: Employee | null | undefined) {
  showToast(employeeName(employee));
}

async function sendMessage(status: string, text: string) {
  const key = actionKey(status);
  if (sendingActionKey.value) {
    return;
  }

  const trimmedText = text.trim();
  if (!trimmedText) {
    showToast("Введите сообщение");
    return;
  }

  const recipientId = taskRecipientId();
  if (!recipientId) {
    showToast("Не удалось определить получателя сообщения");
    return;
  }

  sendingActionKey.value = key;

  try {
    const payload: MessageCreate = {
      task: props.task.id,
      recipient: recipientId,
      text: trimmedText,
      status,
    };

    await messageApi.create(payload);
    showToast("Сообщение отправлено");
    closeReplyForm();
    emit("updated");
  } catch (error) {
    showToast(
      error instanceof Error ? error.message : "Не удалось отправить сообщение",
    );
  } finally {
    sendingActionKey.value = "";
  }
}

</script>

<template>
  <article
    :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-row">
          <RemoteImage
            class="approval-person-avatar approval-person-avatar--author"
            round
            width="30"
            height="30"
            :src="task.author?.avatar_small ?? ''"
            :fallback-text="employeeName(task.author)"
            @click.stop="showEmployeeName(task.author)"
          />
          <div class="approval-task-title">
            {{ task.text?.trim() || task.result?.trim() || `Задача #${task.id}` }}
          </div>
        </div>
        <div class="approval-task-meta">ID {{ task.id }} · {{ task.deadline }}</div>
      </div>
      <div class="approval-task-status">
        <van-tag plain :type="statusType(task.get_status_class)">
          {{ task.get_status }}
        </van-tag>
        <div class="approval-status-avatars">
          <RemoteImage
            class="approval-person-avatar"
            round
            width="28"
            height="28"
            :src="task.doer?.avatar_small ?? ''"
            :fallback-text="employeeName(task.doer)"
            @click.stop="showEmployeeName(task.doer)"
          />
          <RemoteImage
            class="approval-person-avatar"
            round
            width="28"
            height="28"
            :src="task.responsible?.avatar_small ?? ''"
            :fallback-text="employeeName(task.responsible)"
            @click.stop="showEmployeeName(task.responsible)"
          />
        </div>
      </div>
    </div>

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

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

      <div v-else class="approval-message-list">
        <article
          v-for="message in visibleMessages()"
          :key="message.id"
          :class="[
            'approval-message-item',
            !expanded && message.id === taskMessages()[taskMessages().length - 1]?.id
              ? 'approval-message-item--latest'
              : '',
          ]"
          @click="
            message.id === taskMessages()[taskMessages().length - 1]?.id && !expanded
              ? toggleHistory()
              : 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">
                {{ message.author.short_name ?? message.author.name ?? 'не указан' }}
              </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">
              Кому: {{ message.recipient.short_name ?? message.recipient.name ?? 'не указан' }}
            </div>
          </div>
        </article>

        <van-button
          v-if="taskMessages().length > 1"
          class="approval-message-toggle"
          size="small"
          round
          plain
          type="primary"
          @click.stop="toggleHistory"
        >
          <van-icon :name="expanded ? 'arrow-up' : 'arrow-down'" />
        </van-button>
      </div>
    </div>

    <div v-if="isTaskDoer" class="approval-task-actions">
      <van-button
        size="small"
        round
        plain
        type="success"
        :loading="sendingActionKey === `${task.id}:S`"
        :disabled="Boolean(sendingActionKey) && sendingActionKey !== `${task.id}:S`"
        @click="openReplyForm('success')"
      >
        Успех
      </van-button>
      <van-button
        size="small"
        round
        plain
        type="danger"
        :loading="sendingActionKey === `${task.id}:F`"
        :disabled="Boolean(sendingActionKey) && sendingActionKey !== `${task.id}:F`"
        @click="openReplyForm('failure')"
      >
        Отказ
      </van-button>
    </div>

    <div v-else-if="isTaskAuthor" class="approval-task-actions">
      <van-button
        size="small"
        round
        plain
        type="warning"
        :loading="sendingActionKey === `${task.id}:R`"
        :disabled="Boolean(sendingActionKey) && sendingActionKey !== `${task.id}:R`"
        @click="sendMessage('R', 'На повторное рассмотрение')"
      >
        На повторное рассмотрение
      </van-button>
      <van-button
        size="small"
        round
        plain
        type="success"
        :loading="sendingActionKey === `${task.id}:S`"
        :disabled="Boolean(sendingActionKey) && sendingActionKey !== `${task.id}:S`"
        @click="sendMessage('S', 'Одобрить')"
      >
        Одобрить
      </van-button>
    </div>

    <div v-if="hasActionForm" class="approval-reply-box">
      <div class="approval-reply-title">
        {{ activeReplyForm === 'success' ? 'Успех' : 'Отказ' }}
      </div>

      <div class="approval-reply-quick">
          <van-button
            v-for="reply in quickReplies((activeReplyForm ?? 'success') as ReplyMode)"
            :key="reply"
            size="small"
            round
            plain
            type="primary"
            @click="activeReplyForm === 'success' ? sendMessage('S', reply) : sendMessage('F', reply)"
          >
            {{ reply }}
          </van-button>
      </div>

      <van-field
        v-model="replyText"
        rows="3"
        autosize
        type="textarea"
        placeholder="Введите сообщение"
        maxlength="500"
        show-word-limit
      />

      <div class="approval-reply-actions">
        <van-button plain size="small" round @click="closeReplyForm()">
          Отмена
        </van-button>
            <van-button
              size="small"
              round
              :type="activeReplyForm === 'success' ? 'success' : 'danger'"
              :loading="sendingActionKey === `${task.id}:${activeReplyForm === 'success' ? 'S' : 'F'}`"
              @click="activeReplyForm === 'success' ? sendMessage('S', replyText) : sendMessage('F', replyText)"
            >
              Отправить
            </van-button>
      </div>
    </div>
  </article>
</template>

<style scoped>
.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-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}

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

.approval-task-status {
  display: flex;
  flex: none;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
}

.approval-status-avatars {
  display: flex;
  align-items: center;
  gap: 6px;
}

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

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

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

.approval-person-avatar--author {
  margin-top: 1px;
}

.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;
}

.approval-task-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 0 16px 16px;
}

.approval-reply-box {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 0 16px 16px;
}

.approval-reply-title {
  color: #374151;
  font-size: 13px;
  font-weight: 600;
}

.approval-reply-quick {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.approval-reply-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}
</style>
