/**
 * Copyright (c) 2025 SoftCorporation LLC. All rights reserved.
 *
 * The Software License, Version 1.0
 *
 * SoftCorporation LLC. grants you ("Licensee") a non-exclusive, royalty free,
 * license to use, modify and redistribute this software in source and binary
 * code form, provided that the following conditions are met:
 *
 * 1. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        SoftCorporation LLC. (http://www.softcorporation.com)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 2. This software and SoftCorporation name must not be used to
 *    promote products derived from the software without prior
 *    written permission. For written permission, please contact
 *    info@softcorporation.com.
 *
 * This software is provided "AS IS," without a warranty of any kind.
 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
 * IN NO EVENT SHALL THE SOFTCORPORATION BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION).
 *
 */
package com.softcorporation.sandi.search.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import com.softcorporation.sandi.base.service.ClientService;
import com.softcorporation.sandi.search.model.TypeAheadRequest;
import com.softcorporation.sandi.search.model.TypeAheadResponse;
import com.softcorporation.sandi.search.util.SearchException;

public abstract class TypeAheadService {

	private static final Logger LOGGER = LoggerFactory.getLogger(TypeAheadService.class);
	
	/**
	 * Highlight tags
	 */
    @Value("${sandi.search.highlight.tags:<em>,</em>}")
    protected String defaultHighlightTags;
	
    @Autowired
    protected ClientService clientService;
	
	public abstract TypeAheadResponse search(TypeAheadRequest request) throws SearchException;

    /**
     * Clean query from spaces, remove special characters and fix quotes
     * 
     * @param query
     *          The query
     * @return Cleaned query
     */
    public static String clean(final String query) {
        return fixQuotes(mergeSpaces(removeSpecialChars(query)));
    }

    /**
     * Wrap query with dashes in quotes
     * 
     * @param query
     *          The query
     * @return Wrapped in quotes query
     */
    public static String quoteDash(final String query) {
        StringBuilder buffer = new StringBuilder();
        boolean inQuotes = false;
        boolean doQuotes = false;
        int pos = -1;
        int shift = 0;
        for (int i = 0; i < query.length(); i++) {
            char chr = query.charAt(i);
            if (inQuotes) {
                if (chr == '"') {
                    inQuotes = false;
                    doQuotes = false;
                }
            } else {
                if (chr == '"') {
                    inQuotes = true;
                    doQuotes = false;
                } else if (isSpaceOrParentheses(chr)) {
                    if (doQuotes) {
                        if (pos < i - 1) {
                            buffer.insert(pos + 1, '\"');
                            buffer.append('\"');
                            shift += 2;
                        }
                        doQuotes = false;
                    }
                    pos = i + shift;
                } else if (isDashAndPosition(pos, i, chr)) {
                        doQuotes = true;
//                    chr = '-'; // moved to solr schema
                }                
            }
            buffer.append(chr);
        }
        if (doQuotes) {
            buffer.insert(pos + 1, '\"');
            buffer.append('\"');
        }
        return buffer.toString();
    }

	/**
	 * This validates dash and postion.
	 * @param pos int
	 * @param index int
	 * @param chr char
	 * @return boolean valid
	 */
    public static boolean isDashAndPosition(final int pos, final int index, final char chr) {
		return isDash(chr) && (pos < index - 1);
	}

    /**
     * Check if space or parentheses.
     * 
     * @param chr
     *          The character
     * @return true if match
     */
	public static boolean isSpaceOrParentheses(final char chr) {
        boolean output;
        if (chr == ' ' || chr == '\t' || chr == 160) {
            output = true;
        } else if (chr == '(' || chr == ')') {
            output = true;
        } else {
            output = false;
        }
        return output;
    }

    /**
     * Check if dash/hyphen like.
     * 
     * @param chr
     *          The character
     * @return true if match
     */
    public static boolean isDash(final char chr) {
        boolean output;
        if (chr == '-') {
            output = true;
        } else if (chr == 30 || chr == 31 || chr == 9472) {
            output = true;
        } else if (chr == 8211 || chr == 8212 || chr == 8722) { 
            output = true;
        } else {
            output = false;
        }
        return output;
    }

    /**
     * Merge query extra spaces
     * 
     * @param query
     *          The query
     * @return Merged query
     */
    public static String mergeSpaces(final String query) {
        return query.replaceAll("\\s+", " ").trim();
    }

    /**
     * Escape single middle double quote
     * 
     * @param searchText 
     *        The search text
     * @return Escaped search text
     */
    public static String fixQuotes(final String searchText) {
    	String output = searchText;
    	output = output.replaceAll("\\\\\\\\", "XX");
    	output = output.replaceAll("\\\\\"", "YY");
    	int position = -1;
    	int position1 = -1;
    	int occurences = 0;
        for (int i = 0; i < output.length(); i++) {
			char letter = output.charAt(i);
			if (letter == '"') {
	        	position1 = position;
				position = i;
				occurences++;
			}
		}
        output = searchText;
        if (position >= 0 && (occurences % 2) != 0) {
        	if (position1 > 0) {
        		position = position1;
        	}
//   			output = output.substring(0, position) + "\\" + output.substring(position); // escape single quote
   			output = output.substring(0, position) + output.substring(position + 1);  // remove single quote
        }    	
    	return output;
    }

   /**
     * Remove special chars 
     * 		except ",&,',*,+,-
     * 
     * @param query
     *          The query
     * @return Removed chars query
     */
    public static String removeSpecialChars(final String query) {
        return query.replaceAll("[!?#$%()_,./:;<=>@\\[\\]\\\\^`{|}~]", " ");
    }

}