<script setup lang="ts">
import { invoke } from "@tauri-apps/api/core";
import { computed, onMounted, ref } from "vue";
import { useRoute } from "vue-router";
import { showToast } from "vant";
import { billApi } from "../../../generated/api";
import { useModelApi } from "../../../shared/composables/useModelApi";
import DocumentApprovalTasks from "../../../shared/components/DocumentApprovalTasks.vue";

const route = useRoute();
const billId = computed(() => Number(route.params.id));
const activeTab = ref("info");

const {
  item: bill,
  loadingItem,
  error,
  retrieve: loadBill,
} = useModelApi(billApi, {
  retrieveErrorMessage: "Не удалось загрузить счет",
  autoLoad: false,
  autoLoadOnFilterChange: false,
});

type BillRelated = Record<string, unknown>;

function parseJson(value: unknown): unknown {
  if (typeof value === "string") {
    if (!value.trim()) {
      return null;
    }

    try {
      return JSON.parse(value) as unknown;
    } catch {
      return null;
    }
  }

  return value;
}

function parseObject(value: unknown): BillRelated | null {
  const parsed = parseJson(value);
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
    return null;
  }

  return parsed as BillRelated;
}

function objectLabel(value: unknown) {
  const record = parseObject(value);
  if (!record) {
    return "не указано";
  }

  const candidates = ["name", "short_name", "number", "text", "full_name", "get_status_display"];
  for (const key of candidates) {
    const candidate = record[key];
    if (typeof candidate === "string" && candidate.trim()) {
      return candidate;
    }
  }

  return "не указано";
}

function money(value: number | null | undefined) {
  if (typeof value !== "number") {
    return "не указано";
  }

  return new Intl.NumberFormat("ru-RU", {
    style: "currency",
    currency: "RUB",
    maximumFractionDigits: 2,
  }).format(value);
}

function formatValue(value: unknown) {
  if (value === null || value === undefined || value === "") {
    return "не указано";
  }

  return String(value);
}

async function openScan() {
  if (!bill.value?.scan) {
    showToast("У счета нет файла");
    return;
  }

  await invoke("open_remote_file", { url: bill.value.scan });
}

function relatedDocuments() {
  const raw = parseJson(bill.value?.transferdocument_set);
  if (!Array.isArray(raw)) {
    return [];
  }

  return raw;
}

onMounted(() => {
  if (Number.isFinite(billId.value)) {
    loadBill(billId.value);
  }
});
</script>

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

  <section class="card detail-card">
    <van-loading v-if="loadingItem" class="state" type="spinner">Загрузка...</van-loading>

    <van-empty v-else-if="!bill" description="Счет не найден" />

    <template v-else>
      <div class="bill-summary">
        <div class="bill-summary__title">{{ bill.text || bill.number || `Счет #${bill.id}` }}</div>
        <div class="bill-summary__meta">
          № {{ bill.number || 'не указан' }} · {{ bill.date_bill || bill.date }}
        </div>
        <div class="bill-summary__badges">
          <van-tag type="primary">{{ bill.status_name || bill.status }}</van-tag>
          <van-tag plain>{{ bill.contract_typ || 'не указан' }}</van-tag>
        </div>
        <van-cell-group inset>
          <van-cell>
            <template #title>
              <div class="detail-cell">
                <div class="detail-label">Контрагент</div>
                <div class="detail-value">{{ objectLabel(bill.counterparty) }}</div>
              </div>
            </template>
          </van-cell>
          <van-cell>
            <template #title>
              <div class="detail-cell">
                <div class="detail-label">Проект</div>
                <div class="detail-value">{{ objectLabel(bill.project) }}</div>
              </div>
            </template>
          </van-cell>
          <van-cell>
            <template #title>
              <div class="detail-cell">
                <div class="detail-label">Договор</div>
                <div class="detail-value">{{ objectLabel(bill.contract) }}</div>
              </div>
            </template>
          </van-cell>
          <van-cell>
            <template #title>
              <div class="detail-cell">
                <div class="detail-label">Сумма</div>
                <div class="detail-value detail-value--money">{{ money(bill.cost) }}</div>
              </div>
            </template>
          </van-cell>
        </van-cell-group>
      </div>

      <van-tabs v-model:active="activeTab" shrink sticky class="bill-tabs">
        <van-tab name="info" title="Информация">
          <div class="tab-panel">
            <van-cell-group>
              <van-cell title="Номер" :value="formatValue(bill.number)" />
              <van-cell title="Описание" :value="formatValue(bill.text)" />
              <van-cell title="Дата счета" :value="formatValue(bill.date_bill)" />
              <van-cell title="Дата" :value="formatValue(bill.date)" />
              <van-cell title="Срок оплаты" :value="formatValue(bill.date_due)" />
              <van-cell title="Статус" :value="bill.status_name || bill.status" />
              <van-cell title="Тип" :value="formatValue(bill.contract_typ)" />
              <van-cell title="Комментарий" :value="formatValue(bill.comment)" />
            </van-cell-group>
          </div>
        </van-tab>

        <van-tab name="finance" title="Финансы">
          <div class="tab-panel">
            <van-cell-group>
              <van-cell title="Сумма" :value="money(bill.cost)" />
              <van-cell title="Оплачено" :value="money(bill.paid)" />
              <van-cell title="К оплате" :value="money(bill.to_payd)" />
              <van-cell title="НДС" :value="money(bill.nds_cost)" />
              <van-cell title="Реестр" :value="bill.pp_maked ? 'Да' : 'Нет'" />
              <van-cell title="Архив" :value="bill.archive_s ? 'Да' : 'Нет'" />
            </van-cell-group>
          </div>
        </van-tab>

        <van-tab name="relations" title="Связи">
          <div class="tab-panel">
            <van-cell-group>
              <van-cell title="Контрагент" :value="objectLabel(bill.counterparty)" />
              <van-cell title="Проект" :value="objectLabel(bill.project)" />
              <van-cell title="Договор" :value="objectLabel(bill.contract)" />
              <van-cell title="ФРЦ" :value="objectLabel(bill.frc)" />
              <van-cell title="Ответственный" :value="objectLabel(bill.responsible)" />
              <van-cell title="Автор" :value="objectLabel(bill.author)" />
              <van-cell title="Категория" :value="objectLabel(bill.category)" />
            </van-cell-group>

            <van-cell-group v-if="relatedDocuments().length" title="Документы">
              <van-cell v-for="(doc, index) in relatedDocuments()" :key="String((doc as Record<string, unknown>).id ?? index)">
                <template #title>
                  <div class="detail-cell">
                    <div class="detail-label">{{ String((doc as Record<string, unknown>).number ?? 'Документ') }}</div>
                    <div class="detail-value">
                      {{ String((doc as Record<string, unknown>).date ?? '') }}
                      {{ (doc as Record<string, unknown>).cost ? `· ${formatValue((doc as Record<string, unknown>).cost)}` : '' }}
                    </div>
                  </div>
                </template>
              </van-cell>
            </van-cell-group>
          </div>
        </van-tab>

        <van-tab name="approval" title="Согласование">
          <div class="tab-panel">
            <DocumentApprovalTasks
              v-if="bill"
              :document-id="bill.id"
              filter-name="bill"
              title="Согласование счета"
            />
          </div>
        </van-tab>

        <van-tab name="file" title="Файл">
          <div class="tab-panel">
            <van-empty v-if="!bill.scan" description="Файл не прикреплен" />
            <div v-else class="form-actions stacked-actions">
              <van-button block round type="primary" plain @click="openScan">
                Открыть файл
              </van-button>
            </div>
          </div>
        </van-tab>
      </van-tabs>
    </template>
  </section>
</template>

<style scoped>
.bill-summary {
  padding: 16px 16px 10px;
}

.bill-summary__title {
  font-size: 22px;
  font-weight: 700;
  line-height: 1.25;
}

.bill-summary__meta {
  margin-top: 4px;
  color: var(--van-text-color-2);
  font-size: 13px;
}

.bill-summary__badges {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}
</style>
