package com.realnet.dlf.Services;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import com.realnet.OpenAi.Services.HtmlBuilder3;
import com.realnet.dlf.Entity.Design_lbrary;
import com.realnet.dlf.Repository.Design_lbraryRepository;
import com.realnet.realm.Entity.Realm;
import com.realnet.realm.Services.RealmService;
import com.realnet.users.entity1.AppUser;
import com.realnet.users.service1.AppUserServiceImpl;

@Service
public class Design_lbraryService {

	@Value("${projectPath}")
	private String projectPath;
	@Autowired
	private Design_lbraryRepository designLibraryRepository;
	@Autowired
	private AppUserServiceImpl userService;
	@Autowired
	private RealmService realmService;

	public Design_lbrary Savedata(Design_lbrary data) {

		data.setUpdatedBy(getUser().getUserId());
		data.setCreatedBy(getUser().getUserId());
		data.setAccountId(getUser().getAccount().getAccount_id());
		Design_lbrary save = designLibraryRepository.save(data);
		return save;
	}

//	get all with pagination
	public Page<Design_lbrary> getAllWithPagination(Pageable page) {
		return designLibraryRepository.findAll(page, getUser().getUserId());
	}

	public List<Design_lbrary> getdetails() {
		List<Realm> realm = realmService.findByUserId(getUser().getUserId());
		List<Design_lbrary> all = designLibraryRepository.findAll(getUser().getUserId());

		return all;
	}

	public List<Design_lbrary> getAllDlfByhedId(Integer id) {
		// TODO Auto-generated method stub
		List<Design_lbrary> all = designLibraryRepository.getAllByhedId(getUser().getUserId(), id);
		return all;

	}

	public Design_lbrary getdetailsbyId(Integer id) {
		return designLibraryRepository.findById(id).get();
	}

	public void delete_by_id(Integer id) {
		designLibraryRepository.deleteById(id);
	}

	public Design_lbrary update(Design_lbrary data, Integer id) {
		Design_lbrary old = designLibraryRepository.findById(id).get();
		old.setName(data.getName());

		old.setDescription(data.getDescription());

		old.setActive(data.isActive());

		old.setHtmljson(data.getHtmljson());

		old.setCss(data.getCss());

		old.setJavacode(data.getJavacode());

		old.setTemplatetype(data.getTemplatetype());

		old.setUitype(data.getUitype());
		old.setTyperender(data.getTyperender());

		old.setHtml(data.getHtml());

		final Design_lbrary test = designLibraryRepository.save(old);
		data.setUpdatedBy(getUser().getUserId());
		return test;
	}

//	delete by range

	public String deleteByRange(Long startId, Long endId) {
		List<Design_lbrary> all = designLibraryRepository.deleteByIdRange(startId, endId);

		int i = 0;
		for (Design_lbrary design_lbrary : all) {

			designLibraryRepository.delete(design_lbrary);
			System.out.println(design_lbrary.getId() + " deleted " + i);

			i++;
		}

		return i + " Deleted";
	}

	public String generatePreviewHtml(Integer id) {
		// 1. Record uthao
		Design_lbrary design = designLibraryRepository.findById(id)
				.orElseThrow(() -> new RuntimeException("Design not found with ID: " + id));

		// 2. JSON se HTML banao
		String htmljson = design.getHtmljson();
		String generatedHtml = HtmlBuilder3.buildHtml(htmljson); // Tumhara existing method ka call

		// 3. CSS inject karo
		String css = design.getCss();
		String finalHtml = "<html><head><style>" + css + "</style></head><body>" + generatedHtml + "</body></html>";

		return finalHtml;
	}

	// GET LINE BY header id, operation type, field type
	public Design_lbrary getflflinerandom(String operationType, String fieldType) {
		List<Design_lbrary> flf = designLibraryRepository.getallDlfLine(true, operationType.toLowerCase().trim(),
				fieldType.toLowerCase().trim());

		if (flf == null || flf.isEmpty()) {
			return null; // ya throw new RuntimeException("No data found");
		}

		// Random index pick
		int randomIndex = ThreadLocalRandom.current().nextInt(flf.size());
		return flf.get(randomIndex);
	}

	// GET LINE BY header id, operation type, field type
	public Design_lbrary getLinestraight(String operationType, String fieldType) {
		Design_lbrary flf = designLibraryRepository.getallByFieldType(true, operationType.toLowerCase().trim(),
				fieldType.toLowerCase().trim());

		if (flf == null) {
			return null; // ya throw new RuntimeException("No data found");
		}

		// Random index pick
		return flf;
	}

	// GET LINE BY header id, operation type, field type
	public Design_lbrary getallByHeaderId(Integer headerId, String operationType, String fieldType) {
		Design_lbrary flf = designLibraryRepository.getallByHeaderId(headerId, true, operationType.toLowerCase().trim(),
				fieldType.toLowerCase().trim());

		if (flf == null) {
			return null; // ya throw new RuntimeException("No data found");
		}

		// Random index pick
		return flf;
	}

	public List<Design_lbrary> listOfTemplate(String operationType, String fieldType) {
		List<Design_lbrary> flf = designLibraryRepository.getallDlfLine(true, operationType.toLowerCase().trim(),
				fieldType.toLowerCase().trim());

		if (flf == null || flf.isEmpty()) {
			return null; // ya throw new RuntimeException("No data found");
		}

		// Random index pick
		return flf;
	}

	public void build() throws IOException {
		List<Design_lbrary> dls = designLibraryRepository.findAll();

		int i = 0;
		for (Design_lbrary design_lbrary : dls) {

			String name = design_lbrary.getName();
			String javacode = design_lbrary.getJavacode();
			String method = javacode.substring(javacode.indexOf("static String") + 13, javacode.indexOf("("));

			System.out.println(name + " building start .... ");

			String typeRender = "TYPE_RENDERERS.put(" + "\"" + name + "\", HtmlBuilder::" + method + ");";

			buildfront2("//<TYPE_RENDER>", typeRender);

			buildfront2("//<METHOD_RENDER>", javacode);

			i++;

			System.out.println(name + " build ");
			System.out.println("total  build " + i);

		}

	}

	public void buildfront2(String keyword, String replaceString) throws IOException {

		String fileName = "HtmlBuilder.java";
		StringBuilder frontend = new StringBuilder();

		// CEATE PACKAGE

		String directoryName;

		directoryName = projectPath + "/src/main/java/com/realnet/dlf/Builders";

		String filePath = directoryName + File.separator + fileName;
		System.out.println("routing path is " + filePath);

		String str = replaceString;

		int length = str.length();

		// CEATE PACKAGE

		File file = null;

		file = new File(filePath);

		FileReader fr = new FileReader(file);
		BufferedReader br = new BufferedReader(fr);
		String line;

		while ((line = br.readLine()) != null) {

			if (line.trim().equalsIgnoreCase(str.trim())) {
				str = "";
			}
			frontend.append(line + "\n");
//			System.out.println(line);
		}
		fr.close();
		br.close();
		System.out.println(frontend.length());

		String back = keyword;
		int back_l = back.length();

		int ord = StringUtils.ordinalIndexOf(frontend.toString(), back, 1);

		String front = frontend.substring(0, ord + back_l) + "\n" + str + "\n"
				+ frontend.substring(ord + back_l, frontend.length());

		String codee = front.substring(0, front.lastIndexOf("\n")); // remove last line break

//		creating files
		File file1 = new File(filePath);

//		Writing files

		FileWriter fr1 = new FileWriter(file1.getAbsoluteFile());
		BufferedWriter br1 = new BufferedWriter(fr1);
//		PrintWriter out = new PrintWriter(br1);
//		out.println(r_import);

		br1.write(codee.toString());
		br1.close();

	}

	public AppUser getUser() {
		AppUser user = userService.getLoggedInUser();
		return user;

	}

}
