import { CollectionFreeFormView } from "../../views/collections/collectionFreeForm";
import React, { useState } from "react";

export function RecordingApi() {

    type Movement = {
        time: number,
        panX: number,
        panY: number,
    }

    type Presentation = {
        movements: Array<Movement>
        meta: Object,
        startDate: Date | null,
    }

    const NULL_PRESENTATION = {
        movements: [],
        meta: {},
        startDate: null,
    }

    const [currentPresentation, setCurrentPresenation] = useState<Presentation>(NULL_PRESENTATION)
    const [isRecording, setIsRecording] = useState(false)
    const [absoluteStart, setAbsoluteStart] = useState<number>(-1)

    const initAndStart = (view: CollectionFreeFormView, meta?: Object): Error | undefined => {
        // check if already init a presentation
        if (currentPresentation.startDate !== null) {
            console.error('[recordingApi.ts] start() failed: current presentation data exists. please call clear() first.')
            return new Error('[recordingApi.ts] start()')
        }

        // (1a) get start date for presenation
        const startDate = new Date()
        // (1b) set start timestamp to absolute timestamp
        setAbsoluteStart(startDate.getTime())

        // TODO: (2) assign meta content

        // (3) assign init values to currentPresenation
        setCurrentPresenation({ ...currentPresentation, startDate })

        // (4) set isRecording true to allow trackMovements
        setIsRecording(true)
    }

    const clear = (): Error | undefined => {
        // TODO: maybe archive the data?
        if (isRecording) {
            console.error('[recordingApi.ts] clear() failed: currently recording presentation. call pause() or finish() first')
            return new Error('[recordingApi.ts] clear()')
        }
        // clear presenation data
        setCurrentPresenation(NULL_PRESENTATION)

        // clear isRecording
        setIsRecording(false)

        // clear absoluteStart
        setAbsoluteStart(-1)
    }

    const pause = (): Error | undefined => {
        if (currentPresentation.startDate === null) {
            console.error('[recordingApi.ts] pause() failed: no presentation started. try calling init() first')
            return new Error('[recordingApi.ts] pause(): no presenation')
        }
        // don't allow track movments
        setIsRecording(false)

        // set relativeStart to the pausedTimestamp
        const timestamp = new Date().getTime()
        setAbsoluteStart(timestamp)
    }

    const resume = () => {
        if (currentPresentation.startDate === null) {
            console.error('[recordingApi.ts] resume() failed: no presentation started. try calling init() first')
            return new Error('[recordingApi.ts] resume()')
        }

        const timestamp = new Date().getTime()
        const startTimestamp = currentPresentation.startDate?.getTime()
        if (!startTimestamp) {
            console.error('[recordingApi.ts] resume() failed: no presentation data. try calling init() first')
            return new Error('[recordingApi.ts] pause()')
        }

        setAbsoluteStart(prevTime => { 
            // const relativeUnpause = timestamp - absoluteStart
            // const timePaused = relativeUnpause - prevTime
            // return timePaused + absoluteStart
            const absoluteTimePaused = timestamp - prevTime
            return absoluteTimePaused
        })
    }

    const finish = (): Error | Presentation => {
        if (currentPresentation.movements === null) {
            console.error('[recordingApi.ts] finish() failed: no presentation data. try calling init() first')
            return new Error('[recordingApi.ts] finish()')
        }

        // make copy and clear this class's data
        const returnCopy = { ...currentPresentation }
        clear()

        // return the copy
        return returnCopy
    }

    const trackMovements = (panX: number, panY: number): Error | undefined => {
        // ensure we are recording
        if (!isRecording) {
             console.error('[recordingApi.ts] pause() failed: recording is paused()')
            return new Error('[recordingApi.ts] pause()')
        }

        // get the relative time
        const timestamp = new Date().getTime()
        const relativeTime = timestamp - absoluteStart

        // make new movement struct
        const movement: Movement = { time: relativeTime, panX, panY }
        
        // add that movement struct to the current presentation data
        setCurrentPresenation(prevPres => {
            const movements = [...prevPres.movements, movement]
            return {...prevPres, movements}
        })
    }

    // TOOD: need to pause all intervals if possible lol
    // TODO: extract this into different class with pause and resume recording
    const followMovements = (presentation: Presentation, docView: CollectionFreeFormView): void => {
        const document = docView.Document

        const { movements } = presentation
        movements.forEach(movement => {
            const { panX, panY, time } = movement
            // set the pan to what was stored
            setTimeout(() => {
                document._panX = panX;
                document._panY = panY;
            }, time)
        })
    }

}