import React = require('react');
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { IReactionDisposer, ObservableMap, action, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { Doc, NumListCast, Opt } from '../../../../fields/Doc';
import { returnFalse, setupMoveUpEvents, unimplementedFunction } from '../../../../Utils';
import { SelectionManager } from '../../../util/SelectionManager';
import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu';
// import { GPTPopup, GPTPopupMode } from './../../GPTPopup/GPTPopup';
import { Button, IconButton } from 'browndash-components';
import { SettingsManager } from '../../../util/SettingsManager';
import './MapAnchorMenu.scss';
import { NumCast, StrCast } from '../../../../fields/Types';
import { 
    IconLookup, 
    faDiamondTurnRight, 
    faCalendarDays, 
    faEdit, 
    faAdd, 
    faRoute, 
    faArrowLeft,
    faLocationDot,
    faArrowDown,
    faCar,
    faBicycle,
    faPersonWalking,
    faUpload,
    faArrowsRotate,
 } from '@fortawesome/free-solid-svg-icons';
import { DirectionsAnchorMenu } from './DirectionsAnchorMenu';
import { Autocomplete, Checkbox, FormControlLabel, TextField } from '@mui/material';
import { MapboxApiUtility, TransportationType } from './MapboxApiUtility';
import { MapBox } from './MapBox';
import { List } from '../../../../fields/List';

type MapAnchorMenuType = 'standard' | 'route' | 'calendar' | 'customize';

@observer
export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
    static Instance: MapAnchorMenu;

    private _disposer: IReactionDisposer | undefined;
    private _commentRef = React.createRef<HTMLDivElement>();
    private _fileInputRef = React.createRef<HTMLInputElement>();

    public onMakeAnchor: () => Opt<Doc> = () => undefined; // Method to get anchor from text search

    public Center: () => void = unimplementedFunction;
    public OnClick: (e: PointerEvent) => void = unimplementedFunction;
    // public OnAudio: (e: PointerEvent) => void = unimplementedFunction;
    public StartDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction;
    public Highlight: (color: string, isTargetToggler: boolean, savedAnnotations?: ObservableMap<number, HTMLDivElement[]>, addAsAnnotation?: boolean) => Opt<Doc> = (color: string, isTargetToggler: boolean) => undefined;
    public GetAnchor: (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => Opt<Doc> = (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => undefined;
    public Delete: () => void = unimplementedFunction;
    // public MakeTargetToggle: () => void = unimplementedFunction;
    // public ShowTargetTrail: () => void = unimplementedFunction;
    public IsTargetToggler: () => boolean = returnFalse;

    public DisplayRoute: (routeInfoMap: Record<TransportationType, any> | undefined, type: TransportationType) => void = unimplementedFunction;
    public HideRoute: () => void = unimplementedFunction;
    public AddNewRouteToMap: (coordinates: List<any>, origin: string, destination: string) => void = unimplementedFunction;
    public CreatePin: (feature: any) => void = unimplementedFunction;


    private allMapPinDocs: Doc[] = [];

    private pinDoc: Doc | undefined = undefined 

    private title: string | undefined = undefined;


    public setPinDoc(pinDoc: Doc){
        this.pinDoc = pinDoc;
        this.title = StrCast(pinDoc.title ? pinDoc.title : `${NumCast(pinDoc.longitude)}, ${NumCast(pinDoc.latitude)}`) ;
    }

    public setAllMapboxPins(pinDocs: Doc[]) {
        this.allMapPinDocs = pinDocs;
        pinDocs.forEach((p, idx) => {
            console.log(`Pin ${idx}: ${p.title}`);
        })
    }   

    public get Active() {
        return this._left > 0;
    }

    constructor(props: Readonly<{}>) {
        super(props);

        MapAnchorMenu.Instance = this;
        MapAnchorMenu.Instance._canFade = false;
    }

    componentWillUnmount() {
        this.destinationFeatures = [];
        this.destinationSelected = false;
        this.selectedDestinationFeature = undefined;
        this.currentRouteInfoMap = undefined;
        this._disposer?.();
    }

    componentDidMount() {
        this._disposer = reaction(
            () => SelectionManager.Views().slice(),
            sel => MapAnchorMenu.Instance.fadeOut(true)
        );
    }
    // audioDown = (e: React.PointerEvent) => {
    //     setupMoveUpEvents(this, e, returnFalse, returnFalse, e => this.OnAudio?.(e));
    // };

    // cropDown = (e: React.PointerEvent) => {
    //     setupMoveUpEvents(
    //         this,
    //         e,
    //         (e: PointerEvent) => {
    //             this.StartCropDrag(e, this._commentCont.current!);
    //             return true;
    //         },
    //         returnFalse,
    //         e => this.OnCrop?.(e)
    //     );
    // };
    notePointerDown = (e: React.PointerEvent) => {
        setupMoveUpEvents(
            this,
            e,
            (e: PointerEvent) => {
                this.StartDrag(e, this._commentRef.current!);
                return true;
            },
            returnFalse,
            e => this.OnClick(e)
        );
    };

    static top = React.createRef<HTMLDivElement>();

    // public get Top(){
    //     return this.top
    // }

    @observable
    menuType: MapAnchorMenuType = 'standard';

    @action
    DirectionsClick = () => {
        this.menuType = 'route';
    }

    @action
    CustomizeClick = () => {
        this.menuType = 'customize';
    }

    @action
    BackClick = () => {
        this.menuType = 'standard';
    }

    @action
    TriggerFileInputClick = () => {
        if (this._fileInputRef) {
            this._fileInputRef.current?.click(); // Trigger the file input click event
          }
    }


    @observable
    destinationFeatures: any[] = []

    @observable
    destinationSelected: boolean = false;

    @observable
    selectedDestinationFeature: any = undefined;

    @observable 
    createPinForDestination: boolean = true;

    @observable
    currentRouteInfoMap: Record<TransportationType, any> | undefined = undefined;

    @observable
    selectedTransportationType: TransportationType = 'driving';

    @action
    handleTransportationTypeChange = (newType: TransportationType) => {
        if (newType !== this.selectedTransportationType){
            this.selectedTransportationType = newType;
            this.DisplayRoute(this.currentRouteInfoMap, newType);
        }

    }

    @action
    handleSelectedDestinationFeature = (destinationFeature: any) => {
        this.selectedDestinationFeature = destinationFeature;
    }

    @action
    toggleCreatePinForDestinationCheckbox = () => {
        this.createPinForDestination = !this.createPinForDestination;
    }

    @action
    handleDestinationSearchChange = async (searchText: string) => {
        if (this.selectedDestinationFeature !== undefined) this.selectedDestinationFeature = undefined;
        const features = await MapboxApiUtility.forwardGeocodeForFeatures(searchText);
        if (features){
            runInAction(() => {
                this.destinationFeatures = features;
                
            })
        }
    }

    getRoutes = async (destinationFeature: any) => {
        const currentPinLong: number = NumCast(this.pinDoc?.longitude);
        const currentPinLat: number = NumCast(this.pinDoc?.latitude);

        if (currentPinLong && currentPinLat && destinationFeature.center){
            const routeInfoMap = await MapboxApiUtility.getDirections([currentPinLong, currentPinLat], destinationFeature.center);
            if (routeInfoMap) {
                runInAction(() => {
                    this.currentRouteInfoMap = routeInfoMap;
                })
                this.DisplayRoute(routeInfoMap, 'driving');
            }
        }

        // get route menu, set it equal to here 
        // create a temporary route 
        // create pin if createPinForDestination was clicked
    }

    HandleAddRouteClick = () => {
        if (this.currentRouteInfoMap && this.selectedTransportationType && this.selectedDestinationFeature){
            const coordinates = this.currentRouteInfoMap[this.selectedTransportationType].coordinates;
            this.AddNewRouteToMap(this.currentRouteInfoMap![this.selectedTransportationType].coordinates, this.title ?? "", this.selectedDestinationFeature.place_name);
            this.HideRoute();
        }
    }


    render() {
        const buttons = (
            <div className='menu-buttons' style={{display: 'flex'}}>
                {this.menuType === 'standard' && 
                    <>
                        <IconButton
                        tooltip="Delete Pin" //
                        onPointerDown={this.Delete}
                        icon={<FontAwesomeIcon icon="trash-alt" />}
                        color={SettingsManager.userColor}
                        />
                        <IconButton
                            tooltip='Get directions'
                            onPointerDown={this.DirectionsClick} /**TODO: fix */
                            icon={<FontAwesomeIcon icon={faDiamondTurnRight as IconLookup}/>}
                            color={SettingsManager.userColor}
                        />
                        <IconButton
                            tooltip='Add to calendar'
                            onPointerDown={this.Delete} /**TODO: fix */
                            icon={<FontAwesomeIcon icon={faCalendarDays as IconLookup}/>}
                            color={SettingsManager.userColor}
                        />
                        <div ref={this._commentRef}>
                            <IconButton
                                tooltip="Link Note to Pin" //
                                onPointerDown={this.notePointerDown}
                                icon={<FontAwesomeIcon icon="sticky-note" />}
                                color={SettingsManager.userColor}
                            />
                        </div>
                        <IconButton
                            tooltip="Customize pin"
                            onPointerDown={this.CustomizeClick}
                            icon={<FontAwesomeIcon icon={faEdit as IconLookup}/>}
                            color={SettingsManager.userColor}
                        />
                        <IconButton
                            tooltip="Center on pin" //
                            onPointerDown={this.Center}
                            icon={<FontAwesomeIcon icon="compress-arrows-alt" />}
                            color={SettingsManager.userColor}
                        />
                    </>
                }
                {this.menuType === 'route' && 
                    <>
                        <IconButton
                            tooltip="Go back" //
                            onPointerDown={this.BackClick}
                            icon={<FontAwesomeIcon icon={faArrowLeft as IconLookup} />}
                            color={SettingsManager.userColor}
                        />
                        <IconButton
                            tooltip="Add route" //
                            onPointerDown={this.HandleAddRouteClick}
                            icon={<FontAwesomeIcon icon={faAdd as IconLookup} />}
                            color={SettingsManager.userColor}
                        />
                        <IconButton
                            tooltip='Animate route'
                            onPointerDown={this.Delete} /**TODO: fix */
                            icon={<FontAwesomeIcon icon={faRoute as IconLookup}/>}
                            color={SettingsManager.userColor}
                        />
                        <IconButton
                            tooltip='Add to calendar'
                            onPointerDown={this.Delete} /**TODO: fix */
                            icon={<FontAwesomeIcon icon={faCalendarDays as IconLookup}/>}
                            color={SettingsManager.userColor}
                        />
                    </>
                }
                {this.menuType === 'customize' &&
                    <>
                        <IconButton
                            tooltip="Go back" //
                            onPointerDown={this.BackClick}
                            icon={<FontAwesomeIcon icon={faArrowLeft as IconLookup} />}
                            color={SettingsManager.userColor}
                        />
                        <IconButton
                            tooltip="Upload image" //
                            onPointerDown={this.TriggerFileInputClick}
                            icon={<FontAwesomeIcon icon={faUpload as IconLookup} />}
                            color={SettingsManager.userColor}
                        />
                        <input
                            type="file"
                            accept="image/*" // Optionally, specify accepted file types
                            ref={this._fileInputRef}
                            style={{ display: "none" }}
                            onChange={() => {}}
                        />
                        <IconButton
                            tooltip="Revert to original" //
                            onPointerDown={this.BackClick}
                            icon={<FontAwesomeIcon icon={faArrowsRotate as IconLookup} />}
                            color={SettingsManager.userColor}
                        />
                    </>
                }
               
                
                {/* {this.IsTargetToggler !== returnFalse && (
                        <Toggle
                            tooltip={'Make target visibility toggle on click'}
                            type={Type.PRIM}
                            toggleType={ToggleType.BUTTON}
                            toggleStatus={this.IsTargetToggler()}
                            onClick={this.MakeTargetToggle}
                            icon={<FontAwesomeIcon icon="thumbtack" />}
                            color={SettingsManager.userColor}
                        />
                    )} */}
            </div>
        );
        // return (
        //     <div ref={MapAnchorMenu.top} style={{zIndex: 30000, width: '100%', height: '100px'}}>
        //         HELLO THIS IS ANCHOR MENU
        //         {this.getElement(buttons)}
        //     </div>
        // )

        return this.getElement(
            <div 
                ref={MapAnchorMenu.top} 
                className='map-anchor-menu-container'>
                {this.menuType === 'standard' &&
                    <div>{this.title}</div>
                }
                {this.menuType === 'route' && 
                    <div className='direction-inputs' style={{display: 'flex', flexDirection: 'column'}}>
                        <TextField
                            fullWidth
                            disabled
                            value={this.title}
                        />
                        <FontAwesomeIcon icon={faArrowDown as IconLookup} size='xs'/>
                        <Autocomplete
                            fullWidth
                            id="route-destination-searcher"
                            
                            onInputChange={(e, searchText) => this.handleDestinationSearchChange(searchText)}
                            onChange={(e, feature, reason) => {
                                if (reason === 'clear'){
                                    this.handleSelectedDestinationFeature(undefined);
                                } else if (reason === 'selectOption'){
                                    this.handleSelectedDestinationFeature(feature);
                                }
                            }}
                            options={this.destinationFeatures
                                .filter(feature => feature.place_name)
                                .map(feature => feature)}
                            getOptionLabel={(feature) => feature.place_name}
                            renderInput={(params) => (
                                <TextField
                                    {...params}
                                    placeholder='Enter a destination'
                                />
                            )}
                        />
                        {this.selectedDestinationFeature && 
                            <>
                             {!this.allMapPinDocs.some(pinDoc => pinDoc.title === this.selectedDestinationFeature.place_name) && 
                                <div style={{display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '5px'}}>
                                    <FormControlLabel
                                        label='Create pin for destination?'
                                        control={
                                            <Checkbox 
                                                color='success'
                                                checked={this.createPinForDestination}
                                                onChange={this.toggleCreatePinForDestinationCheckbox}
                                            />
                                        }
                                    />
                                </div>
                             }
                            </>
                           

                        }
                        <button 
                            id='get-routes-button'
                            disabled={this.selectedDestinationFeature ? false : true}
                            onClick={() => this.getRoutes(this.selectedDestinationFeature)}
                            >
                            Get routes
                        </button>

                        {/* <input
                            placeholder="Origin"
                        /> */}
                    </div>
                }
                {this.currentRouteInfoMap &&
                    <div className='current-route-info-container'> 
                        <div className='transportation-icons-container'>
                            <IconButton
                                tooltip="Driving route" 
                                onPointerDown={() => this.handleTransportationTypeChange('driving')}
                                icon={<FontAwesomeIcon icon={faCar as IconLookup}/>}
                                color={this.selectedTransportationType === 'driving' ? 'lightblue': 'grey'}
                            />
                            <IconButton
                                tooltip="Cycling route" 
                                onPointerDown={() => this.handleTransportationTypeChange('cycling')}
                                icon={<FontAwesomeIcon icon={faBicycle as IconLookup}/>}
                                color={this.selectedTransportationType === 'cycling' ? 'lightblue': 'grey'}
                            />
                            <IconButton
                                tooltip="Walking route" 
                                onPointerDown={() => this.handleTransportationTypeChange('walking')}
                                icon={<FontAwesomeIcon icon={faPersonWalking as IconLookup}/>}
                                color={this.selectedTransportationType === 'walking' ? 'lightblue': 'grey'}
                            />
                        </div>
                        <div className='selected-route-details-container'>
                            <div>Duration: {this.currentRouteInfoMap[this.selectedTransportationType].duration}</div>
                            <div>Distance: {this.currentRouteInfoMap[this.selectedTransportationType].distance}</div>
                        </div>
                    </div>
                    

                }
                {buttons}
            </div>
        , true);
    }
}
