/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

import { useStdin, useStdout } from 'ink';
import { useEffect, useState } from 'react';
import { useKeypress } from './useKeypress.js';

// ANSI escape codes to enable/disable terminal focus reporting
export const ENABLE_FOCUS_REPORTING = '\x1b[?1004h';
export const DISABLE_FOCUS_REPORTING = '\x1b[?1004l';

// ANSI escape codes for focus events
export const FOCUS_IN = '\x1b[I';
export const FOCUS_OUT = '\x1b[O';

export const useFocus = (): {
  isFocused: boolean;
  hasReceivedFocusEvent: boolean;
} => {
  const { stdin } = useStdin();
  const { stdout } = useStdout();
  const [isFocused, setIsFocused] = useState(true);
  const [hasReceivedFocusEvent, setHasReceivedFocusEvent] = useState(false);

  useEffect(() => {
    const handleData = (data: Buffer) => {
      const sequence = data.toString();
      const lastFocusIn = sequence.lastIndexOf(FOCUS_IN);
      const lastFocusOut = sequence.lastIndexOf(FOCUS_OUT);

      if (lastFocusIn > lastFocusOut) {
        setHasReceivedFocusEvent(true);
        setIsFocused(true);
      } else if (lastFocusOut > lastFocusIn) {
        setHasReceivedFocusEvent(true);
        setIsFocused(false);
      }
    };

    // Enable focus reporting
    stdout?.write(ENABLE_FOCUS_REPORTING);
    stdin?.on('data', handleData);

    return () => {
      // Disable focus reporting on cleanup
      stdout?.write(DISABLE_FOCUS_REPORTING);
      stdin?.removeListener('data', handleData);
    };
  }, [stdin, stdout]);

  useKeypress(
    (_) => {
      if (!isFocused) {
        // If the user has typed a key, and we cannot possibly be focused out.
        // This is a workaround for some tmux use cases. It is still useful to
        // listen for the true FOCUS_IN event as well as that will update the
        // focus state earlier than waiting for a keypress.
        setIsFocused(true);
      }
    },
    { isActive: true },
  );

  return {
    isFocused,
    hasReceivedFocusEvent,
  };
};
