import React from 'react';
import styled, { ThemeProvider, createGlobalStyle } from 'styled-components';
import { WidgetCore } from './DocsGPTWidget';
import { SearchBarProps } from '@/types';
import { getSearchResults } from '../requests/searchAPI';
import { Result } from '@/types';
import MarkdownIt from 'markdown-it';
import { getOS, processMarkdownString } from '../utils/helper';
import DOMPurify from 'dompurify';
import {
    CodeIcon,
    TextAlignLeftIcon,
    HeadingIcon,
    ReaderIcon,
    ListBulletIcon,
    QuoteIcon
} from '@radix-ui/react-icons';
const themes = {
    dark: {
        name: 'dark',
        bg: '#202124',
        text: '#EDEDED',
        primary: {
            text: "#FAFAFA",
            bg: '#111111'
        },
        secondary: {
            text: "#A1A1AA",
            bg: "#38383b"
        }
    },
    light: {
        name: 'light',
        bg: '#EAEAEA',
        text: '#171717',
        primary: {
            text: "#222327",
            bg: "#fff"
        },
        secondary: {
            text: "#A1A1AA",
            bg: "#F6F6F6"
        }
    }
}

const GlobalStyle = createGlobalStyle`
  .highlight {
    color: ${props => props.theme.name === 'dark' ? '#4B9EFF' : '#0066CC'};
    font-weight: 500;
  }
`;

const loadGeistFont = () => {
    const link = document.createElement('link');
    link.href = 'https://fonts.googleapis.com/css2?family=Geist:wght@100..900&display=swap';
    link.rel = 'stylesheet';
    document.head.appendChild(link);
};

const Main = styled.div`
    all: initial;
    font-family: 'Geist', sans-serif;
`
const SearchButton = styled.button<{ inputWidth: string }>`
    padding: 6px 6px;
    font-family: inherit;
    width: ${({ inputWidth }) => inputWidth};
    border-radius: 8px;
    display: inline;
    color: ${props => props.theme.secondary.text};
    outline: none;
    border: none;
    background-color: ${props => props.theme.secondary.bg};
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    transition: background-color 128ms linear;
    text-align: left;
    cursor: pointer;
`

const Container = styled.div`
    position: relative;
    display: inline-block;
`
const SearchOverlay = styled.div`
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: #0000001A;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    z-index: 99;
`;


const SearchResults = styled.div`
    position: fixed;
    display: flex;
    flex-direction: column;
    background-color: ${props => props.theme.name === 'dark' ? 
        'rgba(0, 0, 0, 0.15)' : 
        'rgba(255, 255, 255, 0.4)'};
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 15px;
    padding: 8px 0px 8px 0px;
    width: 792px;
    max-width: 90vw;
    height: 396px;
    z-index: 100;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    color: ${props => props.theme.primary.text};
    
    box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-radius: 10px;
    
    box-sizing: border-box;

    @media only screen and (max-width: 768px) {
        height: 80vh;
        width: 90vw;
    }
`;

const SearchResultsScroll = styled.div`
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    scrollbar-gutter: stable;
    scrollbar-width: thin;
    scrollbar-color: #383838 transparent;
    padding: 0 16px;
`;

const IconTitleWrapper = styled.div`
    display: flex;
    align-items: center;
    gap: 8px;

    .element-icon{
        margin: 4px;
    }
`;

const Title = styled.h3`
    font-size: 15px;
    font-weight: 400;
    color: ${props => props.theme.primary.text};
    margin: 0;
    overflow-wrap: break-word;
    white-space: normal;
    overflow: hidden;
    text-overflow: ellipsis;
`;
const ContentWrapper = styled.div`
    display: flex;
    flex-direction: column;
    gap: 12px; 
`;



const ResultWrapper = styled.div`
    display: flex;
    align-items: flex-start;
    width: 100%;
    box-sizing: border-box;
    padding: 8px 16px;
    cursor: pointer;
    background-color: transparent;
    font-family: 'Geist', sans-serif;
    border-radius: 8px;

    word-wrap: break-word;
    overflow-wrap: break-word;
    word-break: break-word;
    white-space: normal;
    overflow: hidden;
    text-overflow: ellipsis;

    &:hover {
        backdrop-filter: blur(8px);
        -webkit-backdrop-filter: blur(8px);
    }
`;

const Content = styled.div`
    display: flex;
    margin-left: 8px;
    flex-direction: column;
    gap: 8px;
    padding: 4px 0px 0px 12px;
    font-size: 15px;
    color: ${props => props.theme.primary.text};
    line-height: 1.6;
    border-left: 2px solid ${props => props.theme.primary.text}CC;
    overflow: hidden;
    
`;
const ContentSegment = styled.div`
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding-right: 16px;
    overflow-wrap: break-word;
    white-space: normal;
    overflow: hidden; 
    text-overflow: ellipsis;
`

const Markdown = styled.div`
line-height:18px;
font-size: 11px;
white-space: pre-wrap;
 pre {
      padding: 8px;
      width: 90%;
      font-size: 11px;
      border-radius: 6px;
      overflow-x: auto;
      background-color: #1B1C1F;
      color: #fff ;
    }

    h1,h2 {
      font-size: 14px;
      font-weight: 600;
      color: ${(props) => props.theme.text};
      opacity: 0.8;
    }


    h3 {
      font-size: 12px;
    }

    p {
      margin: 0px;
      line-height: 1.35rem;
      font-size: 11px;
    }

    code:not(pre code) {
      border-radius: 6px;
      padding: 2px 2px;
      margin: 2px;
      font-size: 9px;
      display: inline;
      background-color: #646464;
      color: #fff ;
    }
    img{
        max-width: 50%;
    }
    code {
      overflow-x: auto;
    }
    a{
        color: #007ee6;
    }
`
const Toolkit = styled.kbd`
    position: absolute;
    right: 4px;
    top: 50%;
    transform: translateY(-50%);
    background-color: ${(props) => props.theme.primary.bg};
    color: ${(props) => props.theme.secondary.text};
    font-weight: 600;
    font-size: 10px;
    padding: 3px 6px;
    border: 1px solid ${(props) => props.theme.secondary.text};
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1;
    pointer-events: none;
`
const Loader = styled.div`
  margin: 2rem auto;
  border: 4px solid ${props => props.theme.name === 'dark' ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.1)'};
  border-top: 4px solid ${props => props.theme.name === 'dark' ? '#FFFFFF' : props.theme.primary.bg};
  border-radius: 50%;
  width: 12px;
  height: 12px;
  animation: spin 1s linear infinite;

  @keyframes spin {
    0% {
      transform: rotate(0deg);
    }
    100% {
      transform: rotate(360deg);
    }
  }
`;

const NoResults = styled.div`
  margin-top: 2rem;
  text-align: center;
  font-size: 14px;
  color: ${props => props.theme.name === 'dark' ? '#E0E0E0' : '#505050'};
  font-weight: 500;
`;
const AskAIButton = styled.button`
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 12px;
    width: calc(100% - 32px);
    margin: 0 16px 16px 16px;
    box-sizing: border-box;
    height: 50px;
    padding: 8px 24px;
    border: none;
    border-radius: 8px;
    color: ${props => props.theme.text}; 
    cursor: pointer;
    font-size: 16px;
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
    border: 1px solid ${props => props.theme.name === 'dark' ? 
        'rgba(255, 255, 255, 0.2)' : 
        'rgba(0, 0, 0, 0.1)'};
    background-color: ${props => props.theme.name === 'dark' ? 
        'rgba(255, 255, 255, 0.05)' : 
        'rgba(0, 0, 0, 0.03)'}; // Very subtle background for light theme

    &:hover {
        backdrop-filter: blur(20px);
        -webkit-backdrop-filter: blur(20px);
        background-color: ${props => props.theme.name === 'dark' ? 
            'rgba(255, 255, 255, 0.1)' : 
            'rgba(0, 0, 0, 0.06)'}; // Subtle hover effect for light theme
    }
`;

const SearchHeader = styled.div`
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 12px;
    padding-bottom: 12px;
    border-bottom: 1px solid ${props => props.theme.name === 'dark' ? '#FFFFFF24' : 'rgba(0, 0, 0, 0.14)'};
`;



const TextField = styled.input`
    width: calc(100% - 32px);
    margin: 0 16px;
    padding: 12px 16px;
    border: none;
    background-color: transparent;
    color: ${props => props.theme.text}; 
    font-size: 20px;
    font-weight: 400; 
    outline: none;
    
    &:focus {
        border-color: none;
    }

    &::placeholder {
        color: ${props => props.theme.name === 'dark' ? 'rgba(255, 255, 255, 0.6)' : 'rgba(0, 0, 0, 0.5)'} !important;
        opacity: 100%; /* Force opacity to ensure placeholder is visible */
        font-weight: 500;
    }
`



const EscapeInstruction = styled.kbd`
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 12px 16px 0;
    padding: 4px 8px;
    border-radius: 4px;
    background-color: transparent;
    border: 1px solid ${props => props.theme.name === 'dark' ? 
        'rgba(237, 237, 237, 0.6)' : 
        'rgba(23, 23, 23, 0.6)'};
    color: ${props => props.theme.name === 'dark' ? '#EDEDED' : '#171717'};
    font-size: 12px;
    font-family: 'Geist', sans-serif;
    white-space: nowrap;
    cursor: pointer;
    width: fit-content;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
`;


export const SearchBar = ({
    apiKey = "74039c6d-bff7-44ce-ae55-2973cbf13837",
    apiHost = "https://gptcloud.arc53.com",
    theme = "dark",
    placeholder = "Search or Ask AI...",
    width = "256px",
    buttonText = "Search here"
}: SearchBarProps) => {
    const [input, setInput] = React.useState<string>("");
    const [loading, setLoading] = React.useState<boolean>(false);
    const [isWidgetOpen, setIsWidgetOpen] = React.useState<boolean>(false);
    const inputRef = React.useRef<HTMLInputElement>(null);
    const containerRef = React.useRef<HTMLInputElement>(null);
    const [isResultVisible, setIsResultVisible] = React.useState<boolean>(false);
    const [results, setResults] = React.useState<Result[]>([]);
    const debounceTimeout = React.useRef<ReturnType<typeof setTimeout> | null>(null);
    const abortControllerRef = React.useRef<AbortController | null>(null);
    const browserOS = getOS();
    const isTouch = 'ontouchstart' in window;

    const getKeyboardInstruction = () => {
        if (isResultVisible) return "Enter";
        return browserOS === 'mac' ? '⌘ + K' : 'Ctrl + K';
    };

    React.useEffect(() => {
        loadGeistFont()
        const handleClickOutside = (event: MouseEvent) => {
            if (containerRef.current && !containerRef.current.contains(event.target as Node)) {
                setIsResultVisible(false);
            }
        };

        const handleKeyDown = (event: KeyboardEvent) => {
            if (
                ((browserOS === 'win' || browserOS === 'linux') && event.ctrlKey && event.key === 'k') ||
                (browserOS === 'mac' && event.metaKey && event.key === 'k')
            ) {
                event.preventDefault();
                inputRef.current?.focus();
                setIsResultVisible(true);
            } else if (event.key === 'Escape') {
                setIsResultVisible(false);
            }
        };


        document.addEventListener('mousedown', handleClickOutside);
        document.addEventListener('keydown', handleKeyDown);
        return () => {
            document.removeEventListener('mousedown', handleClickOutside);
            document.removeEventListener('keydown', handleKeyDown);
        };
    }, []);

    React.useEffect(() => {
    if (!input) {
        setResults([]);
        setLoading(false);
        return;
    }
    setLoading(true);
    if (debounceTimeout.current) {
        clearTimeout(debounceTimeout.current);
    }

    if (abortControllerRef.current) {
        abortControllerRef.current.abort();
    }
    const abortController = new AbortController();
    abortControllerRef.current = abortController;

    debounceTimeout.current = setTimeout(() => {
        getSearchResults(input, apiKey, apiHost, abortController.signal)
            .then((data) => setResults(data))
            .catch((err) => !abortController.signal.aborted && console.log(err))
            .finally(() => setLoading(false));
    }, 500);

    return () => {
        abortController.abort();
        clearTimeout(debounceTimeout.current ?? undefined);
    };
}, [input])

    const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
        if (event.key === 'Enter') {
            event.preventDefault();
            openWidget();
        }
    };

    const openWidget = () => {
        setIsWidgetOpen(true);
        setIsResultVisible(false);
    };

    const handleClose = () => {
        setIsWidgetOpen(false);
        setIsResultVisible(true);
    };

    return (
        <ThemeProvider theme={{ ...themes[theme] }}>
            <Main>
                <GlobalStyle />
                <Container ref={containerRef}>
                    <SearchButton
                        onClick={() => setIsResultVisible(true)}
                        inputWidth={width}
                    >
                        {buttonText}
                    </SearchButton>
                    {
                        isResultVisible && (
                            <>
                            <SearchOverlay onClick={() => setIsResultVisible(false)} />
                            <SearchResults>
                                <SearchHeader>
                                    <TextField
                                        ref={inputRef}
                                        value={input}
                                        onChange={(e) => setInput(e.target.value)}
                                        onKeyDown={(e) => handleKeyDown(e)}
                                        placeholder={placeholder}
                                        autoFocus
                                    />
                                    <EscapeInstruction onClick={() => setIsResultVisible(false)}>
                                        Esc
                                    </EscapeInstruction>
                                </SearchHeader>
                                <AskAIButton onClick={openWidget}>
                                    <img
                                        src="https://d3dg1063dc54p9.cloudfront.net/cute-docsgpt.png"
                                        alt="DocsGPT"
                                        width={24}
                                        height={24}
                                    />
                                    <span>Ask the AI</span>
                                </AskAIButton>
                                <SearchResultsScroll>
                                    {!loading ? (
                                        results.length > 0 ? (
                                            results.map((res, key) => {
                                                const containsSource = res.source !== 'local';
                                                const processedResults = processMarkdownString(res.text, input);
                                                if (processedResults)
                                                    return (
                                                        <ResultWrapper
                                                            key={key}
                                                            onClick={() => {
                                                                if (!containsSource) return;
                                                                window.open(res.source, '_blank', 'noopener, noreferrer');
                                                            }}
                                                        >
                                                            <div style={{ flex: 1 }}>
                                                                <ContentWrapper>
                                                                    <IconTitleWrapper>
                                                                        <ReaderIcon className="title-icon" />
                                                                        <Title>{res.title}</Title>
                                                                    </IconTitleWrapper>
                                                                    <Content>
                                                                        {processedResults.map((element, index) => (
                                                                            <ContentSegment key={index}>
                                                                                <IconTitleWrapper>
                                                                                    {element.tag === 'code' && <CodeIcon className="element-icon" />}
                                                                                    {(element.tag === 'bulletList' || element.tag === 'numberedList') && <ListBulletIcon className="element-icon" />}
                                                                                    {element.tag === 'text' && <TextAlignLeftIcon className="element-icon" />}
                                                                                    {element.tag === 'heading' && <HeadingIcon className="element-icon" />}
                                                                                    {element.tag === 'blockquote' && <QuoteIcon className="element-icon" />}
                                                                                </IconTitleWrapper>
                                                                                <div
                                                                                    style={{ flex: 1 }}
                                                                                    dangerouslySetInnerHTML={{
                                                                                        __html: DOMPurify.sanitize(element.content),
                                                                                    }}
                                                                                />
                                                                            </ContentSegment>
                                                                        ))}
                                                                    </Content>
                                                                </ContentWrapper>
                                                            </div>
                                                        </ResultWrapper>
                                                    );
                                                return null;
                                            })
                                        ) : (
                                            <NoResults>No results found</NoResults>
                                        )
                                    ) : (
                                        <Loader />
                                    )}
                                </SearchResultsScroll>
                            </SearchResults>
                            </>
                        )
                    }
                    {
                        isTouch ?

                            <Toolkit
                                onClick={() => {
                                    setIsWidgetOpen(true)
                                }}
                                title={"Tap to Ask the AI"}>
                                Tap
                            </Toolkit>
                            :
                            <Toolkit
                                title={getKeyboardInstruction() === "Enter" ? "Press Enter to Ask AI" : ""}>
                                {getKeyboardInstruction()}
                            </Toolkit>
                    }
                </Container>
                <WidgetCore
                    theme={theme}
                    apiHost={apiHost}
                    apiKey={apiKey}
                    prefilledQuery={input}
                    isOpen={isWidgetOpen}
                    handleClose={handleClose} size={"large"}
                />
            </Main>
        </ThemeProvider>
    )
}
