import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react';
import { ArrowUp, Paperclip, Square } from 'lucide-react';
import { IS_WORDPRESS } from '../../constants';
import {
  useCancelCurrentStream,
  useSendMessage,
  useCurrentConversationId,
  useCurrentConversationState,
} from '../../contexts/ChatContext';
import useRenderTracker from '../../hooks/useRenderTracker';
import {
  useAddComposerFiles,
  useClearComposerAttachments,
  useComposerAttachments,
  useComposerDraft,
  useComposerTextareaRef,
  useSetComposerDraft,
} from '../../contexts/ComposerContext';
import { useWorkflows, type Workflow } from '../../contexts/WorkflowsContext';
import { useApplyWorkflow } from '../../hooks/useApplyWorkflow';
import { findNextPlaceholder } from '../../utils/workflowTemplate';
import { useFeatureFlag } from '../../featureFlags';
import { composerAttachmentToChatInput } from '../../services/attachments';
import ComposerAttachments from './ComposerAttachments';
import WorkflowSlashMenu from './WorkflowSlashMenu';

const SLASH_MENU_LIMIT = 8;

interface InputSectionProps {
  scrollToBottom: (behavior: ScrollBehavior) => void;
}

const InputSection: React.FC<InputSectionProps> = ({ scrollToBottom }) => {
  const sendMessage = useSendMessage();
  const cancelCurrentStream = useCancelCurrentStream();
  const currentConversationId = useCurrentConversationId();
  const currentConversationState = useCurrentConversationState();
  const inputValue = useComposerDraft();
  const setInputValue = useSetComposerDraft();
  const textareaRef = useComposerTextareaRef();
  const isEnabled = !currentConversationId || currentConversationState?.phase === 'IDLE';
  const isStreaming = currentConversationState?.phase === 'THINKING' || currentConversationState?.phase === 'STREAMING';
  const showStop = isStreaming;

  const addFiles = useAddComposerFiles();
  const clearAttachments = useClearComposerAttachments();
  const attachments = useComposerAttachments();
  const fileInputRef = useRef<HTMLInputElement>(null);
  const readyAttachments = useMemo(
    () => attachments.filter((attachment) => attachment.status === 'ready'),
    [attachments]
  );
  const hasPendingAttachments = attachments.some((attachment) => attachment.status === 'uploading');
  const hasContent = inputValue.trim() !== '' || readyAttachments.length > 0;
  const canSubmit = hasContent && isEnabled && !hasPendingAttachments;

  // Workflow "/" slash command: typing a single-line draft starting with "/" opens
  // a picker of matching workflows above the composer. Plugin-only (web isn't
  // site-connected, so it has no real workflows).
  const workflowsEnabled = useFeatureFlag('workflows') && IS_WORDPRESS;
  const { workflows } = useWorkflows();
  const applyWorkflow = useApplyWorkflow();
  const [activeSlashIndex, setActiveSlashIndex] = useState(0);

  const slashQuery =
    workflowsEnabled && inputValue.startsWith('/') && !inputValue.includes('\n')
      ? inputValue.slice(1).trim().toLowerCase()
      : null;

  const slashItems = useMemo<Workflow[]>(() => {
    if (slashQuery === null) return [];
    const matched = slashQuery
      ? workflows.filter((w) => `${w.title} ${w.description ?? ''}`.toLowerCase().includes(slashQuery))
      : workflows;
    return matched.slice(0, SLASH_MENU_LIMIT);
  }, [slashQuery, workflows]);

  const slashOpen = slashItems.length > 0;

  useEffect(() => {
    setActiveSlashIndex(0);
  }, [slashQuery]);

  const selectWorkflow = useCallback(
    (workflow: Workflow) => {
      applyWorkflow(workflow); // replaces the "/query" draft with the expanded template
    },
    [applyWorkflow]
  );

  // Only track if we're at mobile breakpoint (sm:)
  const [isMobile, setIsMobile] = useState(() => 
    typeof window !== 'undefined' ? window.innerWidth < 640 : false
  );

  useRenderTracker('InputSection', {
    currentConversationState,
    inputValue,
    isMobile,
    currentConversationId,
    sendMessage,
    scrollToBottom,
  });

  useEffect(() => {
    const handleResize = () => {
      const mobile = window.innerWidth < 640; // Tailwind's sm: breakpoint
      setIsMobile(mobile);
    };

    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  useEffect(() => {
    if (textareaRef.current) {
      textareaRef.current.style.height = 'auto';
      textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;
    }
  }, [inputValue, isMobile, textareaRef]);

  const handleSubmit = useCallback(
    (e?: React.FormEvent) => {
      if (e) e.preventDefault();
      const trimmedValue = inputValue.trim();
      if (canSubmit) {
        const chatAttachments = readyAttachments
          .map(composerAttachmentToChatInput)
          .filter((attachment): attachment is NonNullable<typeof attachment> => Boolean(attachment));
        sendMessage(trimmedValue, chatAttachments);
        setInputValue('');
        clearAttachments();
        setTimeout(() => {
          scrollToBottom('smooth');
        }, 50);
      }
    },
    [inputValue, canSubmit, readyAttachments, sendMessage, scrollToBottom, setInputValue, clearAttachments]
  );

  const handlePaste = useCallback(
    (e: React.ClipboardEvent<HTMLTextAreaElement>) => {
      // Pull any image files off the clipboard (screenshots, copied images).
      const imageFiles = Array.from(e.clipboardData.items)
        .filter((item) => item.kind === 'file' && item.type.startsWith('image/'))
        .map((item) => item.getAsFile())
        .filter((file): file is File => file !== null);
      if (imageFiles.length === 0) return;
      // Prevent the binary from also landing in the textarea as junk text, but let
      // normal text pastes through untouched (we returned early above).
      e.preventDefault();
      addFiles(imageFiles);
    },
    [addFiles]
  );

  const handleKeyDown = useCallback(
    (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
      // Slash-command menu navigation takes priority while it's open.
      if (slashOpen) {
        if (e.key === 'ArrowDown') {
          e.preventDefault();
          setActiveSlashIndex((i) => (i + 1) % slashItems.length);
          return;
        }
        if (e.key === 'ArrowUp') {
          e.preventDefault();
          setActiveSlashIndex((i) => (i - 1 + slashItems.length) % slashItems.length);
          return;
        }
        if ((e.key === 'Enter' && !e.shiftKey) || e.key === 'Tab') {
          e.preventDefault();
          selectWorkflow(slashItems[activeSlashIndex] ?? slashItems[0]);
          return;
        }
        if (e.key === 'Escape') {
          e.preventDefault();
          setInputValue('');
          return;
        }
      }

      if (e.key === 'Enter' && !e.shiftKey) {
        e.preventDefault();
        handleSubmit();
      } else if (e.key === 'Tab') {
        e.preventDefault();
        // If the draft has [placeholder] blanks (from a workflow), Tab jumps to the
        // next one and selects it; otherwise fall back to inserting a tab character.
        const next = findNextPlaceholder(inputValue, e.currentTarget.selectionEnd);
        if (next) {
          setTimeout(() => textareaRef.current?.setSelectionRange(next[0], next[1]), 0);
          return;
        }
        const start = e.currentTarget.selectionStart;
        const end = e.currentTarget.selectionEnd;
        setInputValue((prevValue) =>
          prevValue.substring(0, start) + '\t' + prevValue.substring(end)
        );
        // Set cursor position after tab
        setTimeout(() => {
          if (textareaRef.current) {
            textareaRef.current.selectionStart = textareaRef.current.selectionEnd = start + 1;
          }
        }, 0);
      }
    },
    [slashOpen, slashItems, activeSlashIndex, selectWorkflow, inputValue, handleSubmit, setInputValue, textareaRef]
  );

  return (
    <form
      className={`mx-auto w-full ${IS_WORDPRESS ? 'pb-2' : 'pb-6'}`}
      onSubmit={handleSubmit}
    >
      <div className="relative rounded-2xl border border-app-border bg-app-surface px-3 py-2.5 shadow-composer transition focus-within:border-brand focus-within:ring-2 focus-within:ring-brand/25">
        {slashOpen && (
          <WorkflowSlashMenu
            items={slashItems}
            activeIndex={activeSlashIndex}
            onSelect={selectWorkflow}
            onHover={setActiveSlashIndex}
          />
        )}
        <ComposerAttachments />
        <textarea
          ref={textareaRef}
          rows={2}
          value={inputValue}
          onChange={(e) => setInputValue(e.target.value)}
          onKeyDown={handleKeyDown}
          onPaste={handlePaste}
          aria-label="Message"
          className="block max-h-[250px] min-h-[3rem] w-full resize-none overflow-y-auto bg-transparent py-1 text-[.95rem] leading-relaxed text-app-text placeholder:text-app-muted outline-none focus:ring-0 focus-visible:ring-0 scrollbar-custom"
          placeholder="Ask anything about your WordPress site…"
        />
        <div className="mt-1 flex items-center justify-between gap-2">
          <div className="flex items-center gap-1">
            <button
              type="button"
              onClick={() => fileInputRef.current?.click()}
              aria-label="Attach image"
              className="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg text-app-muted transition-colors hover:bg-app-surface-hover hover:text-app-text focus:outline-none focus-visible:ring-2 focus-visible:ring-brand"
            >
              <Paperclip size={18} />
            </button>
            <input
              ref={fileInputRef}
              type="file"
              accept="image/png,image/jpeg,image/webp,image/gif"
              multiple
              className="hidden"
              onChange={(e) => {
                if (e.target.files?.length) addFiles(e.target.files);
                e.target.value = '';
              }}
            />
          </div>
          {showStop ? (
            <button
              className="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-app-text text-app-surface shadow-sm transition-all hover:opacity-90 active:scale-95"
              type="button"
              onClick={cancelCurrentStream}
              aria-label="Stop generating"
            >
              <Square size={14} strokeWidth={2.5} className="fill-current" />
            </button>
          ) : (
            <button
              className="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-brand-button text-white shadow-sm transition-all enabled:hover:bg-brand-button-hover enabled:active:scale-95 disabled:bg-app-surface-muted disabled:text-app-muted disabled:shadow-none"
              disabled={!canSubmit}
              type="submit"
              aria-label="Send message"
            >
              <ArrowUp size={18} strokeWidth={2.5} />
            </button>
          )}
        </div>
      </div>
    </form>
  );
};

export default React.memo(InputSection);
