/* eslint-disable react/jsx-props-no-spreading */
/* eslint-disable guard-for-in */
import { IconButton, Size, Type } from 'browndash-components';
import * as React from 'react';
import { FaCaretDown, FaCaretUp } from 'react-icons/fa';
import { GrClose } from 'react-icons/gr';
import { DocListCast, StrListCast } from '../../../../fields/Doc';
import { List } from '../../../../fields/List';
import { StrCast } from '../../../../fields/Types';
import { Colors } from '../../global/globalEnums';
import { DocumentView } from '../../nodes/DocumentView';
import { IBounds } from '../ExploreView/utils';
import { NewLightboxView } from '../NewLightboxView';
import { IRecommendation, Recommendation } from '../components';
import { IDocRequest, fetchKeywords, fetchRecommendations } from '../utils';
import './RecommendationList.scss';

export function RecommendationList() {
    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 () => {
            const text = StrCast(DocumentView.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);
            const lightboxDoc = DocumentView.LightboxDoc();
            if (lightboxDoc) {
                console.log('setting keywords on doc');
                lightboxDoc.keywords = new List<string>(kw);
                setKeywordsLoc(NewLightboxView.Keywords);
            }
            setLoadingKeywords(false);
        };
        const keywordsList = StrListCast(DocumentView.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(',');
            const src = StrCast(NewLightboxView.LightboxDoc?.text);
            const dashDocs: IDocRequest[] = [];
            // get linked docs
            const 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(DocumentView.LightboxDoc()?.context).data)
            // let docId = DocumentView.LightboxDoc() && DocumentView.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 theRecs = response.recommendations;
                const responseBounds: 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(responseBounds);
                const recommendations: IRecommendation[] = [];
                // eslint-disable-next-line no-restricted-syntax
                for (const key in theRecs) {
                    console.log(key);
                    const { title } = theRecs[key];
                    const { url } = theRecs[key];
                    const { type } = theRecs[key];
                    const { text } = theRecs[key];
                    const { transcript } = theRecs[key];
                    const { previewUrl } = theRecs[key];
                    const { embedding } = theRecs[key];
                    const { distance } = theRecs[key];
                    const { source } = theRecs[key];
                    const { related_concepts: relatedConcepts } = theRecs[key];
                    const docId = theRecs[key].doc_id;
                    relatedConcepts.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: relatedConcepts,
                            docId: docId,
                        });
                }
                recommendations.sort((a, b) => {
                    if (a.distance && b.distance) {
                        return a.distance - b.distance;
                    }
                    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) => (
                                <div className="keyword" key={word}>
                                    {' '}
                                    {word}
                                    <IconButton
                                        type={Type.PRIM}
                                        size={Size.XSMALL}
                                        color={Colors.DARK_GRAY}
                                        icon={<GrClose />}
                                        onClick={() => {
                                            const 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 => <Recommendation key={rec.data} {...rec} />)}</div>
        </div>
    );
}
