import { writable, derived } from 'svelte/store';

export interface Permissions {
	containers: string[];
	images: string[];
	volumes: string[];
	networks: string[];
	stacks: string[];
	environments: string[];
	registries: string[];
	notifications: string[];
	configsets: string[];
	settings: string[];
	users: string[];
	git: string[];
	license: string[];
	audit_logs: string[];
	activity: string[];
	schedules: string[];
}

export interface AuthUser {
	id: number;
	username: string;
	email?: string;
	displayName?: string;
	avatar?: string;
	isAdmin: boolean;
	provider: 'local' | 'ldap' | 'oidc';
	permissions: Permissions;
}

export interface AuthState {
	user: AuthUser | null;
	loading: boolean;
	authEnabled: boolean;
	authenticated: boolean;
}

function createAuthStore() {
	const { subscribe, set, update } = writable<AuthState>({
		user: null,
		loading: true,
		authEnabled: false,
		authenticated: false
	});

	return {
		subscribe,

		/**
		 * Check current session status
		 * Should be called on app init
		 */
		async check() {
			update(state => ({ ...state, loading: true }));
			try {
				const response = await fetch('/api/auth/session');
				const data = await response.json();

				if (data.error) {
					set({
						user: null,
						loading: false,
						authEnabled: false,
						authenticated: false
					});
					return;
				}

				set({
					user: data.user || null,
					loading: false,
					authEnabled: data.authEnabled,
					authenticated: data.authenticated
				});
			} catch {
				set({
					user: null,
					loading: false,
					authEnabled: false,
					authenticated: false
				});
			}
		},

		/**
		 * Login with username and password
		 */
		async login(username: string, password: string, mfaToken?: string, provider: string = 'local'): Promise<{
			success: boolean;
			error?: string;
			requiresMfa?: boolean;
		}> {
			try {
				const response = await fetch('/api/auth/login', {
					method: 'POST',
					headers: { 'Content-Type': 'application/json' },
					body: JSON.stringify({ username, password, mfaToken, provider })
				});

				const data = await response.json();

				if (!response.ok) {
					return { success: false, error: data.error || 'Login failed' };
				}

				if (data.requiresMfa) {
					return { success: true, requiresMfa: true };
				}

				if (data.success && data.user) {
					// Refresh session to get full user with permissions
					await this.check();
					return { success: true };
				}

				return { success: false, error: 'Login failed' };
			} catch (error) {
				return { success: false, error: 'Network error' };
			}
		},

		/**
		 * Logout and clear session
		 */
		async logout() {
			try {
				await fetch('/api/auth/logout', { method: 'POST' });
			} finally {
				set({
					user: null,
					loading: false,
					authEnabled: true, // Keep authEnabled as we know it was on
					authenticated: false
				});
			}
		},

		/**
		 * Check if user has a specific permission
		 * When auth is disabled, returns true (full access)
		 */
		hasPermission(user: AuthUser | null, authEnabled: boolean, resource: keyof Permissions, action: string): boolean {
			// If auth is disabled, everything is allowed
			if (!authEnabled) return true;

			// If no user and auth is enabled, deny
			if (!user) return false;

			// Admins can do anything
			if (user.isAdmin) return true;

			// Check specific permission
			const permissions = user.permissions[resource];
			return permissions?.includes(action) ?? false;
		}
	};
}

export const authStore = createAuthStore();

// Derived store for easy permission checking
export const canAccess = derived(authStore, ($auth) => {
	return (resource: keyof Permissions, action: string): boolean => {
		// If auth is disabled, everything is allowed
		if (!$auth.authEnabled) return true;

		// If not authenticated and auth is enabled, deny
		if (!$auth.authenticated || !$auth.user) return false;

		// Admins can do anything
		if ($auth.user.isAdmin) return true;

		// Check specific permission
		const permissions = $auth.user.permissions?.[resource];
		return permissions?.includes(action) ?? false;
	};
});

// Derived store to check if user has ANY permission for a resource
// Used for menu visibility - show menu if user has any access to that resource
export const hasAnyAccess = derived(authStore, ($auth) => {
	return (resource: keyof Permissions): boolean => {
		// If auth is disabled, everything is allowed
		if (!$auth.authEnabled) return true;

		// If not authenticated and auth is enabled, deny
		if (!$auth.authenticated || !$auth.user) return false;

		// Admins can do anything
		if ($auth.user.isAdmin) return true;

		// Check if user has ANY permission for this resource
		const permissions = $auth.user.permissions?.[resource];
		return permissions && permissions.length > 0;
	};
});

// Derived store for whether auth is required for the current session
export const requiresAuth = derived(authStore, ($auth) => {
	return $auth.authEnabled && !$auth.authenticated;
});

// Derived store for admin check - true if auth disabled OR user is admin
export const isAdmin = derived(authStore, ($auth) => {
	if (!$auth.authEnabled) return true;
	return $auth.user?.isAdmin ?? false;
});
