/**
 * WordPress dependencies
 */
import { useSelect, useDispatch } from '@wordpress/data';
import { createReduxStore, register } from '@wordpress/data';

/**
 * Mock user data for development (fallback only)
 */
const MOCK_USERS = [
    {
        id: 1,
        user_login: 'john_doe',
        display_name: 'John Doe',
        user_email: 'john.doe@example.com',
        user_url: 'https://johndoe.com',
        phone: '+1-555-0123',
        bio: 'Frontend developer with 5+ years of experience in React and WordPress.',
        avatar_url: 'https://via.placeholder.com/150/007cba/ffffff?text=JD',
        roles: ['subscriber'],
        registered_date: '2023-01-15T10:30:00Z',
        posts_count: 12,
        comments_count: 45,
        location: 'San Francisco, CA',
        company: 'Tech Corp',
        skills: ['JavaScript', 'React', 'WordPress', 'CSS']
    },
    {
        id: 2,
        user_login: 'jane_smith',
        display_name: 'Jane Smith',
        user_email: 'jane.smith@example.com',
        user_url: 'https://janesmith.dev',
        phone: '+1-555-0456',
        bio: 'UX/UI designer passionate about creating beautiful and functional user experiences.',
        avatar_url: 'https://via.placeholder.com/150/e74c3c/ffffff?text=JS',
        roles: ['author'],
        registered_date: '2023-02-20T14:15:00Z',
        posts_count: 8,
        comments_count: 23,
        location: 'New York, NY',
        company: 'Design Studio',
        skills: ['Figma', 'Adobe XD', 'Sketch', 'Prototyping']
    },
    {
        id: 3,
        user_login: 'mike_wilson',
        display_name: 'Mike Wilson',
        user_email: 'mike.wilson@example.com',
        user_url: 'https://mikewilson.io',
        phone: '+1-555-0789',
        bio: 'Backend developer specializing in PHP, Node.js, and database optimization.',
        avatar_url: 'https://via.placeholder.com/150/27ae60/ffffff?text=MW',
        roles: ['editor'],
        registered_date: '2023-03-10T09:45:00Z',
        posts_count: 25,
        comments_count: 67,
        location: 'Austin, TX',
        company: 'Web Solutions',
        skills: ['PHP', 'Node.js', 'MySQL', 'MongoDB']
    },
    {
        id: 4,
        user_login: 'sarah_jones',
        display_name: 'Sarah Jones',
        user_email: 'sarah.jones@example.com',
        user_url: 'https://sarahjones.com',
        phone: '+1-555-0321',
        bio: 'Content strategist and copywriter with expertise in SEO and digital marketing.',
        avatar_url: 'https://via.placeholder.com/150/9b59b6/ffffff?text=SJ',
        roles: ['subscriber'],
        registered_date: '2023-04-05T16:20:00Z',
        posts_count: 3,
        comments_count: 18,
        location: 'Chicago, IL',
        company: 'Content Co',
        skills: ['Copywriting', 'SEO', 'Content Strategy', 'Social Media']
    },
    {
        id: 5,
        user_login: 'david_brown',
        display_name: 'David Brown',
        user_email: 'david.brown@example.com',
        user_url: 'https://davidbrown.tech',
        phone: '+1-555-0654',
        bio: 'DevOps engineer focused on cloud infrastructure and CI/CD pipelines.',
        avatar_url: 'https://via.placeholder.com/150/f39c12/ffffff?text=DB',
        roles: ['administrator'],
        registered_date: '2023-05-12T11:10:00Z',
        posts_count: 15,
        comments_count: 34,
        location: 'Seattle, WA',
        company: 'Cloud Tech',
        skills: ['AWS', 'Docker', 'Kubernetes', 'Jenkins']
    }
];

/**
 * User Directory Store
 */
const USER_DIRECTORY_STORE = 'wpuf-ud/directory';

const DEFAULT_STATE = {
    users: [],
    filteredUsers: [],
    loading: false,
    error: null,
    filters: {
        roles: 'all',
        search: '',
        orderby: 'id',
        order: 'desc',
        per_page: 10,
        exclude_users: []
    },
    pagination: {
        current_page: 1,
        total_pages: 1,
        total_users: 0
    }
};

const actions = {
    setUsers(users) {
        return {
            type: 'SET_USERS',
            users
        };
    },
    
    setFilteredUsers(users) {
        return {
            type: 'SET_FILTERED_USERS',
            users
        };
    },
    
    setLoading(loading) {
        return {
            type: 'SET_LOADING',
            loading
        };
    },
    
    setError(error) {
        return {
            type: 'SET_ERROR',
            error
        };
    },
    
    setFilters(filters) {
        return {
            type: 'SET_FILTERS',
            filters
        };
    },
    
    setPagination(pagination) {
        return {
            type: 'SET_PAGINATION',
            pagination
        };
    },
    
    // Real API fetch action
    fetchUsers(filters = {}) {
        return async ({ dispatch, select }) => {
            dispatch(actions.setLoading(true));
            dispatch(actions.setError(null));
            
            try {
                // Build query parameters
                const params = new URLSearchParams();
                
                // Add role filter if specified and not 'all'
                if (filters.roles && filters.roles !== 'all') {
                    const roles = Array.isArray(filters.roles) ? filters.roles.join(',') : filters.roles;
                    params.append('roles', roles);
                }
                
                				// Add exclude roles filter
				if (filters.exclude_roles && filters.exclude_roles.length > 0) {
					const excludeRoles = Array.isArray(filters.exclude_roles) ? filters.exclude_roles.join(',') : filters.exclude_roles;
					params.append('exclude_roles', excludeRoles);
				}
				
				// Add exclude users filter
				if (filters.exclude_users && filters.exclude_users.length > 0) {
					const excludeUsers = Array.isArray(filters.exclude_users) ? filters.exclude_users.join(',') : filters.exclude_users;
					params.append('exclude_users', excludeUsers);
				}
                
                // Add pagination
                params.append('per_page', filters.per_page || 10);
                params.append('page', filters.page || 1);
                
                // Add ordering
                if (filters.orderby) {
                    params.append('orderby', filters.orderby);
                }
                if (filters.order) {
                    params.append('order', filters.order);
                }
                
                // Add search if provided
                if (filters.search) {
                    params.append('search', filters.search);
                }
                
                // Add searchable fields
                if (filters.searchable_fields && Array.isArray(filters.searchable_fields)) {
                    filters.searchable_fields.forEach(field => {
                        params.append('searchable_fields[]', field);
                    });
                } else {
                    // Default searchable fields
                    ['user_login', 'user_email', 'display_name'].forEach(field => {
                        params.append('searchable_fields[]', field);
                    });
                }
                
                // Add avatar size for better quality avatars
                // Map frontend avatar sizes to WordPress avatar sizes
                const avatarSizeMap = {
                    'small': 32,
                    'medium': 64,
                    'large': 96,
                    'extra_large': 150
                };
                
                // Get avatar size from filters or use default
                const avatarSize = filters.avatar_size || 'medium';
                const wpAvatarSize = avatarSizeMap[avatarSize] || 64;
                params.append('avatar_size', wpAvatarSize);
                
                // Also request multiple avatar sizes for better fallback options
                params.append('avatar_sizes', '32,64,96,150');
                
                // Add exclude users
                if (filters.exclude_users && Array.isArray(filters.exclude_users)) {
                    filters.exclude_users.forEach(userId => {
                        params.append('exclude_users[]', userId);
                    });
                }
                
                // Choose the appropriate endpoint
                const isPreview = filters.isPreview || false;
                const endpoint = isPreview ? 'preview' : 'search';
                
                // Make the API call
                const response = await wp.apiFetch({
                    path: `/wpuf/v1/user_directory/${endpoint}?${params.toString()}`,
                    headers: {
                        'X-WP-Nonce': window.wpuf_user_directory?.rest_nonce || ''
                    }
                });
                
                if (response && response.success) {
                    let users = [];
                    let total = 0;
                    
                    if (endpoint === 'preview') {
                        // Preview endpoint returns users directly
                        users = response.users || [];
                        total = response.total || users.length;
                    } else {
                        // Search endpoint returns HTML, but we need the data
                        // For the store, we should use the preview endpoint for data fetching
                        		// Using search endpoint for data store - this returns HTML. Consider using preview endpoint.
                        users = []; // Search endpoint returns HTML, not user data
                        total = 0;
                    }
                    
                    // Transform API user data to match our expected format
                    const transformedUsers = users.map(user => ({
                        id: user.id,
                        user_login: user.user_login || user.username,
                        display_name: user.display_name || user.name,
                        user_email: user.user_email || user.email,
                        user_url: user.user_url || user.url || user.website,
                        phone: user.phone || '',
                        bio: user.description || user.bio || '',
                        avatar: getBestAvatarUrl(user),
                        avatar_url: getBestAvatarUrl(user),
                        roles: user.roles || ['subscriber'],
                        registered_date: user.registered_date,
                        posts_count: user.posts_count || 0,
                        comments_count: user.comments_count || 0,
                        location: user.location || '',
                        company: user.company || '',
                        skills: user.skills || [],
                        // Add any additional meta fields
                        ...user.meta
                    }));
                    
                    dispatch(actions.setUsers(transformedUsers));
                    dispatch(actions.setFilters(filters));
                    dispatch(actions.setFilteredUsers(transformedUsers));
                    
                    // Update pagination
                    const perPage = filters.per_page || 10;
                    const currentPage = filters.page || 1;
                    const totalPages = Math.ceil(total / perPage);
                    
                    dispatch(actions.setPagination({
                        current_page: currentPage,
                        total_pages: totalPages,
                        total_users: total
                    }));
                    
                } else {
                    throw new Error(response?.message || 'Failed to fetch users');
                }
                
            } catch (error) {
                // Fallback to mock data in case of error (for development)
                if (process.env.NODE_ENV === 'development') {
                    			// Falling back to mock data due to API error
                    const filteredMockUsers = applyFilters(MOCK_USERS, filters);
                    dispatch(actions.setUsers(MOCK_USERS));
                    dispatch(actions.setFilteredUsers(filteredMockUsers));
                    
                    const perPage = filters.per_page || 10;
                    const totalPages = Math.ceil(filteredMockUsers.length / perPage);
                    dispatch(actions.setPagination({
                        current_page: 1,
                        total_pages: totalPages,
                        total_users: filteredMockUsers.length
                    }));
                } else {
                    dispatch(actions.setError(error.message || 'Failed to load users'));
                }
            } finally {
                dispatch(actions.setLoading(false));
            }
        };
    },
    
    // Fetch users for preview (block editor)
    fetchUsersPreview(filters = {}) {
        return async ({ dispatch, select }) => {
            dispatch(actions.setLoading(true));
            dispatch(actions.setError(null));
            
            try {
                // Build query parameters for preview - only include essential parameters for user list
                const params = new URLSearchParams();
                
                // Add role filter if specified and not 'all'
                if (filters.roles && filters.roles !== 'all') {
                    const roles = Array.isArray(filters.roles) ? filters.roles.join(',') : filters.roles;
                    params.append('roles', roles);
                }
                
                // Add exclude roles filter
                if (filters.exclude_roles && filters.exclude_roles.length > 0) {
                    const excludeRoles = Array.isArray(filters.exclude_roles) ? filters.exclude_roles.join(',') : filters.exclude_roles;
                    params.append('exclude_roles', excludeRoles);
                }
                
                // Add exclude users filter
                if (filters.exclude_users && filters.exclude_users.length > 0) {
                    const excludeUsers = Array.isArray(filters.exclude_users) ? filters.exclude_users.join(',') : filters.exclude_users;
                    params.append('exclude_users', excludeUsers);
                }
                
                // Add pagination
                params.append('per_page', filters.per_page || 10);
                params.append('page', filters.page || 1);
                
                // Note: We don't include orderby, order, search, searchable_fields, or avatar_size
                // as these are display/sorting options that don't affect the core user list
                // They are handled separately by the frontend or individual blocks
                
                // Use the preview endpoint for block editor
                const response = await wp.apiFetch({
                    path: `/wpuf/v1/user_directory/preview?${params.toString()}`,
                    headers: {
                        'X-WP-Nonce': window.wpuf_user_directory?.rest_nonce || ''
                    }
                });
                
                if (response && response.success) {
                    const users = response.users || [];
                    const total = response.total || users.length;
                    

                    
                    // Transform API user data to match our expected format
                    const transformedUsers = users.map(user => {
                        const transformedUser = {
                            id: user.id,
                            user_login: user.user_login || user.username,
                            display_name: user.display_name || user.name,
                            user_email: user.user_email || user.email,
                            user_url: user.user_url || user.url || user.website,
                            phone: user.phone || '',
                            bio: user.description || user.bio || '',
                            avatar: getBestAvatarUrl(user),
                            avatar_url: getBestAvatarUrl(user),
                            roles: user.roles || ['subscriber'],
                            registered_date: user.registered_date || user.user_registered,
                            posts_count: user.posts_count || 0,
                            comments_count: user.comments_count || 0,
                            location: user.location || '',
                            company: user.company || '',
                            skills: user.skills || [],
                            first_name: user.first_name || '',
                            last_name: user.last_name || '',
                            nickname: user.nickname || '',
                            // Add any additional meta fields
                            ...user.meta
                        };
                        

                        
                        return transformedUser;
                    });
                    
                    dispatch(actions.setUsers(transformedUsers));
                    dispatch(actions.setFilters(filters));
                    dispatch(actions.setFilteredUsers(transformedUsers));
                    
                    // Update pagination
                    const perPage = filters.per_page || 10;
                    const currentPage = filters.page || 1;
                    const totalPages = Math.ceil(total / perPage);
                    
                    dispatch(actions.setPagination({
                        current_page: currentPage,
                        total_pages: totalPages,
                        total_users: total
                    }));
                    
                } else {
                    throw new Error(response?.message || 'Failed to fetch users for preview');
                }
                
            } catch (error) {

                
                // Fallback to mock data in case of error (for development)
                if (process.env.NODE_ENV === 'development') {
    
                    const filteredMockUsers = applyFilters(MOCK_USERS, filters);
                    dispatch(actions.setUsers(MOCK_USERS));
                    dispatch(actions.setFilteredUsers(filteredMockUsers));
                    
                    const perPage = filters.per_page || 10;
                    const totalPages = Math.ceil(filteredMockUsers.length / perPage);
                    dispatch(actions.setPagination({
                        current_page: 1,
                        total_pages: totalPages,
                        total_users: filteredMockUsers.length
                    }));
                } else {
                    dispatch(actions.setError(error.message || 'Failed to load users for preview'));
                }
            } finally {
                dispatch(actions.setLoading(false));
            }
        };
    }
};

// Helper function to get the best available avatar URL
const getBestAvatarUrl = (user) => {
    // Check direct avatar field first
    if (user.avatar && typeof user.avatar === 'string' && user.avatar.trim() !== '') {
        return user.avatar;
    }
    
    // Check avatar_urls object for best available size
    if (user.avatar_urls && typeof user.avatar_urls === 'object') {
        // Try to get the best available size in order of preference
        const sizes = ['96', '64', '32'];
        for (const size of sizes) {
            if (user.avatar_urls[size] && user.avatar_urls[size].trim() !== '') {
                return user.avatar_urls[size];
            }
        }
    }
    
    return '';
};

// Helper function to apply filters (for mock data fallback)
const applyFilters = (users, filters) => {
    let filtered = [...users];
    
    // Filter by roles
    if (filters.roles && filters.roles !== 'all') {
        const targetRoles = Array.isArray(filters.roles) ? filters.roles : [filters.roles];
        filtered = filtered.filter(user =>
            user.roles.some(role => targetRoles.includes(role))
        );
    }
    
    	// Filter by exclude roles
	if (filters.exclude_roles && filters.exclude_roles.length > 0) {
		const excludeRoles = Array.isArray(filters.exclude_roles) ? filters.exclude_roles : [filters.exclude_roles];
		filtered = filtered.filter(user =>
			!user.roles.some(role => excludeRoles.includes(role))
		);
	}
	
	// Filter by exclude users
	if (filters.exclude_users && filters.exclude_users.length > 0) {
		const excludeUsers = Array.isArray(filters.exclude_users) ? filters.exclude_users : [filters.exclude_users];
		filtered = filtered.filter(user =>
			!excludeUsers.includes(user.id.toString())
		);
	}
    
    // Filter by search
    if (filters.search) {
        const searchTerm = filters.search.toLowerCase();
        filtered = filtered.filter(user =>
            user.display_name.toLowerCase().includes(searchTerm) ||
            user.user_login.toLowerCase().includes(searchTerm) ||
            user.user_email.toLowerCase().includes(searchTerm) ||
            user.bio.toLowerCase().includes(searchTerm)
        );
    }
    
    // Filter by exclude_users
    if (filters.exclude_users && filters.exclude_users.length > 0) {
        filtered = filtered.filter(user =>
            !filters.exclude_users.includes(user.id)
        );
    }
    
    // Sort users
    const orderby = filters.orderby || 'id';
    const order = filters.order || 'desc';
    
    filtered.sort((a, b) => {
        let aValue, bValue;
        
        switch (orderby) {
            case 'user_login':
                aValue = a.user_login.toLowerCase();
                bValue = b.user_login.toLowerCase();
                break;
            case 'user_email':
                aValue = a.user_email.toLowerCase();
                bValue = b.user_email.toLowerCase();
                break;
            case 'display_name':
                aValue = a.display_name.toLowerCase();
                bValue = b.display_name.toLowerCase();
                break;
            case 'registered':
                aValue = new Date(a.registered_date);
                bValue = new Date(b.registered_date);
                break;
            case 'posts_count':
                aValue = a.posts_count;
                bValue = b.posts_count;
                break;
            default: // id
                aValue = a.id;
                bValue = b.id;
        }
        
        if (order === 'asc') {
            return aValue > bValue ? 1 : -1;
        } else {
            return aValue < bValue ? 1 : -1;
        }
    });
    
    return filtered;
};

const selectors = {
    getUsers(state) {
        return state.users;
    },
    
    getFilteredUsers(state) {
        return state.filteredUsers;
    },
    
    getLoading(state) {
        return state.loading;
    },
    
    getError(state) {
        return state.error;
    },
    
    getFilters(state) {
        return state.filters;
    },
    
    getPagination(state) {
        return state.pagination;
    },
    
    getUserById(state, userId) {
        return state.users.find(user => user.id === userId);
    }
};

const reducer = (state = DEFAULT_STATE, action) => {
    switch (action.type) {
        case 'SET_USERS':
            return {
                ...state,
                users: action.users
            };
            
        case 'SET_FILTERED_USERS':
            return {
                ...state,
                filteredUsers: action.users
            };
            
        case 'SET_LOADING':
            return {
                ...state,
                loading: action.loading
            };
            
        case 'SET_ERROR':
            return {
                ...state,
                error: action.error
            };
            
        case 'SET_FILTERS':
            return {
                ...state,
                filters: { ...state.filters, ...action.filters }
            };
            
        case 'SET_PAGINATION':
            return {
                ...state,
                pagination: { ...state.pagination, ...action.pagination }
            };
            
        default:
            return state;
    }
};

// Create and register the store
const store = createReduxStore(USER_DIRECTORY_STORE, {
    reducer,
    actions,
    selectors,
    controls: {
        FETCH_USERS: () => actions.fetchUsers
    }
});

register(store);

/**
 * Custom hooks for easy store usage
 */
export const useUserDirectoryStore = () => {
    const users = useSelect(select => select(USER_DIRECTORY_STORE).getUsers(), []);
    const filteredUsers = useSelect(select => select(USER_DIRECTORY_STORE).getFilteredUsers(), []);
    const loading = useSelect(select => select(USER_DIRECTORY_STORE).getLoading(), []);
    const error = useSelect(select => select(USER_DIRECTORY_STORE).getError(), []);
    const filters = useSelect(select => select(USER_DIRECTORY_STORE).getFilters(), []);
    const pagination = useSelect(select => select(USER_DIRECTORY_STORE).getPagination(), []);
    
    const { fetchUsers, fetchUsersPreview, setFilters, setPagination } = useDispatch(USER_DIRECTORY_STORE);
    
    return {
        users,
        filteredUsers,
        loading,
        error,
        filters,
        pagination,
        fetchUsers,
        fetchUsersPreview,
        setFilters,
        setPagination
    };
};

export const useUserById = (userId) => {
    return useSelect(select => select(USER_DIRECTORY_STORE).getUserById(userId), [userId]);
};

export default store; 