import React from 'react';
import superagent from 'superagent';
import { fromUnixTime, formatDistanceToNow } from "date-fns";
import { formatInTimeZone } from 'date-fns-tz'

import constants, { DEFAULT_TIMEZONE } from '../CloudApi/Constants.js';
import ApiButtonModal from '../CloudApi/ApiButtonModal.jsx';
import { splitUpperCamelCase } from '../CloudApi/ApiUtils.js';
import BigApiErrorMessage from '../CloudApi/BigApiErrorMessage.jsx';
import ScreenComponent from './ScreenComponent.jsx';

import {
    Radio,
    Segment,
    Header,
    Image,
    Modal,
    Icon,
    Button,
    Table,
    Form,
    Label, Dropdown
} from 'semantic-ui-react'

export function renderCompactTitle(storedRoom, liveRoom, extra) {
    const name = storedRoom.name;
    const participantsCount = (liveRoom.participantsIndex ? Object.keys(liveRoom.participantsIndex).length : 0);
    const size = storedRoom.maxUsersPerInstance;
    const instancePolicy = storedRoom.instancePolicy;
    const isNSFWRoom = storedRoom.category === "NSFW";

    const roomTitle = (
        <span>
            {isNSFWRoom && <Label color="red"><Icon name='ban' />&nbsp;NSFW</Label>}
            <strong><a style={{ textDecoration: "underline" }} href={`/room/${storedRoom.roomId}`}>{name}</a>&nbsp;</strong>
            <Label basic={participantsCount !== size} color={participantsCount === size ? "grey" : null}><Icon name='users' />&nbsp;{participantsCount}/{size}</Label>
            {(storedRoom.visibility === 'private') && <Label color="black">Private</Label>}
            {extra && (instancePolicy && instancePolicy.startsWith("Multiple") ? <Label color="green">{instancePolicy}</Label> : <Label color="orange">{instancePolicy}</Label>)}
            {extra && ((participantsCount > 0) ? <Label color="red"><Icon name="sun" loading />Live</Label> : <Label color="grey">Offline</Label>)}
        </span>
    );

    return roomTitle;
}

class RoomComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            currentMediaProduct: null,
        };
    }

    async componentDidMount() {
        console.log(this.props.room);
        if (this.props.room.content) {
            const contentJSON = JSON.parse(decodeURIComponent(this.props.room.content));
            let bigMediaId = contentJSON.bigMediaId;
            const res = await superagent.post("/api/admin/media/query").send({ bigMediaId });
            this.setState({ currentMediaProduct: res.body[0] })
        }
    }

    showSetRoomPrivateModal(roomIndex, e) {
        this.setState({ isShowingSetRoomPrivateModal: true });
    }

    async onSetRoomPrivate() {
        this.setState({ isShowingSetRoomPrivateModal: false });

        try {
            console.log(`/cloud/admin/room/${this.props.liveRoom.roomId}`);
            const res = await superagent.put(`/cloud/admin/room/${this.props.liveRoom.roomId}`).accept('json').send({ visibility: 'Private' });
            console.log("Room is now private!");
        } catch (e) {
            console.error(e);
        }
    }

    async onScreenUpdated(screenIndex, e) {
        this.props.onReloadRoom();
    }

    closeSetRoomPrivateModal(e) {
        this.setState({ isShowingSetRoomPrivateModal: false });
    }


    showDeleteRoomModal(roomIndex, e) {
        this.setState({ isShowingDeleteRoomModal: true });
    }

    async onDeleteRoom(e) {
        this.setState({ isShowingDeleteRoomModal: false });

        try {
            const res = await superagent.delete(`/cloud/admin/room/${this.props.room.roomId}`).accept('json');
        } catch (e) {
            console.error(e);
        }
    }

    closeDeleteRoomModal(e) {
        this.setState({ isShowingDeleteRoomModal: false });
    }

    sendMessage(selectedBigscreenUser, e) {
        e.preventDefault();
        this.setState({ selectedBigscreenUser, showMessageDialog: true });
    }

    closeMessageModal(e) {
        this.setState({ showMessageDialog: false });
    }

    onUpdateMessageText(e, { name, value }) {
        const state = this.state;
        state[name] = value;
        this.setState(state);
    }

    async onConfirmSendMessage(e) {
        e.preventDefault();
        try {
            console.log(this.state.selectedBigscreenUser);
            const payload = { message: this.state.message };
            const result = await superagent.post(`/cloud/admin/account/${this.state.selectedBigscreenUser.bigscreenAccountId}/message`).send(payload).accept('json');
        } catch (e) {
            console.log(e);
        }
        this.setState({ showMessageDialog: false, message: undefined, selectedBigscreenUser: undefined });
    }

    async onUpdateAdminSettings(e, { name, value }) {
        console.log(name, value);
        return this.props.onUpdateRoom(this.props.roomIndex, e, { adminSettings: name, value });
    }

    

    renderTitle() {
        let ownerLink = null;
        if (this.props.ownerBigscreenAccount) {
            ownerLink = (
                <span>by <a style={{ textDecoration: "underline" }} href={`/account/${this.props.ownerBigscreenAccount.id}`}>{this.props.ownerBigscreenAccount.username}</a></span>
            );
        }

        const title = (
            <Header as="h2">
                🏠 Room: <span style={{ textDecoration: "underline" }}>{this.props.room.name}</span> {ownerLink}
            </Header>
        );

        const createdAt = formatInTimeZone(new Date(this.props.room.createdAt), DEFAULT_TIMEZONE, 'PPPp z');
        const fromNow = formatDistanceToNow(new Date(this.props.room.createdAt), { addSuffix: true });

        return (
            <div style={{ display: "flex" }}>
                <div style={{ flex: 3 }}>
                    {title}
                    <p>{(this.props.liveRoom) ? <Label color="red"><Icon name="sun" loading />Live</Label> : <Label color="grey">Offline</Label>} Created: {createdAt} ({fromNow})</p>
                </div>
                <div style={{ flex: 1, textAlign: "right", verticalAlign: "center" }}>
                    <Dropdown direction='left' icon={null} closeOnBlur openOnFocus={false} trigger={
                        <Button color="blue">🏠 Room Actions...</Button>
                    }>
                        <Dropdown.Menu>
                            <Dropdown.Divider />
                            <Dropdown.Header as="h2" content="📸 Room Data" />

                            <ApiButtonModal as="dropdown" color="black" size="small" icon="key" text="Set room to private" cancel modalIcon="key" modalButtonText="Yes, make room private" onConfirm={this.onSetRoomPrivate.bind(this)}>
                                <div>
                                    <p>Are you sure you want to set the room {this.props.room.name} ({this.props.room.roomId}) to private?</p>
                                </div>
                            </ApiButtonModal>

                            <Dropdown.Header as="h2" content="📦 Admin" />
                            <ApiButtonModal as="dropdown" color="red" size="small" icon="archive" text="Close Live Room" cancel modalIcon="trash" modalButtonText="Yes, Delete this room" onConfirm={this.onDeleteRoom.bind(this)}>
                                <div>
                                    <p>Are you sure you want to delete the room {this.props.room.name} ({this.props.room.roomId})?</p>
                                    <p><b>This will kick everyone from the room!!!</b></p>
                                </div>
                            </ApiButtonModal>
                        </Dropdown.Menu>
                    </Dropdown>
                </div>
            </div>
        );
    }

    renderRoomInstances() {
        // HACK HACK HACK
        //
        // Server returning null room instance in the array.
        return this.props.roomInstances && this.props.roomInstances.map((roomInstance) => {
            return (roomInstance && roomInstance.participants.length > 0) ?
                <Table compact celled padded>
                    <Table.Header>
                        <Table.Row>
                            <Table.HeaderCell width={3}>Name</Table.HeaderCell>
                            <Table.HeaderCell width={2}>Room Info</Table.HeaderCell>
                            <Table.HeaderCell width={2}>Device</Table.HeaderCell>
                            <Table.HeaderCell width={2}>GPU/CPU</Table.HeaderCell>
                            <Table.HeaderCell width={2}>OS</Table.HeaderCell>
                            <Table.HeaderCell width={2}>App Version</Table.HeaderCell>
                            <Table.HeaderCell>Tools</Table.HeaderCell>
                        </Table.Row>
                    </Table.Header>
                    <Table.Body>
                        {roomInstance.participants.map((participant, participantIndex) => {
                            const isAdmin = _.indexOf(this.props.room.adminUserIds, participant.bigscreenUserId) !== -1;
                            const isOwner = this.props.room.owner && participant.userSessionId === this.props.room.owner.userSessionId;

                            let avatarUrl = "/images/avatar_b.jpg";
                            const bigscreenUser = participant.bigscreenUser;
                            const accountProfile = participant.bigscreenUser.socialProfile;
                            if (accountProfile && accountProfile.oculusProfile && accountProfile.oculusProfile.oculusImageURL) {
                                avatarUrl = accountProfile.oculusProfile.oculusImageURL;
                            } else if (accountProfile && accountProfile.steamProfile && accountProfile.steamProfile.avatarfull) {
                                avatarUrl = accountProfile.steamProfile.avatarfull;
                            }

                            let bigscreenUserHeader = null;
                            if (bigscreenUser && accountProfile) {
                                bigscreenUserHeader = (bigscreenUser.bigscreenAccountId) ? (
                                    <Header as='h4' image>
                                        <Image src={avatarUrl} rounded size='small' />
                                        <Header.Content>
                                            <a href={`/account/${bigscreenUser.bigscreenAccountId}`}>{accountProfile.username}</a>
                                        </Header.Content>
                                    </Header>
                                ) : (
                                    <div>
                                        <a href={`/account/${bigscreenUser.bigscreenAccountId}`}>{accountProfile.username}</a>
                                        <Label color="yellow">Ghost user! 👻</Label>
                                    </div>
                                );
                            } else {
                                bigscreenUserHeader = (
                                    <div>
                                        Missing User Data!!!!
                                        <Label color="yellow">Ghost user! 👻</Label>
                                    </div>
                                );
                            }

                            return (
                                <Table.Row>
                                    <Table.Cell width={3}>
                                        {bigscreenUserHeader}
                                    </Table.Cell>
                                    <Table.Cell width={2}>
                                        {isOwner ? <Label color="violet">Owner</Label> : ""}
                                        {isAdmin ? <Label color="blue">Admin</Label> : ""}
                                        <Label>Seat {participant.seatIndex}</Label><Label>{participant.legacyUserId}</Label>
                                    </Table.Cell>
                                    <Table.Cell width={2}>
                                        <Label color="blue" basic>{bigscreenUser.systemInfo && (bigscreenUser.systemInfo.deviceName || bigscreenUser.systemInfo.HMD)}</Label>
                                        <Label>{bigscreenUser.websocketServerId}</Label>
                                    </Table.Cell>
                                    <Table.Cell width={2}>
                                        <Header as='h4'>
                                            <Header.Content>
                                                {bigscreenUser.systemInfo && bigscreenUser.systemInfo.GPU}
                                                <Header.Subheader>{bigscreenUser.systemInfo && bigscreenUser.systemInfo.CPU}</Header.Subheader>
                                            </Header.Content>
                                        </Header>
                                    </Table.Cell>
                                    <Table.Cell width={2}>
                                        {bigscreenUser.systemInfo && bigscreenUser.systemInfo.operatingSystem}
                                    </Table.Cell>
                                    <Table.Cell width={2}>
                                        {bigscreenUser.systemInfo && bigscreenUser.systemInfo.version}
                                    </Table.Cell>
                                    <Table.Cell>
                                        {this.props.onEjectParticipant && <Button color="orange" onClick={this.props.onEjectParticipant.bind(this, participant, participantIndex, this.props.room, this.props.roomIndex)}><Icon name='cancel' size="small" />Eject</Button>}
                                        {this.props.onKickParticipant && <Button color="orange" onClick={this.props.onKickParticipant.bind(this, participant, participantIndex, this.props.room, this.props.roomIndex)}><Icon name='user cancel' size="small" />Kick</Button>}
                                        <Button color="green" onClick={this.sendMessage.bind(this, bigscreenUser)}><Icon name='send' />Message</Button>
                                    </Table.Cell>
                                </Table.Row>
                            )
                        })}
                    </Table.Body>
                </Table> : null;
        });
    }

    render() {
        if (!this.props.room) {
            return (
                <div />
            )
        }

        if (this.props.compact) {
            const storedRoom = this.props.room.storedRoomSnapshot;
            const liveRoom = this.props.room;

            const anchor = `${storedRoom.roomType}${this.props.roomIndex}`;
            const participantsCount = (this.props.room.participantsIndex ? Object.keys(this.props.room.participantsIndex).length : 0);

            let environmentName = storedRoom.environmentId;
            if (this.props.environmentOptions) {
                const environmentOption = this.props.environmentOptions.find((environmentOption) => environmentOption.key === storedRoom.environmentId);
                if (environmentOption) {
                    environmentName = environmentOption.text;
                }
            }

            const environmentLink = (
                <a style={{ textDecoration: "underline" }} href={`/rooms/environments/${storedRoom.environmentId}`}>{environmentName}</a>
            );

            return (
                <>
                    {renderCompactTitle(this.props.room.storedRoomSnapshot, this.props.room, this.props.roomIndex)}
                    <Table compact celled definition>
                        <Table.Body>
                            <Table.Row>
                                <Table.HeaderCell width={3}>Room Type</Table.HeaderCell>
                                <Table.Cell>{storedRoom.roomType}</Table.Cell>
                            </Table.Row>

                            <Table.Row>
                                <Table.HeaderCell width={3}>Environment</Table.HeaderCell>
                                <Table.Cell>{environmentLink}</Table.Cell>
                            </Table.Row>

                            <Table.Row>
                                <Table.HeaderCell width={3}>Name</Table.HeaderCell>
                                <Table.Cell>{storedRoom.name}</Table.Cell>
                            </Table.Row>

                            <Table.Row>
                                <Table.HeaderCell width={3}>Category</Table.HeaderCell>
                                <Table.Cell>{storedRoom.category}</Table.Cell>
                            </Table.Row>

                            <Table.Row>
                                <Table.HeaderCell width={3}>Max Users Per Instance</Table.HeaderCell>
                                <Table.Cell>{storedRoom.maxUsersPerInstance}</Table.Cell>
                            </Table.Row>

                            <Table.Row>
                                <Table.HeaderCell width={3}>Room Id</Table.HeaderCell>
                                <Table.Cell>{storedRoom.roomId}</Table.Cell>
                            </Table.Row>

                            <Table.Row>
                                <Table.HeaderCell width={3}>App Version</Table.HeaderCell>
                                <Table.Cell>{liveRoom.contextAppVersion}</Table.Cell>
                            </Table.Row>

                            <Table.Row>
                                <Table.HeaderCell width={3}>Version</Table.HeaderCell>
                                <Table.Cell>{storedRoom.version}</Table.Cell>
                            </Table.Row>

                            <Table.Row>
                                <Table.HeaderCell width={3}>Participants</Table.HeaderCell>
                                <Table.Cell>{participantsCount}</Table.Cell>
                            </Table.Row>
                        </Table.Body>
                    </Table>
                </>
            );
        } else {
            const anchor = `${this.props.liveRoom && this.props.liveRoom.roomType}`;
            const participantsCount = ((this.props.liveRoom && this.props.liveRoom.participantsIndex) ? Object.keys(this.props.liveRoom.participantsIndex).length : 0);

            return (
                <>
                    {this.renderTitle()}

                    <Table compact celled definition>
                        <Table.Body>
                            {(this.props.room.visibility === 'Public') &&
                                <Table.Row>
                                    <Table.HeaderCell width={3}>Invite Code</Table.HeaderCell>
                                    <Table.Cell><strong>{this.props.room.inviteCode}</strong>&nbsp;<Button size="tiny" onClick={() => { navigator.clipboard.writeText(this.props.room.inviteCode) }}>Copy</Button></Table.Cell>
                                </Table.Row>
                            }

                            {(this.props.room.visibility !== 'Private') &&
                                <Table.Row>
                                    <Table.HeaderCell width={3}>Room Id</Table.HeaderCell>
                                    <Table.Cell>{this.props.room.roomId}<a name={anchor} /></Table.Cell>
                                </Table.Row>
                            }

                            <Table.Row>
                                <Table.HeaderCell width={3}>Visibility</Table.HeaderCell>
                                <Table.Cell>{this.props.room.visibility}</Table.Cell>
                            </Table.Row>

                            <Table.Row>
                                <Table.HeaderCell width={3}>Room Type (Legacy)</Table.HeaderCell>
                                <Table.Cell>{this.props.room.roomType}</Table.Cell>
                            </Table.Row>

                            {(this.props.onUpdateRoom && this.props.environmentOptions) ? (
                                <Table.Row>
                                    <Table.HeaderCell width={3}>Environment</Table.HeaderCell>
                                    <Table.Cell>
                                        <Form.Select size="small" name="environmentId" value={this.props.room.environmentId} options={this.props.environmentOptions} onChange={this.props.onUpdateRoom.bind(this, this.props.roomIndex)} />
                                    </Table.Cell>
                                </Table.Row>
                            ) : (
                                <Table.Row>
                                    <Table.HeaderCell width={3}>Environment</Table.HeaderCell>
                                    <Table.Cell>{this.props.room.environmentId}</Table.Cell>
                                </Table.Row>
                            )}

                            {(this.props.onUpdateRoom) ? (
                                <Table.Row>
                                    <Table.HeaderCell width={3}>Name</Table.HeaderCell>
                                    <Table.Cell><Form.Input size="small" name="name" value={this.props.room.name} onChange={this.props.onUpdateRoom.bind(this, this.props.roomIndex)} /></Table.Cell>
                                </Table.Row>
                            ) : (
                                <Table.Row>
                                    <Table.HeaderCell width={3}>Name</Table.HeaderCell>
                                    <Table.Cell>{this.props.room.name}</Table.Cell>
                                </Table.Row>
                            )}

                            {(this.props.onUpdateRoom) &&
                                <Table.Row>
                                    <Table.HeaderCell width={3}>Description</Table.HeaderCell>
                                    <Table.Cell><Form.Input fluid size="small" name="description" value={this.props.room.description} onChange={this.props.onUpdateRoom.bind(this, this.props.roomIndex)} /></Table.Cell>
                                </Table.Row>
                            }

                            {(this.props.onUpdateRoom) &&
                                <Table.Row>
                                    <Table.HeaderCell width={3}>Category</Table.HeaderCell>
                                    <Table.Cell><Form.Select size="small" name="category" value={this.props.room.category} options={constants.RoomCategories} onChange={this.props.onUpdateRoom.bind(this, this.props.roomIndex)} /></Table.Cell>
                                </Table.Row>
                            }

                            {(this.props.onUpdateRoom) ? (
                                <Table.Row>
                                    <Table.HeaderCell width={3}>Max Users Per Instance</Table.HeaderCell>
                                    <Table.Cell><Form.Select size="small" name="maxUsersPerInstance" value={this.props.room.maxUsersPerInstance} options={constants.RoomSizes} onChange={this.props.onUpdateRoom.bind(this, this.props.roomIndex)} /></Table.Cell>
                                </Table.Row>
                            ) : (
                                <Table.Row>
                                    <Table.HeaderCell width={3}>Max Users Per Instance</Table.HeaderCell>
                                    <Table.Cell>{this.props.room.maxUsersPerInstance}</Table.Cell>
                                </Table.Row>
                            )}

                            {this.props.room && this.props.cloudSchemas &&
                                <Table.Row>
                                    <Table.HeaderCell width={3}>Admin Settings</Table.HeaderCell>
                                    <Table.Cell>
                                        <Table>
                                            <Table.Body>
                                                {Object.keys(this.props.cloudSchemas.AdminSettingsOptions).map((key) => {
                                                    let adminSettingsOption = this.props.cloudSchemas.AdminSettingsOptions[key];
                                                    let options = this.props.cloudSchemas[adminSettingsOption.optionsKey];
                                                    let value = this.props.room[key];
                                                    return (
                                                        <Table.Row>
                                                            <Table.HeaderCell collapsing>{adminSettingsOption.title}</Table.HeaderCell>
                                                            <Table.Cell>
                                                                <Form.Select size="small" name={key} value={value} options={options} onChange={this.props.onUpdateRoom.bind(this, this.props.roomIndex)} />
                                                            </Table.Cell>
                                                        </Table.Row>
                                                    );
                                                })}
                                            </Table.Body>
                                        </Table>
                                    </Table.Cell>
                                </Table.Row>
                            }

                            {this.props.liveRoom && this.props.liveRoom.mediaServer &&
                                <Table.Row>
                                    <Table.HeaderCell width={3}>Media Server Info</Table.HeaderCell>
                                    <Table.Cell>
                                        <Label color="blue">{this.props.liveRoom.mediaServer.id}</Label>
                                        <Label>{this.props.liveRoom.mediaServer.ipAddress}</Label>
                                        <Label>Load: {this.props.liveRoom.mediaServer.load}%</Label>
                                    </Table.Cell>
                                </Table.Row>}

                            {this.props.liveRoom && this.props.liveRoom.screens && <Table.Row>
                                <Table.HeaderCell width={3}>Screens list ({this.props.liveRoom.screens.length})</Table.HeaderCell>
                                <Table.Cell>
                                    {this.props.liveRoom.screens.map((screen, screenIndex) => {
                                        return (
                                            <div>
                                                <ScreenComponent onScreenUpdated={this.onScreenUpdated.bind(this)} screen={screen} screenIndex={screenIndex} room={this.props.room} />
                                            </div>
                                        );
                                    })}
                                </Table.Cell>
                            </Table.Row>}

                            <Table.Row>
                                <Table.HeaderCell width={3}>Participants</Table.HeaderCell>
                                <Table.Cell>{participantsCount}</Table.Cell>
                            </Table.Row>

                            <Table.Row>
                                <Table.HeaderCell width={3}>Version</Table.HeaderCell>
                                <Table.Cell>{this.props.room.version}</Table.Cell>
                            </Table.Row>

                        </Table.Body>
                    </Table>

                    {this.renderRoomInstances()}

                    <Modal dimmer="inverted" closeOnEscape={true} closeOnDimmerClick={true} closeIcon
                        onClose={this.closeMessageModal.bind(this)}
                        open={this.state.showMessageDialog}>
                        <Header icon='user' content='Send a message' />
                        <Modal.Content>{
                            (this.state.account) &&
                            <p>Enter a message to send to this user {this.state.selectedUser.username}:</p>
                        }
                            <Form.Input fluid size="medium" name="message" value={this.state.message} onChange={this.onUpdateMessageText.bind(this)} />
                        </Modal.Content>
                        <Modal.Actions>
                            <Button color='green' disabled={!this.state.message || this.state.message.length === 0} onClick={this.onConfirmSendMessage.bind(this)}>
                                <Icon name='send' />Yes, send a message!
                            </Button>
                        </Modal.Actions>
                    </Modal>
                </>
            );
        }
    }
}

export default RoomComponent;
