package org.iri_research.renkan.controller;

import java.util.HashMap;
import java.util.Map;

import org.iri_research.renkan.Constants;
import org.iri_research.renkan.Constants.EditMode;
import org.iri_research.renkan.RenkanException;
import org.iri_research.renkan.models.Project;
import org.iri_research.renkan.repositories.ProjectsRepository;
import org.iri_research.renkan.repositories.SpacesRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.servlet.ModelAndView;


@Controller
@RequestMapping("/p")
public class RenkanController {

	private final Logger logger = LoggerFactory.getLogger(RenkanController.class);
		
	@Autowired
	private ProjectsRepository projectsRepository;
	
	@Autowired
	private SpacesRepository spacesRepository;
	
	private void checkCowebkey(String cowebkey, Project project, Constants.EditMode editMode) {
		if(cowebkey == null || cowebkey.isEmpty()) {
			throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Cowebkey missing");
		}
		try {
			if(!project.checkKey(cowebkey, editMode)) {
				throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Bad cowebkey");
			}
		} catch (RenkanException e) {
			throw new HttpServerErrorException(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage());
		}
	}
	
	@RequestMapping(value="/copy", method = RequestMethod.POST, produces={"application/json;charset=UTF-8"})
	public @ResponseBody Project copyProject(@RequestParam(value="project_id") String projectId ) {
				
		if(projectId == null || projectId.length() == 0) {
			throw new IllegalArgumentException("RenkanContoller.renkanProject.copyProject: Project id is null or empty.");
		}
		Project project = this.projectsRepository.findOne(projectId);
		if(project == null) {
			throw new HttpClientErrorException(HttpStatus.NOT_FOUND, "Project " + projectId + " not found for copyProject.");
		}

		Project newProject = this.projectsRepository.copy(project, project.getTitle() + " (copy)");
		
		return newProject;
	}

	 	
	@RequestMapping(value="/{project_id}", method = RequestMethod.GET, produces={"text/html;charset=UTF-8", "!image/*"})
	public ModelAndView renkanProject(
			@PathVariable(value="project_id") String project_id,
			@RequestHeader(value="Accept") String accept_header,
			@RequestParam(value="cowebkey") String cowebkey
			) throws HttpMediaTypeNotSupportedException
	{

		this.logger.debug("renkanProject : " + project_id + " Accept : " + accept_header!=null?accept_header:"" + ", cowebkey: "+ cowebkey!=null?cowebkey:"");
				
		if(accept_header != null && accept_header.matches(".*image/.*")) {
			throw new HttpMediaTypeNotSupportedException("Do not produce image");
		}
		
		if(project_id == null || project_id.length() == 0) {
			throw new IllegalArgumentException("RenkanContoller.renkanProject: Project id is null or empty.");
		}
		
		Project project = this.projectsRepository.findOne(project_id);
		
		if(project == null) {
			throw new HttpClientErrorException(HttpStatus.NOT_FOUND, "Project " + project_id + " not found.");
		}
		
		this.checkCowebkey(cowebkey, project, EditMode.EDITION);
		
		Map<String, Object> model = new HashMap<String, Object>();
		model.put("project", project);
		model.put("space", spacesRepository.findOne(project.getSpaceId()));
		
		return new ModelAndView("renkanProjectEdit", model);
	}
	
	@RequestMapping(value="/pub/{project_id}", method = RequestMethod.GET, produces={"text/html;charset=UTF-8", "!image/*"})
	public String renkanPublishProject(
			Model model,
			@PathVariable(value="project_id") String project_id,
			@RequestParam(value="cowebkey") String cowebkey
			)
	{
		if(project_id == null || project_id.length() == 0) {
			throw new IllegalArgumentException("RenkanContoller.renkanProject: Project id is null or empty.");
		}
		
		Project project = this.projectsRepository.findOne(project_id);
		if(project == null) {
			throw new HttpClientErrorException(HttpStatus.NOT_FOUND, "Project " + project_id + " not found.");
		}

		this.checkCowebkey(cowebkey, project, EditMode.READ_ONLY);
		
		model.addAttribute("project", project);
		model.addAttribute("space", spacesRepository.findOne(project.getSpaceId()));
		
		return "renkanProjectPublish";
	}
	
	
}
