import * as React from "react";
import { Alert, ListGroup } from "react-bootstrap";

import {
    ErrorDisplay, FormError, RemoveButton, SingleInputField, StatelessInputGroupForm, StatelessTextAreaForm,
    UserDisplay, userLoggedOnWarning
} from "./common";
import { AllowedBackendsForm } from "./meetingType";
import { MeetingBackend, User } from "../models";
import { MeetingTypesValidationResult, uniqnameSchema, ValidationResult } from "../validation";


const requiredSymbol = <span className='text-danger'>*</span>;

interface QueueEditorProps {
    disabled: boolean;
}

interface GeneralEditorProps extends QueueEditorProps {
    name: string;
    nameValidationResult?: ValidationResult;
    onChangeName: (value: string) => void;
    description: string;
    descriptValidationResult?: ValidationResult;
    onChangeDescription: (value: string) => void;
    backends: MeetingBackend[];
    allowedMeetingTypes: Set<string>;
    allowedValidationResult?: MeetingTypesValidationResult;
    onChangeAllowed: (allowed: Set<string>) => void;
    showCorrectGeneralMessage: boolean;
    showSuccessMessage?: boolean;
    inpersonLocation: string;
    locationValidationResult?: ValidationResult;
    onChangeLocation: (value: string) => void;
}

export function GeneralEditor(props: GeneralEditorProps) {
    const correctMessage = 'Please correct the invalid entries below in order to proceed.';
    const successMessage = 'Your changes were saved successfully!';

    const allowedFeedbackMessages = props.allowedValidationResult?.isInvalid
        ? props.allowedValidationResult.messages.map((m, key) => <Alert key={key} variant='danger'>{m}</Alert>)
        : undefined;

    return (
        <div>
            <h2>General</h2>
            {props.showSuccessMessage ? <Alert variant='success'>{successMessage}</Alert> : undefined}
            {props.showCorrectGeneralMessage ? <Alert variant='danger'>{correctMessage}</Alert> : undefined}
            <p>{requiredSymbol} indicates a required field.</p>
            <h3>Name {requiredSymbol}</h3>
            <StatelessInputGroupForm
                id='name'
                value={props.name}
                formLabel='Queue Name'
                placeholder='Queue name...'
                disabled={props.disabled}
                validationResult={props.nameValidationResult}
                onChangeValue={props.onChangeName}
            />
            <h3>Description</h3>
            <StatelessTextAreaForm
                id='description'
                value={props.description}
                formLabel='Queue Description'
                placeholder='Queue description...'
                disabled={props.disabled}
                validationResult={props.descriptValidationResult}
                onChangeValue={props.onChangeDescription}
            />
            <h3>Meeting Types {requiredSymbol}</h3>
            <p>Allow the following meeting types (select at least one):</p>
            <div>{allowedFeedbackMessages}</div>
            <AllowedBackendsForm
                allowed={props.allowedMeetingTypes}
                backends={props.backends}
                onChange={props.onChangeAllowed}
                disabled={props.disabled}
            />
            {props.allowedMeetingTypes.has('inperson') && 
                <>
                    <h3>In-Person Meeting Location</h3>
                    <p>
                        Attendees who select to meet in-person will be instructed to meet at this location. 
                        Enter all information an attendee would need to know, such as a street address, building name, and/or room number.
                    </p>
                    <StatelessInputGroupForm 
                        id='inpersonLocation'
                        value={props.inpersonLocation}
                        formLabel='In-Person Meeting Location'
                        placeholder='In-person meeting location...'
                        disabled={props.disabled}
                        validationResult={props.locationValidationResult}
                        onChangeValue={props.onChangeLocation}
                    />
                </>
            }
        </div>
    );
}

interface ManageHostsEditorProps extends QueueEditorProps {
    currentUser?: User;
    hosts: User[];
    addHostTextPrefix?: string;
    onAddHost: (username: string) => void;
    onRemoveHost: (user: User) => void;
    checkHostError?: FormError;
}

export function ManageHostsEditor(props: ManageHostsEditorProps) {
    const hostUsernames = props.hosts.map(h => h.username);

    const hostsSoFar = props.hosts.map((host, key) => (
        <ListGroup.Item key={key}>
            <UserDisplay user={host} />
            {
                (host.id !== props.currentUser?.id)
                    && (
                        <div className='float-right'>
                            <RemoveButton
                                onRemove={() => props.onRemoveHost(host)}
                                size='sm'
                                disabled={props.disabled}
                                screenReaderLabel='Remove Host'
                            />
                        </div>
                    )
            }
        </ListGroup.Item>
    ));

    const handleSubmit = (username: string) => {
        if (!hostUsernames.includes(username)) props.onAddHost(username);
    }

    return (
        <div>
            <h2>Manage Hosts</h2>
            <h3>Add Hosts</h3>
            <p>{props.addHostTextPrefix} Add additional hosts to the queue here.</p>
            {userLoggedOnWarning}
            {props.checkHostError ? <ErrorDisplay formErrors={[props.checkHostError]} /> : undefined}
            <SingleInputField
                id="add_host"
                fieldComponent={StatelessInputGroupForm}
                formLabel='Add Host'
                placeholder="Uniqname..."
                buttonOptions={{ onSubmit: handleSubmit, buttonType: 'success' }}
                disabled={props.disabled}
                fieldSchema={uniqnameSchema}
                showRemaining={false}
            >
                + Add Host
            </SingleInputField>
            <h3>Current Hosts</h3>
            <p>
                To remove a host, select the trash icon to the right of the user's name. <strong>You cannot remove yourself as a host.</strong>
            </p>
            <ListGroup>{hostsSoFar}</ListGroup>
        </div>
    );
}

type CombinedEditorProps = GeneralEditorProps & ManageHostsEditorProps;

export interface MultiTabEditorProps extends CombinedEditorProps {
    onTabSelect?: (eventKey: string | null, e: React.SyntheticEvent<unknown>) => void;
}