using System;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.Events;

namespace CG.Speech
{
    public class VoiceCommandRouter : MonoBehaviour
    {
        public enum RouteMode { CommandFirst, ChatFirst }

        [Header("Mode")]
        public RouteMode mode = RouteMode.CommandFirst;

        [Header("Events")]
        public UnityEvent onStartListening;
        public UnityEvent onStopListening;
        public UnityEvent onClearCaptions;
        public UnityEvent onCancelCurrent;
        public UnityEvent<string> onChatText; // text to chat

        // Patterns assume Traditional input (we normalize earlier)
        private static readonly Regex RxStart = new(@"^(開始(聽|語音)|開始|聽我說)$", RegexOptions.Compiled);
        private static readonly Regex RxStop  = new(@"^(停止(聽|語音)|停止|閉嘴|不要聽)$", RegexOptions.Compiled);
        private static readonly Regex RxClear = new(@"^(清除(字幕|文字)|清除|清空)$", RegexOptions.Compiled);
        private static readonly Regex RxCancel= new(@"^(取消|算了|不要了|撤銷)$", RegexOptions.Compiled);
        private static readonly Regex RxToggle= new(@"^(切換模式|模式切換)$", RegexOptions.Compiled);

        public void HandleFinalUtterance(string zhTW)
        {
            zhTW ??= "";
            zhTW = zhTW.Trim();

            if (string.IsNullOrWhiteSpace(zhTW)) return;

            if (mode == RouteMode.CommandFirst)
            {
                if (TryHandleCommand(zhTW)) return;
                onChatText?.Invoke(zhTW);
            }
            else
            {
                // ChatFirst: allow explicit command keywords still work
                if (TryHandleCommand(zhTW)) return;
                onChatText?.Invoke(zhTW);
            }
        }

        private bool TryHandleCommand(string t)
        {
            if (RxToggle.IsMatch(t))
            {
                mode = (mode == RouteMode.CommandFirst) ? RouteMode.ChatFirst : RouteMode.CommandFirst;
                Debug.Log($"[Router] mode={mode}");
                return true;
            }
            if (RxStart.IsMatch(t)) { onStartListening?.Invoke(); return true; }
            if (RxStop.IsMatch(t))  { onStopListening?.Invoke();  return true; }
            if (RxClear.IsMatch(t)) { onClearCaptions?.Invoke();  return true; }
            if (RxCancel.IsMatch(t)){ onCancelCurrent?.Invoke();  return true; }

            return false;
        }
    }
}
