/*
Copyright 2024 New Vector Ltd.
Copyright 2020-2022 The Matrix.org Foundation C.I.C.

SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/

import { CallState, type MatrixCall } from "matrix-js-sdk/src/webrtc/call";
import React from "react";
import { Resizable } from "re-resizable";

import { LegacyCallHandlerEvent } from "../../../LegacyCallHandler";
import LegacyCallView from "./LegacyCallView";
import { SDKContext } from "../../../contexts/SDKContext";

interface IProps {
    // What room we should display the call for
    roomId: string;

    showApps?: boolean;
}

interface IState {
    call: MatrixCall | null;
    sidebarShown: boolean;
}

/*
 * Wrapper for LegacyCallView that always display the call in a given room,
 * or nothing if there is no call in that room.
 */
export default class LegacyCallViewForRoom extends React.Component<IProps, IState> {
    public static contextType = SDKContext;
    declare public context: React.ContextType<typeof SDKContext>;

    public constructor(props: IProps, context: React.ContextType<typeof SDKContext>) {
        super(props, context);
        const call = this.getCall();
        this.state = {
            call,
            sidebarShown: !!call && context.legacyCallHandler.isCallSidebarShown(call.callId),
        };
    }

    public componentDidMount(): void {
        this.context.legacyCallHandler.addListener(LegacyCallHandlerEvent.CallState, this.updateCall);
        this.context.legacyCallHandler.addListener(LegacyCallHandlerEvent.CallChangeRoom, this.updateCall);
        this.context.legacyCallHandler.addListener(LegacyCallHandlerEvent.ShownSidebarsChanged, this.updateCall);
    }

    public componentWillUnmount(): void {
        this.context.legacyCallHandler.removeListener(LegacyCallHandlerEvent.CallState, this.updateCall);
        this.context.legacyCallHandler.removeListener(LegacyCallHandlerEvent.CallChangeRoom, this.updateCall);
        this.context.legacyCallHandler.removeListener(LegacyCallHandlerEvent.ShownSidebarsChanged, this.updateCall);
    }

    private updateCall = (): void => {
        const newCall = this.getCall();
        if (newCall !== this.state.call) {
            this.setState({ call: newCall });
        }
        const newSidebarShown = !!newCall && this.context.legacyCallHandler.isCallSidebarShown(newCall.callId);
        if (newSidebarShown !== this.state.sidebarShown) {
            this.setState({ sidebarShown: newSidebarShown });
        }
    };

    private getCall(): MatrixCall | null {
        const call = this.context.legacyCallHandler.getCallForRoom(this.props.roomId);

        if (call && [CallState.Ended, CallState.Ringing].includes(call.state)) return null;
        return call;
    }

    private onResizeStart = (): void => {
        this.context.resizeNotifier.startResizing();
    };

    private onResize = (): void => {
        this.context.resizeNotifier.notifyTimelineHeightChanged();
    };

    private onResizeStop = (): void => {
        this.context.resizeNotifier.stopResizing();
    };

    private setSidebarShown = (sidebarShown: boolean): void => {
        if (!this.state.call) return;
        this.context.legacyCallHandler.setCallSidebarShown(this.state.call.callId, sidebarShown);
    };

    public render(): React.ReactNode {
        if (!this.state.call) return null;

        return (
            <div className="mx_LegacyCallViewForRoom">
                <Resizable
                    minHeight={380}
                    maxHeight="80vh"
                    enable={{
                        top: false,
                        right: false,
                        bottom: true,
                        left: false,
                        topRight: false,
                        bottomRight: false,
                        bottomLeft: false,
                        topLeft: false,
                    }}
                    onResizeStart={this.onResizeStart}
                    onResize={this.onResize}
                    onResizeStop={this.onResizeStop}
                    className="mx_LegacyCallViewForRoom_ResizeWrapper"
                    handleClasses={{ bottom: "mx_LegacyCallViewForRoom_ResizeHandle" }}
                >
                    <LegacyCallView
                        call={this.state.call}
                        pipMode={false}
                        showApps={this.props.showApps}
                        sidebarShown={this.state.sidebarShown}
                        setSidebarShown={this.setSidebarShown}
                    />
                </Resizable>
            </div>
        );
    }
}
