import { computed, onMounted, reactive, ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import { usageAPI } from "@/api";
import { useConsoleViewState } from "@/composables/useConsoleViewState";
import { useUserAuditWorkspace } from "@/composables/admin/useUserAuditWorkspace";
import {
  auditKey, formatDate, formatNumber, formatSigned, ledgerColumns,
  metadataPreview, userColumns, userKey, usageColumns,
} from "@/composables/admin/usersWorkspacePresentation";
import type {
  AccessUserStatus, AdminBillingUserDetail, AdminBillingUserSummary,
  ApiKeyRecord, AuthUser, BillingPlanDetail, ResourceEntitlementSummary,
  UsageLedgerRow, UsageReservationRow,
} from "@/types";

export function useUsersWorkspace() {
const route = useRoute();
const router = useRouter();
const viewState = useConsoleViewState<"list" | "grid">({
  view: "list",
  viewValues: ["list", "grid"],
  tab: "profile",
});
const users = ref<AdminBillingUserSummary[]>([]);
const plans = ref<BillingPlanDetail[]>([]);
const detail = ref<AdminBillingUserDetail | null>(null);
const selectedUserId = ref<string | null>(
  typeof route.params.userId === "string" ? route.params.userId : null,
);
const loading = ref(true);
const loaded = ref(false);
const detailLoading = ref(false);
const error = ref<string | null>(null);
const mutationError = ref<string | null>(null);
const pending = ref<string | null>(null);
const page = ref(Math.max(1, Number(route.query.cursor) || 1));
const pageSize = 25;
const total = ref(0);
const stateAuthority = ref("pk01-postgres");
const createOpen = ref(false);
  const audit = useUserAuditWorkspace();
const filters = reactive({
  search: textQuery("q"),
  status: textQuery("filter"),
  role: textQuery("role"),
});
const createForm = reactive({
  email: "",
  username: "",
  displayName: "",
  password: "",
  role: "user",
  status: "active",
  initialCredits: 0,
});
const editForm = reactive({
  email: "",
  username: "",
  displayName: "",
  password: "",
  role: "user",
  status: "active",
  planId: "default",
});
const creditForm = reactive({
  deltaCredits: 0,
  reason: "admin_adjust",
  idempotencyKey: "",
});
let usersRequestSequence = 0;
let detailRequestSequence = 0;

const selectedSummary = computed(
  () =>
    detail.value?.summary ??
    users.value.find((item) => item.user?.id === selectedUserId.value) ??
    null,
);
const selectedUser = computed(() => selectedSummary.value?.user ?? null);
const selectedEntitlements = computed<ResourceEntitlementSummary[]>(
  () => selectedSummary.value?.entitlements ?? [],
);
const ledgerRows = computed<UsageLedgerRow[]>(
  () => detail.value?.ledger?.rows ?? [],
);
const apiKeys = computed<ApiKeyRecord[]>(
  () => detail.value?.apiKeys?.keys ?? [],
);
const reservations = computed<UsageReservationRow[]>(
  () =>
    detail.value?.reservations?.rows ??
    detail.value?.reservations?.active ??
    selectedSummary.value?.reservations?.active ??
    [],
);
const viewMode = computed({
  get: () => viewState.view.value,
  set: (value: "list" | "grid") =>
    void viewState.update(
      { view: value === "list" ? undefined : value },
      false,
    ),
});
const density = computed({
  get: () => viewState.density.value,
  set: (value: "compact" | "comfortable") =>
    void viewState.update(
      { density: value === "comfortable" ? undefined : value },
      false,
    ),
});
const detailTab = computed({
  get: () => viewState.tab.value || "profile",
  set: (value: string) =>
    void viewState.update(
      { tab: value === "profile" ? undefined : value },
      false,
    ),
});
const asyncState = computed(() =>
  loading.value
    ? users.value.length
      ? "refreshing"
      : "initial-loading"
    : error.value
      ? users.value.length
        ? "partial"
        : "error"
      : loaded.value
        ? "ready"
        : "empty",
);
const statusItems = computed(() => [
  { id: "users", label: "Users", value: total.value },
  {
    id: "active",
    label: "Active on page",
    value: users.value.filter((item) => item.user?.status === "active").length,
    tone: "ok" as const,
  },
  { id: "authority", label: "Authority", value: stateAuthority.value },
  {
    id: "selected",
    label: "Selected",
    value: selectedUser.value?.username || "-",
  },
]);

  onMounted(async () => {
    await Promise.all([loadPlans(), loadUsers(false), audit.loadAudit(false)]);
    if (selectedUserId.value) await selectUser(selectedUserId.value, false);
  });

  watch(
    () => route.params.userId,
    (value) => {
      const userId = typeof value === "string" ? value : "";
      if (userId && userId !== selectedUserId.value) void selectUser(userId, false);
      if (!userId) {
        detailRequestSequence += 1;
        selectedUserId.value = null;
        detail.value = null;
        detailLoading.value = false;
      }
    },
  );
  watch(
    () => route.query,
    () => {
      const nextPage = Math.max(1, Number(route.query.cursor) || 1);
      const changed = filters.search !== textQuery("q") ||
        filters.status !== textQuery("filter") ||
        filters.role !== textQuery("role") || page.value !== nextPage;
      if (!changed) return;
      filters.search = textQuery("q");
      filters.status = textQuery("filter");
      filters.role = textQuery("role");
      page.value = nextPage;
      void loadUsers(false);
    },
  );

function textQuery(key: string): string {
  return typeof route.query[key] === "string" ? String(route.query[key]) : "";
}

async function loadPlans(): Promise<void> {
  const response = await usageAPI.adminPlans();
  if (response.ok) plans.value = response.data?.plans ?? [];
}
async function loadUsers(updateRoute = true): Promise<void> {
  const requestSequence = ++usersRequestSequence;
  if (updateRoute) await syncUserQuery();
  if (requestSequence !== usersRequestSequence) return;
  loading.value = true;
  const response = await usageAPI.adminUsers({
    page: page.value,
    pageSize,
    search: filters.search.trim(),
    status: filters.status,
    role: filters.role,
  });
  if (requestSequence !== usersRequestSequence) return;
  if (!response.ok) error.value = response.error ?? `HTTP ${response.status}`;
  else {
    users.value = response.data?.users ?? [];
    total.value = Number(
      response.data?.total ?? response.data?.count ?? users.value.length,
    );
    stateAuthority.value = String(
      response.data?.state?.stateAuthority ?? "pk01-postgres",
    );
    error.value = null;
  }
  loading.value = false;
  loaded.value = true;
}
async function applyFilters(): Promise<void> {
  page.value = 1;
  await loadUsers();
}
async function setPage(value: number): Promise<void> {
  page.value = value;
  await loadUsers();
}
async function syncUserQuery(): Promise<void> {
  const query = {
    ...route.query,
    q: filters.search.trim() || undefined,
    filter: filters.status || undefined,
    role: filters.role || undefined,
    cursor: page.value > 1 ? String(page.value) : undefined,
  };
  await router.push({ query });
}
async function selectUser(
  userId: string | undefined,
  updateRoute = true,
): Promise<void> {
  if (!userId) return;
  const requestSequence = ++detailRequestSequence;
  selectedUserId.value = userId;
  if (updateRoute && route.params.userId !== userId)
    await router.push({
      name: "UserDetail",
      params: { userId },
      query: route.query,
    });
  if (
    requestSequence !== detailRequestSequence ||
    selectedUserId.value !== userId
  )
    return;
  detailLoading.value = true;
  mutationError.value = null;
  const response = await usageAPI.adminUser(userId);
  if (
    requestSequence !== detailRequestSequence ||
    selectedUserId.value !== userId
  )
    return;
  if (!response.ok) {
    mutationError.value = response.error ?? `HTTP ${response.status}`;
    detail.value = null;
  } else {
    detail.value = response.data?.detail ?? null;
    fillEditForm(
      detail.value?.summary?.user ??
        users.value.find((item) => item.user?.id === userId)?.user,
    );
  }
  detailLoading.value = false;
}
function closeInspector(): void {
  detailRequestSequence += 1;
  selectedUserId.value = null;
  detail.value = null;
  detailLoading.value = false;
  void router.push({ name: "Users", query: route.query });
}
function fillEditForm(
  user: (AuthUser & { email?: string }) | null | undefined,
): void {
  editForm.email = user?.email ?? "";
  editForm.username = user?.username ?? "";
  editForm.displayName = user?.displayName ?? "";
  editForm.password = "";
  editForm.role = user?.role === "admin" ? "admin" : "user";
  editForm.status = String(user?.status ?? "active");
  editForm.planId = selectedSummary.value?.planId ?? "default";
}
async function createUser(): Promise<void> {
  pending.value = "create";
  mutationError.value = null;
  const response = await usageAPI.createAdminUser({
    ...createForm,
    initialCredits: Number(createForm.initialCredits || 0),
  });
  pending.value = null;
  if (!response.ok) {
    mutationError.value = response.error ?? `HTTP ${response.status}`;
    return;
  }
  Object.assign(createForm, {
    email: "",
    username: "",
    displayName: "",
    password: "",
    role: "user",
    status: "active",
    initialCredits: 0,
  });
  createOpen.value = false;
  await loadUsers(false);
  if (response.data?.user?.id) await selectUser(response.data.user.id);
}
async function saveUser(): Promise<void> {
  const userId = selectedUser.value?.id;
  if (!userId) return;
  pending.value = `save:${userId}`;
  mutationError.value = null;
  const body: Record<string, unknown> = {
    email: editForm.email.trim(),
    username: editForm.username.trim(),
    displayName: editForm.displayName.trim(),
    role: editForm.role,
    status: editForm.status,
    planId: editForm.planId || "default",
  };
  if (editForm.password) body.password = editForm.password;
  const response = await usageAPI.updateAdminUser(userId, body);
  pending.value = null;
  if (!response.ok)
    mutationError.value = response.error ?? `HTTP ${response.status}`;
  else {
    await loadUsers(false);
    await selectUser(userId, false);
  }
}
async function setUserStatus(item: AdminBillingUserSummary): Promise<void> {
  const userId = item.user?.id;
  if (!userId) return;
  const status: AccessUserStatus =
    item.user?.status === "disabled" ? "active" : "disabled";
  pending.value = `status:${userId}`;
  mutationError.value = null;
  const response = await usageAPI.updateAdminUserStatus(userId, status);
  pending.value = null;
  if (!response.ok)
    mutationError.value = response.error ?? `HTTP ${response.status}`;
  else {
    await loadUsers(false);
    if (selectedUserId.value === userId) await selectUser(userId, false);
  }
}
async function adjustCredits(): Promise<void> {
  const userId = selectedUser.value?.id;
  if (!userId) return;
  pending.value = `credits:${userId}`;
  mutationError.value = null;
  const response = await usageAPI.adjustAdminCredits(userId, {
    deltaCredits: Number(creditForm.deltaCredits),
    reason: creditForm.reason.trim() || "admin_adjust",
    idempotencyKey: creditForm.idempotencyKey.trim() || undefined,
  });
  pending.value = null;
  if (!response.ok)
    mutationError.value = response.error ?? `HTTP ${response.status}`;
  else {
    creditForm.deltaCredits = 0;
    creditForm.idempotencyKey = "";
    await Promise.all([
      loadUsers(false),
      selectUser(userId, false),
      audit.loadAudit(false),
    ]);
  }
}
  return {
    users, plans, detail, selectedUserId, loading, loaded, detailLoading,
    error, mutationError, pending, page, pageSize, total, stateAuthority,
    createOpen, filters, createForm, editForm, creditForm, selectedSummary,
    selectedUser, selectedEntitlements, ledgerRows, apiKeys, reservations,
    viewMode, density, detailTab, asyncState, statusItems, loadPlans, loadUsers,
    applyFilters, setPage, selectUser, closeInspector, createUser, saveUser,
    setUserStatus, adjustCredits, userColumns, userKey, formatNumber,
    ...audit, usageColumns, ledgerColumns, auditKey, formatSigned, formatDate,
    metadataPreview,
  };
}
