<script setup>
import {computed, onMounted, ref} from 'vue';
import {useAuthStore} from '@/stores/Auth.js';
import {useRoleStore} from '@/stores/RoleStore.js';
import {useRouter} from 'vue-router';

const router = useRouter();
const authStore = useAuthStore();
const roleStore = useRoleStore();
const users = ref([]);
const points = ref([]);
const rawLogs = ref([])
const expanded = ref({});
const roles = ref([]);
const meta = ref({current_page: 1, last_page: 1});
const page = ref(1);

// ---- новые фильтры ----
const filterObject   = ref('')
const filterAction   = ref('')
const filterAuthorId = ref(null)
const filterDateFrom = ref('')
const filterDateTo   = ref('')
const objects = ref([]);
const usersGrouped = ref({});
const usersList = computed(() =>
    Object.values(usersGrouped.value).flat().map(u => ({
      id: u.id,
      full_name: [u.last_name, u.first_name, u.middle_name].filter(Boolean).join(' ')
    }))
)

// Запрос логов
async function getLogs(p = 1) {
  page.value = p

  // Собираем все возможные параметры
  const all = {
    page:      p,
    object:    filterObject.value,
    action:    filterAction.value,
    author_id: filterAuthorId.value,
    date_from: filterDateFrom.value,
    date_to:   filterDateTo.value,
  }

  // Очищаем от undefined, null и пустых строк
  const params = Object.fromEntries(
      Object.entries(all)
          .filter(([_, v]) => v !== null && v !== undefined && v !== '')
  )

  const { response, error } = await authStore.getLogs(params)
  if (!error) {
    rawLogs.value = response.data.logs
    meta.value    = response.data.meta
  }
}

function resetFilters() {
  filterObject.value = ''
  filterAction.value = ''
  filterAuthorId.value = null
  filterDateFrom.value = ''
  filterDateTo.value = ''
  getLogs(1)
}

// Запрос пользователей для отображения ФИО
const getUsers = async () => {
  const {response, error} = await authStore.getUsers();
  if (!error) {
    // API возвращает сгруппированный объект, нужно плоский массив
    const data = response.data.data || response.data;
    // если это не массив, собираем все значения групп
    users.value = Array.isArray(data) ? data : Object.values(data).flat();
  }
};



// Запрос точек для отображения названий
const getPoints = async () => {
  const {response, error} = await authStore.getPointNames()
  if (!error) points.value = response.data.points
}

onMounted(async () => {
  const { objects: objs, error: objErr } = await authStore.fetchLogObjects();
  if (!objErr) objects.value = objs;

  await Promise.all([getUsers(), getPoints(), getRoles(), getLogs(page.value)]);
});

async function getRoles() {
  await roleStore.fetchRoles();
  roles.value = roleStore.roles;
}

const getRoleName = (id) => {
  const r = roles.value.find(r => r.id === id);
  return r ? r.name : '—';
};

// Сбор изменений по каждому логу
const getChanges = (log) => {
  const changes = [];
  if (log.description === 'created') {
    Object.entries(log.new).forEach(([k, v]) => changes.push({field: k, old: null, new: v}));
  } else if (log.description === 'deleted') {
    Object.entries(log.old).forEach(([k, v]) => changes.push({field: k, old: v, new: null}));
  } else {
    Object.keys({...log.old, ...log.new}).forEach(k => {
      const o = log.old[k] ?? null;
      const n = log.new[k] ?? null;
      if (o !== n) changes.push({field: k, old: o, new: n});
    });
  }
  return changes;
};

// Формат даты/времени
const formatDateTime = (dt) => {
  const d = new Date(dt);
  const pad = n => n.toString().padStart(2, '0');
  return `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())} ` +
      `${pad(d.getDate())}.${pad(d.getMonth() + 1)}.${d.getFullYear()}`;
};

// Получаем ФИО пользователя по id
const getUserFullName = (id) => {
  const list = Array.isArray(users.value) ? users.value : [];
  const u = list.find(u => u.id === id);
  return u ? `${u.last_name} ${u.first_name} ${u.middle_name}`.trim() : '—';
};

// Получаем название точки по id
const getPointName = (id) => {
  const p = points.value.find(p => p.id === id);
  return p ? p.record_number + ' ' + p.name : '—';
};

const groupedLogs = computed(() =>
    rawLogs.value.map(log => ({isGroup: false, log}))
);

const filteredLogs = computed(() =>
    rawLogs.value
        // оставляем только те, где НЕ (log_name="Замеры интенсивности" & description="created" & new.count===0)
        .filter(l =>
            !(
                l.log_name === 'Замеры интенсивности' &&
                l.description === 'created' &&
                (l.new.count ?? 0) === 0
            )
        )
)

// Генерируем массив для пагинации
const pagesList = computed(() => {
  const total = meta.value.last_page
  const current = page.value
  const delta = 2  // сколько страниц показывать вокруг current

  if (total <= 1) return []

  const range = []
  const rangeWithDots = []

  for (let i = 1; i <= total; i++) {
    if (
        i === 1 ||
        i === total ||
        (i >= current - delta && i <= current + delta)
    ) {
      range.push(i)
    }
  }

  let last = 0
  for (const i of range) {
    if (i - last > 1) {
      rangeWithDots.push('…')
    }
    rangeWithDots.push(i)
    last = i
  }

  return rangeWithDots
})
</script>

<template>
  <div class="table-responsive p-3">
    <!-- Форма фильтра -->
    <div class="row g-2 align-items-end mb-4">
      <div class="col-auto">
        <label class="form-label">Объект</label>
        <select v-model="filterObject" class="form-select">
          <option value="">Все</option>
          <option v-for="o in objects" :key="o" :value="o">
            {{ o }}
          </option>
        </select>
      </div>

      <div class="col-auto">
        <label class="form-label">Действие</label>
        <select v-model="filterAction" class="form-select">
          <option value="">Все</option>
          <option value="created">created</option>
          <option value="updated">updated</option>
          <option value="deleted">deleted</option>
        </select>
      </div>

      <div class="col-auto">
        <label class="form-label">Автор</label>
        <select v-model="filterAuthorId" class="form-select">
          <option :value="null">Все</option>
          <option v-for="u in users" :key="u.id" :value="u.id">
            {{ [ u.last_name, u.first_name, u.middle_name ].filter(Boolean).join(' ') }}
          </option>
        </select>
      </div>

      <div class="col-auto">
        <label class="form-label">Дата с</label>
        <input type="date" v-model="filterDateFrom" class="form-control" />
      </div>

      <div class="col-auto">
        <label class="form-label">Дата по</label>
        <input type="date" v-model="filterDateTo" class="form-control" />
      </div>

      <div class="col-auto">
        <button @click="getLogs(1)"    class="btn btn-primary">Применить</button>
        <button @click="resetFilters"  class="btn btn-outline-secondary">Сбросить</button>
      </div>
    </div>
    <!-- пагинация -->
    <nav aria-label="Logs pagination" class="mt-3">
      <ul class="pagination justify-content-center flex-wrap">
        <!-- Prev -->
        <li class="page-item" :class="{ disabled: page===1 }">
          <a class="page-link" href="#" @click.prevent="getLogs(page-1)">Prev</a>
        </li>

        <!-- Умный список страниц -->
        <li
            v-for="item in pagesList"
            :key="item + '-' + page"
            class="page-item"
            :class="{ active: item === page }"
            :aria-disabled="item === '…'"
        >
          <template v-if="item === '…'">
            <span class="page-link">…</span>
          </template>
          <template v-else>
            <a
                class="page-link"
                href="#"
                @click.prevent="getLogs(item)"
            >{{ item }}</a>
          </template>
        </li>

        <!-- Next -->
        <li class="page-item" :class="{ disabled: page===meta.last_page }">
          <a class="page-link" href="#" @click.prevent="getLogs(page+1)">Next</a>
        </li>
      </ul>
    </nav>
    <table class="table table-striped table-hover align-middle">
      <thead class="table-dark">
      <tr>
        <th>Объект</th>
        <th>Действие</th>
        <th>Изменения</th>
        <th>Когда</th>
        <th>Кто</th>
      </tr>
      </thead>
      <tbody>
      <template v-for="row in filteredLogs" :key="row.id">
        <tr>
          <td>
            <span class="fw-bold text-primary">{{ row.log_name }}</span><br>
            <small>
              <template v-if="row.subject.type === 'User'">
                {{ getUserFullName(row.subject.id) }}
              </template>
              <template v-else>
                №{{ row.subject.id }}
              </template>
            </small>
          </td>
          <td class="text-capitalize">{{ row.description }}</td>
          <td>
            <div class="changes-list">
              <div v-for="c in getChanges(row)" :key="c.field" class="change-item">
                <span class="field-name">{{ c.field }}</span>
                <span class="old-value" v-if="c.old !== null">
                  «{{ c.old }}»
                  <template
                      v-if="c.field === 'user_id' || c.field === 'signed_by' || c.field === 'subgroup_manager_id'">
                    &nbsp;(<small>{{ getUserFullName(c.old) }}</small>)
                  </template>
                  <template v-if="c.field === 'point_id'">
                    &nbsp;(<small>{{ getPointName(c.old) }}</small>)
                  </template>
                  <template v-if="c.field==='role_id'"> (<small>{{ getRoleName(c.old) }}</small>)</template>
                </span>
                <span class="arrow">→</span>
                <span class="new-value" v-if="c.new !== null">
                  «{{ c.new }}»
                  <template
                      v-if="c.field === 'user_id' || c.field === 'signed_by' || c.field === 'subgroup_manager_id'">
                    &nbsp;(<small>{{ getUserFullName(c.new) }}</small>)
                  </template>
                <template v-if="c.field === 'point_id'">
                    &nbsp;(<small>{{ getPointName(c.new) }}</small>)
                  </template>
                  <template v-if="c.field==='role_id'"> (<small>{{ getRoleName(c.new) }}</small>)</template>
                </span>
              </div>
            </div>
          </td>
          <td>{{ formatDateTime(row.created_at) }}</td>
          <td>{{ row.causer?.name || '—' }}</td>
        </tr>
      </template>
      </tbody>
    </table>
    <!-- пагинация -->
    <nav aria-label="Logs pagination" class="mt-3">
      <ul class="pagination justify-content-center flex-wrap">
        <!-- Prev -->
        <li class="page-item" :class="{ disabled: page===1 }">
          <a class="page-link" href="#" @click.prevent="getLogs(page-1)">Prev</a>
        </li>

        <!-- Умный список страниц -->
        <li
            v-for="item in pagesList"
            :key="item + '-' + page"
            class="page-item"
            :class="{ active: item === page }"
            :aria-disabled="item === '…'"
        >
          <template v-if="item === '…'">
            <span class="page-link">…</span>
          </template>
          <template v-else>
            <a
                class="page-link"
                href="#"
                @click.prevent="getLogs(item)"
            >{{ item }}</a>
          </template>
        </li>

        <!-- Next -->
        <li class="page-item" :class="{ disabled: page===meta.last_page }">
          <a class="page-link" href="#" @click.prevent="getLogs(page+1)">Next</a>
        </li>
      </ul>
    </nav>
  </div>
</template>

<style scoped>
.table {
  border-radius: 8px;
  overflow: hidden;
}

.table-striped tbody tr:nth-of-type(odd) {
  background-color: #f9f9f9;
}

.changes-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.change-item {
  white-space: nowrap;
}

.field-name {
  font-weight: 600;
  color: #0d6efd;
}

.old-value {
  color: #6c757d;
  text-decoration: line-through;
}

.arrow {
  margin: 0 4px;
  color: #6c757d;
}

.new-value {
  font-weight: 500;
  color: #198754;
}
</style>
