import { useState, useEffect, useRef, useCallback } from "react";
import { Mic, MicOff } from "lucide-react";
import { Messages } from "../../../Components/Notifications/Messages";
import { Tooltip } from "antd";

const EnhancedVoiceForm = ({ setVoiceData, uomNames }) => {
    const [messageType, setMessageType] = useState(null);
    const [messageData, setMessageData] = useState(null);
    const [formData, setFormData] = useState({ product: "", qty: "", uom: "", price: "" });
    const [transcript, setTranscript] = useState("");
    const [isListening, setIsListening] = useState(false);
    const [isProcessing, setIsProcessing] = useState(false);
    const [error, setError] = useState("");
    const [confidence, setConfidence] = useState(0);
    const recognitionRef = useRef(null);

    // Improved extractEntities function with better pattern recognition
    // Improved extractEntities function with better pattern recognition
    const extractEntities = (text) => {
        if (!text?.trim()) return { product: "", qty: "", uom: "", price: "" };

        const cleanText = text.toLowerCase().trim();

        // UOM mappings (comprehensive list with all common units)
        const uomMappings = {
            // Existing units
            nos: ["nos", "no", "number", "numbers", "piece", "pieces", "pcs", "pc", "unit", "units", "each"],
            "m.w": ["m.w", "mw", "meter weight", "meter weight", "m weight", "m w"],
            "l.w": ["l.w", "lw", "length width", "length and width", "l width", "l w", "length", "width"],
            "h.w": ["h.w", "hw", "height width", "height and width", "h width", "h w", "height", "width"],
            box: ["box", "boxes", "bx", "carton", "cartons", "case", "cases"],
            plt: ["plt", "plate", "plates", "plat", "plats"],
            pcs: ["pcs", "pc", "piece", "pieces", "unit", "units", "each"],

            // Weight/Mass units
            kgs: ["kgs", "kilos", "kilograms", "kilogrammes"],
            kg: ["kg", "kilo", "kilogram", "kilogramme"],
            gram: ["gram", "grams", "g", "gms", "gramme", "grammes"],
            ton: ["ton", "tons", "tonne", "tonnes", "t"],
            pound: ["lb", "lbs", "pound", "pounds"],
            ounce: ["oz", "ounce", "ounces"],

            // Volume units
            ltr: ["ltr", "l", "liter", "liters", "litre", "litres", "liquid", "fluid"],
            ml: ["ml", "mili", "milli", "millilitre", "millilitres", "milliliter", "milliliters", "mili litre", "mili liter", "milli litre", "milli liter"],
            gallon: ["gal", "gallon", "gallons"],
            pint: ["pt", "pint", "pints"],
            cup: ["cup", "cups"],
            tablespoon: ["tbsp", "tablespoon", "tablespoons", "table spoon", "table spoons"],
            teaspoon: ["tsp", "teaspoon", "teaspoons", "tea spoon", "tea spoons"],

            // Length/Distance units
            meter: ["meter", "meters", "m", "mtr", "metre", "metres", "length", "distance"],
            centimeter: ["cm", "centimeter", "centimeters", "centimetre", "centimetres", "centi meter", "centi meters"],
            millimeter: ["mm", "millimeter", "millimeters", "millimetre", "millimetres", "milli meter", "milli meters"],
            kilometer: ["km", "kilometer", "kilometers", "kilometre", "kilometres", "kilo meter", "kilo meters"],
            inch: ["in", "inch", "inches"],
            foot: ["ft", "foot", "feet"],
            yard: ["yd", "yard", "yards"],

            // Area units
            sqm: ["sq m", "sqm", "square meter", "square meters", "square metre", "square metres"],
            sqft: ["sq ft", "sqft", "square foot", "square feet"],
            acre: ["acre", "acres"],

            // Time units
            second: ["sec", "second", "seconds", "s"],
            minute: ["min", "minute", "minutes"],
            hour: ["hr", "hour", "hours", "h"],
            day: ["day", "days"],
            week: ["week", "weeks"],
            month: ["month", "months"],
            year: ["year", "years", "yr", "yrs"],

            // Temperature units
            celsius: ["°C", "celsius", "centigrade", "c", "degree celsius", "degrees celsius"],
            fahrenheit: ["°F", "fahrenheit", "f", "degree fahrenheit", "degrees fahrenheit"],
            kelvin: ["K", "kelvin", "degree kelvin", "degrees kelvin"],

            // Electrical units
            watt: ["watt", "watts", "w", "power", "wt"],
            volt: ["volt", "volts", "v", "voltage", "vt"],
            ampere: ["amp", "amps", "ampere", "amperes", "a"],
            ohm: ["ohm", "ohms", "Ω"],

            // Other common units
            dozen: ["dozen", "dozens", "dz"],
            pair: ["pair", "pairs", "pr"],
            set: ["set", "sets"],
            pack: ["pack", "packs", "packet", "packets", 'pac'],
            roll: ["roll", "rolls"],
            sheet: ["sheet", "sheets"],
            bottle: ["bottle", "bottles", "btl"],
            can: ["can", "cans"],
            jar: ["jar", "jars"],
            tube: ["tube", "tubes"]
        };

        // Number words mapping (compound phrases first to match them before individual words)
        const numberWords = {
            "three quarters": "0.75",
            "two quarters": "0.5",
            "one quarter": "0.25",
            "a quarter": "0.25",
            "half": "0.5",
            "one half": "0.5",
            "a half": "0.5",
            zero: "0", one: "1", two: "2", three: "3", four: "4", five: "5",
            six: "6", seven: "7", eight: "8", nine: "9", ten: "10",
            eleven: "11", twelve: "12", thirteen: "13", fourteen: "14", fifteen: "15",
            sixteen: "16", seventeen: "17", eighteen: "18", nineteen: "19", twenty: "20",
            thirty: "30", forty: "40", fifty: "50", sixty: "60", seventy: "70",
            eighty: "80", ninety: "90", hundred: "100",
            quarter: "0.25"
        };

        // Create reverse mapping for UOM lookup
        const uomReverseMapping = {};
        Object.entries(uomMappings).forEach(([standardUom, variations]) => {
            variations.forEach(variation => {
                uomReverseMapping[variation] = standardUom;
            });
        });

        // Create regex pattern for all UOM variations (sorted by length desc to match longer ones first)
        const allUomVariations = Object.keys(uomReverseMapping).sort((a, b) => b.length - a.length);
        const uomPattern = allUomVariations.map(uom => uom.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|');

        let qty = "";
        let uom = "";
        let product = "";
        let price = "";

        // --- IMPROVED PRICE EXTRACTION ---
        // First, look for specific price patterns with actual numbers
        const specificPricePatterns = [
            /(?:₹|rs\.?|inr|rupees)\s*(\d+(?:\.\d+)?)/i,  // ₹100, rs 100, inr 100, rupees 100
            /(\d+(?:\.\d+)?)\s*(?:₹|rs\.?|inr|rupees)/i,  // 100₹, 100 rs, 100 inr, 100 rupees
            /price\s*(?:is\s*)?(?:₹|rs\.?|inr|rupees)?\s*(\d+(?:\.\d+)?)/i,  // price is 100, price rs 100
            /costs?\s*(?:₹|rs\.?|inr|rupees)?\s*(\d+(?:\.\d+)?)/i,  // costs 100, cost rs 100
            /for\s*(?:₹|rs\.?|inr|rupees)?\s*(\d+(?:\.\d+)?)/i  // for 100, for rs 100
        ];

        // Check for specific price patterns first
        for (const pattern of specificPricePatterns) {
            const priceMatch = cleanText.match(pattern);
            if (priceMatch && priceMatch[1]) {
                price = priceMatch[1];
                break;
            }
        }

        // Remove the entire price phrase from text for further processing
        let textWithoutPrice = cleanText;
        if (price) {
            // Remove the matched price pattern
            for (const pattern of specificPricePatterns) {
                textWithoutPrice = textWithoutPrice.replace(pattern, " ");
            }
        }

        // Also remove currency indicators that don't have specific prices (like "in rupees", "for money")
        const currencyIndicators = [
            /\bin\s+rupees?\b/gi,
            /\bfor\s+money\b/gi,
            /\bfor\s+rupees?\b/gi,
            /\bwith\s+rupees?\b/gi,
            /\bcurrency\s+rupees?\b/gi
        ];

        currencyIndicators.forEach(pattern => {
            textWithoutPrice = textWithoutPrice.replace(pattern, " ");
        });

        // Clean up extra spaces
        textWithoutPrice = textWithoutPrice.replace(/\s+/g, " ").trim();

        // --- REST OF EXTRACTION LOGIC (same as before but using textWithoutPrice) ---

        // Pattern 1: Handle attached quantity-UOM (like "apple1kg", "milk2l", "water500ml")
        const attachedPattern = new RegExp(`(.+?)(\\d+(?:\\.\\d+)?)(${uomPattern})(?:\\s|$)`, 'i');
        const attachedMatch = textWithoutPrice.match(attachedPattern);

        if (attachedMatch) {
            const productPart = attachedMatch[1].trim();
            const qtyPart = attachedMatch[2];
            const uomPart = attachedMatch[3];

            if (productPart && qtyPart && uomReverseMapping[uomPart]) {
                product = productPart;
                qty = qtyPart;
                uom = uomReverseMapping[uomPart];
            }
        }

        // Pattern 2: Spaced quantity-UOM patterns (like "apple 1 kg", "milk 2 liters", "water 500 ml")
        if (!qty || !uom) {
            const spacedPatterns = [
                new RegExp(`(.+?)\\s+(\\d+(?:\\.\\d+)?)\\s+(${uomPattern})(?:\\s|$)`, 'i'),
                new RegExp(`(\\d+(?:\\.\\d+)?)\\s+(${uomPattern})\\s+(.+)`, 'i'),
                new RegExp(`(\\d+(?:\\.\\d+)?)\\s+(${uomPattern})\\s+of\\s+(.+)`, 'i')
            ];

            for (const pattern of spacedPatterns) {
                const match = textWithoutPrice.match(pattern);
                if (match) {
                    if (match[3] && !match[1].match(/^\d/)) {
                        // Pattern: "product qty uom"
                        product = match[1].trim();
                        qty = match[2];
                        uom = uomReverseMapping[match[3]];
                    } else if (match[3]) {
                        // Pattern: "qty uom product" or "qty uom of product"
                        qty = match[1];
                        uom = uomReverseMapping[match[2]];
                        product = match[3].trim();
                    }
                    if (product && qty && uom) break;
                }
            }
        }

        // Pattern 3: Word number patterns (like "two kg apple", etc.)
        if (!qty || !uom) {
            const sortedNumberWords = Object.keys(numberWords).sort((a, b) => b.length - a.length);

            for (const numberPhrase of sortedNumberWords) {
                if (textWithoutPrice.includes(numberPhrase)) {
                    const escapedPhrase = numberPhrase.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');

                    if (!qty || !uom) {
                        const wordNumbers = Object.keys(numberWords).join('|');
                        const wordNumberPatterns = [
                            new RegExp(`(.+?)\\s+(${wordNumbers})\\s+(${uomPattern})(?:\\s|$)`, 'i'),
                            new RegExp(`(${wordNumbers})\\s+(${uomPattern})\\s+(.+)`, 'i'),
                            new RegExp(`(${wordNumbers})\\s+(${uomPattern})\\s+of\\s+(.+)`, 'i')
                        ];

                        for (const pattern of wordNumberPatterns) {
                            const match = textWithoutPrice.match(pattern);
                            if (match) {
                                if (match[3] && !numberWords[match[1]]) {
                                    product = match[1].trim();
                                    qty = numberWords[match[2]];
                                    uom = uomReverseMapping[match[3]];
                                } else if (match[3]) {
                                    qty = numberWords[match[1]];
                                    uom = uomReverseMapping[match[2]];
                                    product = match[3].trim();
                                }
                                if (product && qty && uom) break;
                            }
                        }
                    }

                    const compoundPatterns = [
                        new RegExp(`(.+?)\\s+(${escapedPhrase})\\s+(${uomPattern})(?:\\s|$)`, 'i'),
                        new RegExp(`(${escapedPhrase})\\s+(${uomPattern})\\s+(.+)`, 'i'),
                        new RegExp(`(${escapedPhrase})\\s+(${uomPattern})\\s+of\\s+(.+)`, 'i')
                    ];

                    for (const pattern of compoundPatterns) {
                        const match = textWithoutPrice.match(pattern);
                        if (match) {
                            if (match[3] && match[1] !== numberPhrase) {
                                product = match[1].trim();
                                qty = numberWords[numberPhrase];
                                uom = uomReverseMapping[match[3]];
                            } else if (match[3]) {
                                qty = numberWords[numberPhrase];
                                uom = uomReverseMapping[match[2]];
                                product = match[3].trim();
                            }
                            if (product && qty && uom) break;
                        }
                    }
                    if (product && qty && uom) break;
                }
            }
        }

        // Pattern 4: Fallback - look for any quantity and UOM separately
        if (!qty) {
            const qtyMatch = textWithoutPrice.match(/(\d+(?:\.\d+)?)/);
            if (qtyMatch) {
                qty = qtyMatch[1];
            } else {
                const sortedNumberWords = Object.keys(numberWords).sort((a, b) => b.length - a.length);
                for (const numberPhrase of sortedNumberWords) {
                    if (textWithoutPrice.includes(numberPhrase)) {
                        qty = numberWords[numberPhrase];
                        break;
                    }
                }
            }
        }

        if (!uom) {
            const words = textWithoutPrice.split(/\s+/);
            for (const word of words) {
                if (uomReverseMapping[word]) {
                    uom = uomReverseMapping[word];
                    break;
                }
            }
        }

        // Extract product if not found yet
        if (!product) {
            const words = textWithoutPrice.split(/\s+/);

            const excludeWords = new Set();
            if (qty) excludeWords.add(qty);
            if (uom) {
                excludeWords.add(uom);
                if (uomMappings[uom]) {
                    uomMappings[uom].forEach(variation => excludeWords.add(variation));
                }
            }
            Object.keys(numberWords).forEach(word => {
                excludeWords.add(word);
                word.split(' ').forEach(subword => excludeWords.add(subword));
            });
            Object.keys(uomReverseMapping).forEach(variation => excludeWords.add(variation));
            ['of', 'and', 'the', 'a', 'an'].forEach(word => excludeWords.add(word));

            const productWords = words.filter(word =>
                !excludeWords.has(word) &&
                !excludeWords.has(word.toLowerCase()) &&
                !/^\d+(\.\d+)?$/.test(word)
            );

            product = productWords.join(' ').trim();
        }

        // Clean up product name
        product = product
            .replace(/^\W+|\W+$/g, '')
            .split(/\s+/)
            .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
            .join(' ');

        // Set default quantity if product exists but no quantity found
        const finalQty = product && !qty ? "1" : qty;

        const result = {
            product: product || "",
            qty: finalQty || "",
            uom: uom || "",
            price: price || ""
        };

        return result;
    };
    // Setup speech recognition (same as before)
    useEffect(() => {
        const SpeechRecognition =
            window.SpeechRecognition || window.webkitSpeechRecognition;

        if (!SpeechRecognition) {
            setError("Speech Recognition not supported in this browser");
            return;
        }

        const recognition = new SpeechRecognition();
        recognition.lang = "en-US";
        recognition.continuous = false;
        recognition.interimResults = false;
        recognition.maxAlternatives = 3;

        recognition.onstart = () => {
            setIsProcessing(false);
            setError("");
        };

        recognition.onresult = (event) => {
            setIsProcessing(true);
            const results = event.results[0];

            let bestResult = results[0];
            for (let i = 1; i < results.length; i++) {
                if (results[i].confidence > bestResult.confidence) {
                    bestResult = results[i];
                }
            }

            const spokenText = bestResult.transcript;
            const confidence = bestResult.confidence || 0;

            setTranscript(spokenText);
            setConfidence(confidence);

            const { product, qty, uom, price } = extractEntities(spokenText);
            setFormData({ product, qty, uom, price });
            if (setVoiceData) {
                setVoiceData({ product, qty, uom, price, transcript: spokenText, confidence });
            }

            setIsProcessing(false);
        };

        recognition.onerror = (event) => {
            setIsProcessing(false);
            setError(event.error);
            setIsListening(false);
        };

        recognition.onend = () => {
            setIsListening(false);
            setIsProcessing(false);
        };

        recognitionRef.current = recognition;

        return () => {
            recognitionRef.current?.abort();
        };
    }, [setVoiceData]);

    useEffect(() => {
        if (error) {
            setMessageType("error");
            setMessageData(`Recognition error: ${error}`);
        }
    }, [error]);

    const startListening = async () => {
        try {
            setError("");
            const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
            stream.getTracks().forEach((track) => track.stop());

            recognitionRef.current?.start();
            setIsListening(true);
            setTranscript("");
            setFormData({ product: "", qty: "", uom: "" });
            setConfidence(0);
        } catch {
            setError("Microphone access denied or not available");
            setIsListening(false);
        }
    };

    const stopListening = () => {
        recognitionRef.current?.stop();
        setIsListening(false);
        setIsProcessing(false);
    };

    const onComplete = useCallback(() => {
        setMessageData(null);
        setMessageType(null);
    }, []);

    return (
        <Tooltip
            title={
                <>
                    Voice Input: {isListening ? "Stop Listening" : "Start Listening"}
                    <br />
                    Examples:
                    <ul style={{ margin: 0, paddingLeft: "20px" }}>
                        <li>1 plate Chicken Biryani 200 rupees</li>
                        <li>2 cups of Coffee 30 rupees</li>
                        <li>12 rupees 1 cup tea</li>
                        <li>50 rupees 1 kg rice</li>
                    </ul>
                </>
            }
        >
            <div className="voice-wrapper flex items-center">
                <Messages messageType={messageType} messageData={messageData} onComplete={onComplete} />
                <div
                    className={`voice-search-btn ${isListening ? "on" : ""}`}
                    onClick={isListening ? stopListening : startListening}
                    title="Voice Search"
                >
                    {isListening ? <Mic size={18} /> : <MicOff size={18} />}
                    {isListening && <span className="font-medium ml-1">Listening...</span>}
                </div>

                {/* Debug info */}
                {/* {transcript && (
                    <div className="ml-4 text-sm text-gray-600">
                        Heard: "{transcript}" → Product: "{formData.product}", Qty: "{formData.qty}", UOM: "{formData.uom}", Price: "{formData.price}"
                    </div>
                )} */}
            </div>
        </Tooltip>
    );
};

export default EnhancedVoiceForm;