package com.ffii.lioner.modules.lioner.client.web;

import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.Date;
import java.util.HashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.CacheControl;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.ffii.lioner.modules.lioner.client.req.UpdateClientReq;
import com.ffii.lioner.modules.lioner.client.service.ClientService;
import com.ffii.lioner.modules.lioner.commonField.entity.CommonField;

import aj.org.objectweb.asm.Type;

import com.ffii.lioner.modules.common.service.ExcelReportService;
import com.ffii.core.exception.NotFoundException;
import com.ffii.core.response.DataRes;
import com.ffii.core.response.RecordsRes;
import com.ffii.core.utils.CriteriaArgsBuilder;
import com.ffii.core.utils.DateUtils;
import com.ffii.core.utils.Params;
import com.ffii.lioner.modules.lioner.client.entity.Client;
import com.ffii.lioner.modules.lioner.commonField.service.CommonFieldService;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;

@RestController
@RequestMapping("/client")
public class ClientController{

	@Autowired
	private CommonFieldService commonFieldService;

    private final Log logger = LogFactory.getLog(getClass());
	private ClientService clientService;
	private ExcelReportService excelReportService;

    public ClientController(ClientService clientService, ExcelReportService excelReportService) {
        this.clientService = clientService;
		this.excelReportService = excelReportService;
	}

    @GetMapping("/{id}")
	public Map<String, Object> get(@PathVariable Long id) {
		return Map.of(
				Params.DATA, clientService.find(id).orElseThrow(NotFoundException::new)
				// "eventDivision", clientService.getEventDivision(Map.of("id",id))
			);
	}

	@Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class, readOnly = false)
	@PostMapping("/save")
	public Map<String, Object> saveOrUpdate(@RequestBody @Valid UpdateClientReq req) {
		logger.info("getPhone1Code:" + req.getPhone1Code());
		logger.info("getMortgagesCurrent:" + req.getMortgagesCurrent());
		Map<String, Object>  m = Map.of(
				Params.DATA,clientService.saveOrUpdate(req)
			);


		Map<String, Object> data  = ((Map)m.get("data"));

		if(data.get("id") != null){
			long clientId = (Long)data.get("id");
			Client client = clientService.find(clientId).orElse(null);
			//check if commond field is null
			Long commonFieldId = commonFieldService.getByClientId(clientId);
                CommonField commonField = commonFieldService.find(commonFieldId).orElse(null);
        
                if (commonField == null) {
					commonField = new CommonField();
                    commonField.setClientId(clientId);
                    commonFieldService.save(commonField);
				}

				commonField.setEmail(client.getEmail());
				commonField.getOthers().put("contactNoCode",client.getPhone1Code());
				commonField.setContactNo(client.getPhone1());
				
				if(client.getDob() != null){
					String dd = client.getDob().format(DateTimeFormatter.ofPattern("dd"));
					String mm = client.getDob().format(DateTimeFormatter.ofPattern("MM"));
					String yyyy = client.getDob().format(DateTimeFormatter.ofPattern("yyyy"));
					
					commonField.setDateOfBirth(dd + "/" + mm + "/" + yyyy );
					commonField.setDdDateOfBirth(dd);
					commonField.setMmDateOfBirth(mm);
					commonField.setYyyyDateOfBirth(yyyy);
					
				}
				
				commonFieldService.save(commonField);
		}

		return m;
	}

	@Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class, readOnly = false)
	@DeleteMapping("/{id}")
	@ResponseStatus(HttpStatus.NO_CONTENT)
	public void delete(@PathVariable Long id) {
		clientService.markDelete(clientService.find(id).get());
		// clientService.markDeleteWithAuditLog(clientService.find(id).get());
	}

    @GetMapping
	public RecordsRes<Map<String, Object>> list(HttpServletRequest request) throws ServletRequestBindingException {
		return new RecordsRes<>(clientService.list(
				CriteriaArgsBuilder.withRequest(request)
						.addStringLike("clientCode")
                        .addStringLike("lastname")
                        .addStringLike("firstname")
                        // .addStringLike("title")
                        .addStringLike("email")
                        .addStringLike("phone1")
                        .addStringLike("phone2")
						.addLong("consultantId")
                        // .addDate("dobFrom")
                        // .addDate("dobTo")
                        .addStringLike("remarks")
						.build()));
	}
	
	@GetMapping("/excel-client-consultant-report")
	public void exportClientConsultantReport(
			@RequestParam("fromDate") @DateTimeFormat(pattern = "yyyy-MM-dd") Date fromDate,
			@RequestParam("toDate") @DateTimeFormat(pattern = "yyyy-MM-dd") Date toDate,
			@RequestParam(required = false) List<Long> consultantIds,
			HttpServletResponse response) throws IOException {
				
		Map<String, Object> args = new HashMap<>();
		if (fromDate != null) {
			args.put("fromDate", fromDate);
		}
		if (toDate != null) {
			args.put("toDate", DateUtils.addDay(toDate, 1));
		}
		if (consultantIds != null && !consultantIds.isEmpty()) {
			args.put("consultantIds", consultantIds);
		}

		response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
		String fileName = "Client_Consultant_Report.xlsx";
		response.setHeader("Content-Disposition", "attachment; filename=" + fileName);

		// Call service to generate Excel and write to response output stream
		clientService.generateClientConsultantReport(args, response.getOutputStream());
	}

}
