import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import React from 'react';
import { SettingsManager } from '../../../util/SettingsManager';
import { ObservableReactComponent } from '../../ObservableReactComponent';
import { Button, IconButton } from 'browndash-components';
import ReactLoading from 'react-loading';
import { AiOutlineSend } from 'react-icons/ai';
import { MarqueeOptionsMenu } from './MarqueeOptionsMenu';
import './ImageLabelHandler.scss';
import { gptAPICall, GPTCallType } from '../../../apis/gpt/GPT';
import { InkData } from '../../../../fields/InkField';
import { ButtonType } from '../../nodes/FontIconBox/FontIconBox';
import { SVGToBezier } from '../../../util/bezierFit';
const { parse, stringify } = require('svgson');

@observer
export class SmartDrawHandler extends ObservableReactComponent<{}> {
    static Instance: SmartDrawHandler;

    @observable private _display: boolean = false;
    @observable private _pageX: number = 0;
    @observable private _pageY: number = 0;
    @observable private _yRelativeToTop: boolean = true;
    @observable private _isLoading: boolean = false;
    @observable private _userInput: string = '';
    @observable private _drawingTypeToolTip = 'Create Geometric Drawing';
    @observable private _drawingTypeIcon: 'star' | 'splotch' = 'star';
    @observable private _alpha: number | undefined = undefined; // number between 0 and 1 that determines how rounded a drawing will be
    // @observable public strokes: InkData[] = [];
    private _addToDocFunc: (strokeList: InkData[], alpha?: number) => void = () => {};

    constructor(props: any) {
        super(props);
        makeObservable(this);
        SmartDrawHandler.Instance = this;
    }

    @action
    setIsLoading = (isLoading: boolean) => {
        this._isLoading = isLoading;
    };

    @action
    setUserInput = (input: string) => {
        this._userInput = input;
    };

    @action
    displaySmartDrawHandler = (x: number, y: number, addToDoc: (strokeList: InkData[], alpha?: number) => void) => {
        this._pageX = x;
        this._pageY = y;
        this._display = true;
        this._addToDocFunc = addToDoc;
    };

    @action
    hideSmartDrawHandler = () => {
        this._display = false;
    };

    @action
    drawWithGPT = async (startPoint: { X: number; Y: number }, input: string) => {
        console.log('start point is', startPoint);
        this.setIsLoading(true);
        try {
            const res = await gptAPICall(input, GPTCallType.DRAW);
            if (!res) {
                console.error('GPT call failed');
                return;
            }
            console.log('GPT response:', res);
            const svg = res.match(/<svg[^>]*>([\s\S]*?)<\/svg>/g);
            console.log('svg', svg);
            if (svg) {
                const svgObject = await parse(svg[0]);
                console.log('svg object', svgObject);
                const svgStrokes: any = svgObject.children;
                const beziers: InkData[] = [];
                svgStrokes.forEach((stroke: any) => {
                    const convertedBezier: InkData = SVGToBezier(stroke.name, stroke.attributes);
                    beziers.push(
                        convertedBezier.map(point => {
                            return { X: point.X + startPoint.X, Y: point.Y + startPoint.Y };
                        })
                    );
                });
                this._addToDocFunc(beziers);
            }

            // const strokes = res.trim().split(/\s*(?=\s*M)/); // prettier-ignore
            // const parsedSegments: InkData[] = [];
            // console.log('strokes', strokes);
            // strokes.forEach(stroke => {
            //     stroke = stroke.replace(/C\s*\((\d+,\d+)\)\s*\((\d+,\d+)\)\s*\((\d+,\d+)\)/g, (c, p1, p2, p3) => {
            //         return `C (${p1}) (${p2}) (${p3}) (${p3})`;
            //     });
            //     const coordStrings = stroke.match(/(\d+,\d+)/g);
            //     const coords: InkData = [];
            //     if (coordStrings) {
            //         coordStrings.forEach(coord => {
            //             const xy = coord.split(',');
            //             coords.push({ X: parseInt(xy[0]), Y: parseInt(xy[1]) });
            //         });
            //         coords.pop();
            //         parsedSegments.push(coords);
            //     }
            //     console.log('coords', coords);
            // });
            // this._addToDocFunc(parsedSegments);
        } catch (err) {
            console.error('GPT call failed', err);
        }

        this.setIsLoading(false);
        this.setUserInput('');
        this.hideSmartDrawHandler();
    };

    changeDrawingType = () => {
        if (this._drawingTypeIcon === 'star') {
            this._drawingTypeIcon = 'splotch';
            this._drawingTypeToolTip = 'Create Rounded Drawing';
            this._alpha = 0.2;
        } else {
            this._drawingTypeIcon = 'star';
            this._drawingTypeToolTip = 'Create Geometric Drawing';
            this._alpha = 0;
        }
    };

    render() {
        if (this._display) {
            return (
                <div
                    id="label-handler"
                    className="contextMenu-cont"
                    style={{
                        display: this._display ? '' : 'none',
                        left: this._pageX,
                        ...(this._yRelativeToTop ? { top: Math.max(0, this._pageY) } : { bottom: this._pageY }),
                        background: SettingsManager.userBackgroundColor,
                        color: SettingsManager.userColor,
                    }}>
                    <div>
                        <IconButton tooltip={'Cancel'} onClick={this.hideSmartDrawHandler} icon={<FontAwesomeIcon icon="xmark" />} color={MarqueeOptionsMenu.Instance.userColor} style={{ width: '19px' }} />
                        <input
                            aria-label="label-input"
                            id="new-label"
                            type="text"
                            style={{ color: 'black' }}
                            value={this._userInput}
                            onChange={e => {
                                this.setUserInput(e.target.value);
                            }}
                            placeholder="Enter item to draw"
                        />
                        <IconButton tooltip={this._drawingTypeToolTip} icon={<FontAwesomeIcon icon={this._drawingTypeIcon} />} color={MarqueeOptionsMenu.Instance.userColor} style={{ width: '14px' }} onClick={this.changeDrawingType} />
                        {/* <IconButton
                            tooltip="Create Geometric Drawing"
                            icon={<FontAwesomeIcon icon="star" />}
                            color={MarqueeOptionsMenu.Instance.userColor}
                            style={{ width: '14px' }}
                            onClick={() => {
                                this._alpha = 0;
                            }}
                        /> */}
                        <Button
                            style={{ alignSelf: 'flex-end' }}
                            text="Send"
                            icon={this._isLoading ? <ReactLoading type="spin" color="#ffffff" width={20} height={20} /> : <AiOutlineSend />}
                            iconPlacement="right"
                            color={MarqueeOptionsMenu.Instance.userColor}
                            onClick={e => {
                                this.drawWithGPT({ X: e.clientX, Y: e.clientY }, this._userInput);
                            }}
                        />
                    </div>
                </div>
            );
        } else {
            return <></>;
        }
    }
}
