import React, { useEffect, useMemo, useState } from 'react';
import { Dialog } from '@/components/elements/dialog';
import { Button } from '@/components/elements/button/index';
import Input from '@/components/elements/Input';
import GreyRowBox from '@/components/elements/GreyRowBox';
import type { OpenFile } from '../../EditorTabs';

interface FindResult {
    path: string;
    filename: string;
    line: number;
    preview: string;
}

interface Props {
    open: boolean;
    openFiles: OpenFile[];
    onClose: () => void;
    onOpenResult: (path: string, line: number) => void;
}

const MAX_RESULTS = 200;

const cx = (...parts: Array<string | false | null | undefined>) => parts.filter(Boolean).join(' ');

const getPreview = (line: string, index: number, length: number) => {
    const start = Math.max(0, index - 36);
    const end = Math.min(line.length, index + length + 72);
    const prefix = start > 0 ? '...' : '';
    const suffix = end < line.length ? '...' : '';
    return `${prefix}${line.slice(start, end).trim()}${suffix}`;
};

const FindInOpenFilesDialog: React.FC<Props> = ({ open, openFiles, onClose, onOpenResult }) => {
    const [query, setQuery] = useState('');

    useEffect(() => {
        if (!open) setQuery('');
    }, [open]);

    const results = useMemo<FindResult[]>(() => {
        const trimmed = query.trim().toLowerCase();
        if (!trimmed) return [];

        const nextResults: FindResult[] = [];
        for (const file of openFiles) {
            const lines = file.content.split('\n');
            for (let index = 0; index < lines.length; index += 1) {
                const line = lines[index];
                const matchIndex = line.toLowerCase().indexOf(trimmed);
                if (matchIndex === -1) continue;

                nextResults.push({
                    path: file.path,
                    filename: file.name || file.path.split('/').pop() || file.path,
                    line: index + 1,
                    preview: getPreview(line, matchIndex, trimmed.length),
                });

                if (nextResults.length >= MAX_RESULTS) return nextResults;
            }
        }

        return nextResults;
    }, [openFiles, query]);

    const hasQuery = query.trim().length > 0;

    return (
        <Dialog open={open} onClose={onClose} title='Find in Open Files'>
            <div className='space-y-4'>
                <Input
                    value={query}
                    autoFocus
                    onChange={(e) => setQuery(e.currentTarget.value)}
                    placeholder='Search open files...'
                />

                <GreyRowBox className='!flex-col !items-stretch !p-0 overflow-hidden' $hoverable={false}>
                    <div className='max-h-[420px] overflow-y-auto'>
                        {!hasQuery ? (
                            <div className='px-4 py-6 text-sm text-neutral-400'>Type to search open editor tabs.</div>
                        ) : results.length === 0 ? (
                            <div className='px-4 py-6 text-sm text-neutral-400'>No matches found.</div>
                        ) : (
                            results.map((result, index) => (
                                <button
                                    key={`${result.path}:${result.line}:${index}`}
                                    type='button'
                                    className={cx(
                                        'w-full border-b border-neutral-700 px-4 py-3 text-left transition-colors last:border-b-0',
                                        'hover:bg-neutral-700 focus:bg-neutral-700 focus:outline-none'
                                    )}
                                    onClick={() => {
                                        onOpenResult(result.path, result.line);
                                        onClose();
                                    }}
                                >
                                    <div className='flex items-center gap-3 text-sm'>
                                        <span className='min-w-0 flex-1 truncate font-semibold text-neutral-100'>{result.filename}</span>
                                        <span className='shrink-0 text-xs text-neutral-400'>Line {result.line}</span>
                                    </div>
                                    <div className='mt-1 truncate font-mono text-xs text-neutral-300'>{result.preview || '(empty line)'}</div>
                                    <div className='mt-1 truncate text-xs text-neutral-500'>{result.path}</div>
                                </button>
                            ))
                        )}
                    </div>
                </GreyRowBox>
            </div>
            <Dialog.Footer>
                <Button.Text onClick={onClose}>Close</Button.Text>
            </Dialog.Footer>
        </Dialog>
    );
};

export default FindInOpenFilesDialog;
