<script lang="ts">
import { defineBasicLoader } from 'unplugin-vue-router/data-loaders/basic';
import { defineColadaLoader } from 'unplugin-vue-router/data-loaders/pinia-colada';

async function getUserById(userId: string, { signal }: { signal?: AbortSignal }) {
  console.warn('[getUserById] 被调用, userId :>> ', userId);
  setTimeout(() => {
    console.log('10s 已过', 'userId :>> ', userId);
  }, 1000 * 10);
  const res = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`, { signal });
  await new Promise((resolve) => setTimeout(resolve, 300));
  return await res.json();
}

export const useUserData = defineColadaLoader('DataLoadersIdSub1UserId', {
  async query(to, { signal }) {
    console.debug('[defineColadaLoader] query');
    return getUserById(to.params.userId, { signal });
  },
  key: (to) => ['users', to.params.userId],
  // Keep the data "fresh" 10 seconds to avoid fetching the same data too often
  // 保持数据“新鲜”10秒，以避免过于频繁地获取相同的数据
  staleTime: 1000 * 10,
});

export const usePageData = defineBasicLoader('DataLoadersIdSub1UserId', async (route) => {
  console.warn('[defineBasicLoader] 被调用, userId :>> ', route.params.userId);
  await new Promise((resolve) => setTimeout(resolve, 777));
  return { idFromPreviousPage: route.params.id, someOtherData: 'someOtherData' };
});
</script>

<script setup lang="ts">
const { data: user, status, error, isLoading, reload, refresh } = useUserData();

const route = useRoute('DataLoadersIdSub1UserId');
</script>

<template>
  <div flex="~ row">
    <button class="green" @click="$router.back()">Back</button>
  </div>
  <h1>Pinia Colada Loader Example</h1>
  <pre>route.params: {{ route.params }}</pre>

  <fieldset class="flex items-center gap-4">
    <legend>Controls</legend>

    <button @click="refresh()">Refresh</button>
    <button @click="reload()">Refetch</button>
  </fieldset>

  <div class="flex items-center">
    <RouterLink :to="{ params: { userId: (Number(route.params.userId) || 0) - 1 } }">
      Previous
      {{ (Number(route.params.userId) || 0) - 1 }}
    </RouterLink>
    |
    <RouterLink :to="{ params: { userId: (Number(route.params.userId) || 0) + 1 } }">
      Next {{ (Number(route.params.userId) || 0) + 1 }}
    </RouterLink>
  </div>

  <h2>State</h2>

  <p>
    <code>status: {{ status }}</code>
    <br />
    <code>isLoading: {{ isLoading }}</code>
  </p>
  <pre v-if="error">Error: {{ error }}</pre>
  <pre v-else>{{ user == null ? String(user) : user }}</pre>
</template>

<style scoped lang="less">
button {
  padding: 0.5rem 1rem;
  border-radius: 4px;
  border: 1px solid #ccc;
  background: #f5f5f5;
  cursor: pointer;
  transition: all 0.2s;

  &:hover {
    background: #e5e5e5;
  }

  &.green {
    background: #4caf50;
    color: white;
    border-color: #45a049;

    &:hover {
      background: #45a049;
    }
  }

  @media (prefers-color-scheme: dark) {
    background: #2a2a2a;
    border-color: #444;
    color: #fff;

    &:hover {
      background: #333;
    }

    &.green {
      background: #2e7d32;
      border-color: #1b5e20;

      &:hover {
        background: #1b5e20;
      }
    }
  }
}

fieldset {
  border: 1px solid #ddd;
  border-radius: 6px;
  padding: 1rem;
  margin: 1rem 0;

  legend {
    padding: 0 0.5rem;
  }

  @media (prefers-color-scheme: dark) {
    border-color: #444;
    background: #1a1a1a;
  }
}

pre {
  background: #f8f8f8;
  padding: 1rem;
  border-radius: 4px;
  overflow-x: auto;

  @media (prefers-color-scheme: dark) {
    background: #1a1a1a;
    color: #e0e0e0;
  }
}

.flex.items-center {
  a {
    color: #2196f3;
    text-decoration: none;
    padding: 0.5rem;

    &:hover {
      text-decoration: underline;
    }

    @media (prefers-color-scheme: dark) {
      color: #64b5f6;

      &:hover {
        color: #90caf9;
      }
    }
  }
}

code {
  background: #f1f1f1;
  padding: 0.2rem 0.4rem;
  border-radius: 3px;

  @media (prefers-color-scheme: dark) {
    background: #2a2a2a;
    color: #e0e0e0;
  }
}

@media (prefers-color-scheme: dark) {
  :deep(body) {
    background: #121212;
    color: #e0e0e0;
  }
}
</style>

<route lang="yaml">
meta:
  layout: second
</route>
