package page.tools.stats;

import java.util.Map;
import java.util.TreeSet;

import org.wikiwebserver.core.WareHouse;
import org.wikiwebserver.core.WikiMap;
import org.wikiwebserver.handler.http.interfaces.HTTPResponder;
import page.config.SiteTemplatedPage;
import org.wikiwebserver.util.comparator.DescendingEntryValueComparator;

import page.config.SiteMonitor;
import page.tools.entity.User;

import static org.wikiwebserver.html.HTMLHelper.*;
import static org.wikiwebserver.html.HTMLHelper.ContainerType.*;

public class UserList extends SiteTemplatedPage implements HTTPResponder {
    
    private static final int USERS_PER_PAGE = 10;
    
    public void generate() {
        
        setTitle("Users - WikiWebServer.org");
        addResourceRoot("/templates/default/list/");
        addCSSLink("list.css");   
        
        addJavascriptLink("/page/tools/html/ajax.js");
        
        append(h(1, "Registered Users"));
        
        String query = "";
        int limit = USERS_PER_PAGE;
        int start = 0;
        if (getFormData() != null) {
            if (getFormData().getFirst("o") != null) {
                start = Integer.parseInt(getFormData().getFirst("o"));
            }
            if (getFormData().getFirst("q") != null) {
                query = getFormData().getFirst("q");
            }   
            if (getFormData().getFirst("limit") != null) {
                limit = Integer.parseInt(getFormData().getFirst("limit"));
            }              
        }

        append(form("Search: " + textfield("q", query, "onkeyup='cpov(this, 300);'")
                               + submitbutton("action", "Search")));

        append(div("list", userItems(start, limit, query)));
        append(cleardiv());

    }
    
    public void ajax() {
        append("$('#list').hide();");   
        String query = (String) getHandler().getRequest().getData();
        append(updateHTMLScript("list", userItems(0, USERS_PER_PAGE, query)));
        append("$('#list').fadeIn(500);");        
    }
    
    private String userItems(int start, int maxResults, String query) {
        
        query = query.toLowerCase();
        
        TreeSet<Map.Entry<String, Object>> sortedSet 
            = new TreeSet<Map.Entry<String, Object>>(
                    new DescendingEntryValueComparator<String, Object>());   
    
        Map<String, Object> dataStore = (WikiMap) SiteMonitor.getStatistic("UserAccessTimes");
        if (dataStore == null) return p("No users found.");
        
        for (Map.Entry<String, Object> entry : dataStore.entrySet()) {
            sortedSet.add(entry);
        }
    
        int end = start + maxResults;
        StringBuilder bill = new StringBuilder();
        
        if (start > 0) {
            bill.append(p(a("?o=" + (start-maxResults) + "&q=" + query, "&lt;- Previous")));
        } 
        
        int numResults = 0;
        int i = 0;
        for (Map.Entry<String, Object> entry : sortedSet) {
            User user = User.getUserById((String) entry.getKey());
            if (user != null && user.getEmail() != null) {
                String userEmail = user.getEmail().toLowerCase();
                if (userEmail.contains(query)) {
                    if (i++ < start) continue;                
                    if (i <= end) {
                        bill.append(userItem(user));    
                    }
                    numResults++;                
                    // Optimisation (early exit)
                    if (numResults > maxResults) {
                        break;
                    }
                }
            }
            else {
            	// Remove this user, it can't be read
            	dataStore.remove(entry.getKey());
            }            
        }
        
        bill.append(cleardiv());        

        if (numResults > maxResults) {
            bill.append(p(a("?o=" + end + "&q=" + query, "Next -&gt;")));      
        }
        
        
        if (numResults == 0) {
            bill.append(p("No users found."));
        } 
        else {
            bill.append(p("Total users: " + sortedSet.size()));      
        }        
        
        return bill.toString();
    }
    
    
    private String userItem(User user) {
        
        String id = user.getId();
        
        String profile = WareHouse.getUrlPathForClass(
                page.tools.stats.BrowserInfo.class) + "?userID=" + id;
        
        String files = WareHouse.getUrlPathForClass(
                page.example.UserFiles.class) + "?userID=" + id;    
        
        String gallery = WareHouse.getUrlPathForClass(
                page.example.ImageGallery.class) + "?file=/user/u" + id;         
        
        return div(CLASS, "listitem", avatarImage(user, "width='56' height='56' class='icon'") +
                    div(CLASS, "email", emailImage(user)) +
                    div(CLASS, "detailslink", a(profile, "User details")) +
                    div(CLASS, "fileslink", a(files, "Files") + " " + 
                                            a(gallery, "Images")));
    }
    
    @Override
    public String getCacheKey() {
        return String.valueOf(System.currentTimeMillis() / 1000);
    }    
    
    @Override
    public long getExpireTime() {
        return System.currentTimeMillis() + 1000;
    }    

}
