import { computed, ref } from "vue";
import { defineStore } from "pinia";
import { accessAPI } from "@/api";
import { normalizeAccessDetail, normalizeAccessSummary, normalizeAccessUsers, type AccessToolRow, type AccessUserRow } from "./admin-access-view";
import type { AccessToolId, AccessUserRole, AccessUserStatus, AdminAccessMatrixResponse, AdminAccessSummaryResponse, AdminAccessUsersResponse } from "@/types";

export const useAccessStore = defineStore("access", () => {
  const summary = ref<AdminAccessSummaryResponse | null>(null);
  const users = ref<AdminAccessUsersResponse | null>(null);
  const detail = ref<AdminAccessMatrixResponse | null>(null);
  const selectedUserId = ref<string | null>(null);
  const loading = ref(false);
  const detailLoading = ref(false);
  const savingKey = ref<string | null>(null);
  const error = ref<string | null>(null);
  const mutationError = ref<string | null>(null);

  const summaryView = computed(() => normalizeAccessSummary(summary.value));
  const userRows = computed<AccessUserRow[]>(() => normalizeAccessUsers(users.value));
  const detailView = computed(() => normalizeAccessDetail(detail.value));
  const toolRows = computed<AccessToolRow[]>(() => detailView.value.tools);
  const selectedUser = computed(() => detailView.value.user ?? userRows.value.find((row) => row.id === selectedUserId.value) ?? null);

  async function refresh(): Promise<void> {
    loading.value = true;
    error.value = null;
    const [summaryResult, usersResult] = await Promise.all([accessAPI.summary(), accessAPI.users()]);
    summary.value = summaryResult.data;
    users.value = usersResult.data;
    error.value = summaryResult.ok && usersResult.ok ? null : summaryResult.error ?? usersResult.error ?? "Access API unavailable";
    loading.value = false;
    const firstUserId = userRows.value[0]?.id ?? null;
    if (!selectedUserId.value && firstUserId) await selectUser(firstUserId);
  }

  async function selectUser(userId: string): Promise<void> {
    if (!userId) return;
    selectedUserId.value = userId;
    detailLoading.value = true;
    mutationError.value = null;
    const response = await accessAPI.user(userId);
    if (response.ok) {
      detail.value = response.data;
    } else {
      mutationError.value = response.error ?? `HTTP ${response.status}`;
    }
    detailLoading.value = false;
  }

  async function updateSelectedUser(payload: { role?: AccessUserRole; status?: AccessUserStatus }): Promise<void> {
    if (!selectedUserId.value) return;
    savingKey.value = `user:${selectedUserId.value}`;
    mutationError.value = null;
    const response = await accessAPI.updateUser(selectedUserId.value, payload);
    if (!response.ok) {
      mutationError.value = response.error ?? `HTTP ${response.status}`;
      savingKey.value = null;
      return;
    }
    await refresh();
    await selectUser(selectedUserId.value);
    savingKey.value = null;
  }

  async function setTool(toolId: AccessToolId, allowed: boolean): Promise<void> {
    if (!selectedUserId.value) return;
    savingKey.value = `tool:${toolId}`;
    mutationError.value = null;
    const response = await accessAPI.setTool(selectedUserId.value, toolId, allowed);
    if (!response.ok) {
      mutationError.value = response.error ?? `HTTP ${response.status}`;
      savingKey.value = null;
      return;
    }
    await refresh();
    await selectUser(selectedUserId.value);
    savingKey.value = null;
  }

  return { summary, users, detail, selectedUserId, summaryView, userRows, detailView, toolRows, selectedUser, loading, detailLoading, savingKey, error, mutationError, refresh, selectUser, updateSelectedUser, setTool };
});
