import { GrClose } from 'react-icons/gr';
import { IRecommendation, Recommendation } from "../components";
import './RecommendationList.scss';
import * as React from 'react';
import { IRecommendationList } from "./utils";
import { NewLightboxView } from '../NewLightboxView';
import { DocCast, StrCast } from '../../../../fields/Types';
import { FaCaretDown, FaCaretUp } from 'react-icons/fa';
import { Doc, DocListCast, StrListCast } from '../../../../fields/Doc';
import { IDocRequest, fetchKeywords, fetchRecommendations } from '../utils';
import { IBounds } from '../ExploreView/utils';
import { List } from '../../../../fields/List';
import { Id } from '../../../../fields/FieldSymbols';
import { LightboxView } from '../../LightboxView';
import { IconButton, Size, Type } from 'browndash-components';
import { Colors } from '../../global/globalEnums';

export const RecommendationList = (props: IRecommendationList) => {
    const {loading, keywords} = props
    const [loadingKeywords, setLoadingKeywords] = React.useState<boolean>(true)
    const [showMore, setShowMore] = React.useState<boolean>(false)
    const [keywordsLoc, setKeywordsLoc] = React.useState<string[]>([])
    const [update, setUpdate] = React.useState<boolean>(true)
    const initialRecs: IRecommendation[] = [
        {loading: true},
        {loading: true},
        {loading: true},
        {loading: true},
        {loading: true}
    ];
    const [recs, setRecs] = React.useState<IRecommendation[]>(initialRecs)

    React.useEffect(() => {
        const getKeywords = async () => {
            let text = StrCast(LightboxView.LightboxDoc?.text)
            console.log('[1] fetching keywords')
            const response = await fetchKeywords(text, 5, true)
            console.log('[2] response:', response)
            const kw = response.keywords;
            console.log(kw);
            NewLightboxView.SetKeywords(kw);
            if (LightboxView.LightboxDoc) {
                console.log('setting keywords on doc')
                LightboxView.LightboxDoc.keywords = new List<string>(kw);
                setKeywordsLoc(NewLightboxView.Keywords);
            }
            setLoadingKeywords(false)
        }
        let keywordsList = StrListCast(LightboxView.LightboxDoc!.keywords)
        if (!keywordsList || keywordsList.length < 2) {
            setLoadingKeywords(true)
            getKeywords()
            setUpdate(!update)
        } else {
            setKeywordsLoc(keywordsList)
            setLoadingKeywords(false)
            setUpdate(!update)
        }
    }, [NewLightboxView.LightboxDoc])

    // terms: vannevar bush, information spaces, 
    React.useEffect(() => {
        const getRecommendations = async () => {
            console.log('fetching recommendations')
            let query = 'undefined'
            if (keywordsLoc) query = keywordsLoc.join(',')
            let src = StrCast(NewLightboxView.LightboxDoc?.text)
            let dashDocs:IDocRequest[] = [];
            // get linked docs
            let linkedDocs = DocListCast(NewLightboxView.LightboxDoc?.links)
            console.log("linked docs", linkedDocs)
            // get context docs (docs that are also in the collection)
            // let contextDocs: Doc[] = DocListCast(DocCast(LightboxView.LightboxDoc?.context).data)
            // let docId = LightboxView.LightboxDoc && LightboxView.LightboxDoc[Id]
            // console.log("context docs", contextDocs)
            // contextDocs.forEach((doc: Doc) => {
            //     if (docId !== doc[Id]){
            //         dashDocs.push({
            //             title: StrCast(doc.title),
            //             text: StrCast(doc.text),
            //             id: doc[Id],
            //             type: StrCast(doc.type)
            //         })
            //     }
            // })
            console.log("dash docs", dashDocs)
            if (query !== undefined) {
                const response = await fetchRecommendations(src, query, [], true)
                const num_recs = response.num_recommendations
                const recs = response.recommendations
                const keywords = response.keywords
                const response_bounds: IBounds = {
                  max_x: response.max_x,
                  max_y: response.max_y,
                  min_x: response.min_x,
                  min_y: response.min_y
                }
                // if (NewLightboxView.NewLightboxDoc) {
                //     NewLightboxView.NewLightboxDoc.keywords = new List<string>(keywords);
                //     setKeywordsLoc(NewLightboxView.Keywords);
                // }
                // console.log(response_bounds)
                NewLightboxView.SetBounds(response_bounds)
                const recommendations: IRecommendation[] = [];
                for (const key in recs) {
                    console.log(key)
                    const title = recs[key].title;
                    const url = recs[key].url
                    const type = recs[key].type
                    const text = recs[key].text
                    const transcript = recs[key].transcript
                    const previewUrl = recs[key].previewUrl
                    const embedding = recs[key].embedding
                    const distance = recs[key].distance
                    const source = recs[key].source
                    const related_concepts = recs[key].related_concepts
                    const docId = recs[key].doc_id
                    related_concepts.length >= 1 && recommendations.push({
                        title: title,
                        data: url,
                        type: type,
                        text: text,
                        transcript: transcript,
                        previewUrl: previewUrl,
                        embedding: embedding,
                        distance: Math.round(distance * 100) / 100,
                        source: source,
                        related_concepts: related_concepts,
                        docId: docId
                    })
                }
                recommendations.sort((a, b) => {
                    if (a.distance && b.distance) {
                        return a.distance - b.distance
                    } else return 0
                })
                console.log("[rec]: ", recommendations)
                NewLightboxView.SetRecs(recommendations)
                setRecs(recommendations)
            }
        }
        getRecommendations();
    }, [update])
    
    

    return <div className={`recommendationlist-container`} onPointerDown={(e) => {e.stopPropagation()}}>
        <div className={`header`}>
            <div className={`title`}>
                Recommendations
            </div>
            {NewLightboxView.LightboxDoc && <div style={{fontSize: 10}}>
                The recommendations are produced based on the text in the document <b><u>{StrCast(NewLightboxView.LightboxDoc.title)}</u></b>. The following keywords are used to fetch the recommendations.
            </div>}
            <div className={`lb-label`}>Keywords</div>
            {loadingKeywords ? <div className={`keywords`}>
                    <div className={`keyword ${loadingKeywords && 'loading'}`}/>
                    <div className={`keyword ${loadingKeywords && 'loading'}`}/>
                    <div className={`keyword ${loadingKeywords && 'loading'}`}/>
                    <div className={`keyword ${loadingKeywords && 'loading'}`}/>
                    </div>
                :
                <div className={`keywords`}>
                {keywordsLoc && keywordsLoc.map((word, ind) => {
                    return <div className={`keyword`}>
                        {word}
                        <IconButton type={Type.PRIM} size={Size.XSMALL} color={Colors.DARK_GRAY} icon={<GrClose/>} onClick={() => {
                            let kw = keywordsLoc
                            kw.splice(ind)
                            NewLightboxView.SetKeywords(kw)
                        }}/>
                    </div>
                })}
            </div>
            }
            {!showMore ?
            <div className={`lb-caret`} onClick={() => {setShowMore(true)}}>
                More <FaCaretDown/>
            </div>
            :
            <div className={`more`}>
                <div className={`lb-caret`} onClick={() => {setShowMore(false)}}>
                    Less <FaCaretUp/>
                </div>
                <div className={`lb-label`}>Type</div>
                <div className={`lb-label`}>Sources</div>
            </div>
            }
        </div>
        <div className={`recommendations`}>
            {recs && recs.map((rec: IRecommendation) => {
                return <Recommendation {...rec} />
            })}
        </div>
    </div>
}