import map from 'lodash/map';
import React from 'react';
import CaseUtils from '../../../utils/caseUtils';
import ProgressBar from '../ProgressBar';
import { IFileLocal, IUploadMetadata, IAbleToUpload } from './reducer/AttachemntReducer';

interface IProps {
    selectedLocalFiles: IFileLocal[];
    onFileEdit: (editedLocalFile: IFileLocal, indexToEdit: number) => void;
    onFileRemove: (indexToRemove: number) => void;
    onRetry?: (indexToRetry: number) => void;
}

export default function FileLister(props: IProps) {
    const onDescriptionChange = (localFile: IFileLocal, indexToEdit: number) => (event: React.ChangeEvent<HTMLInputElement>) => {
        const editedLocalFile = { ...localFile };
        editedLocalFile.description = event.target.value;
        props.onFileEdit && props.onFileEdit(editedLocalFile, indexToEdit);
    };
    const onRetry = (index: number) => () => {
        props.onRetry && props.onRetry(index);
    };
    const onRemoveClick = (localFile: IFileLocal, index: number) => () => {
        if (localFile.uploadProgress.inProgress) {
            localFile.uploadProgress.onAbort && localFile.uploadProgress.onAbort(index);
        } else {
            props.onFileRemove && props.onFileRemove(index);
        }
    };
    const getProgressBarClassName = (uploadProgress: IUploadMetadata): string => {
        if (uploadProgress.completed) { return 'progress-bar-success'; }
        if (uploadProgress.uploadError) { return 'progress-bar-danger'; }
        if (uploadProgress.aborted) { return 'progress-bar-warning'; }
        if (uploadProgress.inProgress) { return 'progress-bar-info progress-bar-striped active'; }
        return 'progress-bar-info';
    };
    const getProgressBarLabel = (uploadProgress: IUploadMetadata): string => {
        if (uploadProgress.verifying) { return 'Upload verifying'; }
        if (uploadProgress.completed) { return 'Upload completed'; }
        if (uploadProgress.aborted) { return 'Upload aborted'; }
        if (uploadProgress.uploadError) { return 'Error'; }
        return `${uploadProgress.percentUploaded}% completed`;
    };
    const getRemoveButtonText = (uploadProgress: IUploadMetadata): string => {
        return `${uploadProgress.inProgress ? 'Abort Upload' : 'Remove file'}`;
    };
    const canShowProgressBar = (uploadProgress: IUploadMetadata): boolean => {
        return (uploadProgress.inProgress || uploadProgress.completed || uploadProgress.aborted || uploadProgress.uploadError);
    };
    const shouldDisableDescription = (uploadProgress: IUploadMetadata): boolean => {
        return uploadProgress.inProgress || uploadProgress.completed;
    };
    const shouldHideDescription = (uploadProgress: IUploadMetadata, canUpload: boolean, descLength: number): boolean => {
        return !canUpload || (canUpload && uploadProgress.percentUploaded > 0 && descLength === 0);
    };
    const isUploadOnTrack = (uploadProgress: IUploadMetadata, uploadability: IAbleToUpload): boolean => {
        return !uploadProgress.uploadError && !uploadProgress.aborted && uploadability.ableToUpload;
    };

    return (
        <table className="file-table">
            <caption className="sr-only">Selected file(s)</caption>
            <thead>
                <tr>
                    <th id="th-name" scope="col" className="sr-only">Name</th>
                    <th id="th-description" scope="col" className="sr-only">Description</th>
                    {/* <th id="th-uploadable" scope="col" className="sr-only">Able to Upload</th> */}
                </tr>
            </thead>
            <tbody>
                {map(props.selectedLocalFiles, (localFile, index) => (
                    <tr key={`${index}-file-lister`}>
                        <th id={`th-file${index}`} headers="th-name">
                            <div className={`${localFile.uploadability.ableToUpload ? 'file-name' : 'file-name text-error'}`}>
                                <i className={`${isUploadOnTrack(localFile.uploadProgress, localFile.uploadability) ? 'icon-ok text-green' : 'icon-blocked'}`}
                                    title={localFile.uploadability.ableToUploadMessage}
                                    aria-label={localFile.uploadability.ableToUploadMessage} />
                                    {`${localFile.name} (${CaseUtils.humanizeSize(localFile.size)})`}
                                    {!localFile.uploadability.ableToUpload && (<span className="file-error">can't be selected.</span>)}
                                    {!shouldDisableDescription(localFile.uploadProgress) && localFile.description.length > 1 &&
                                        <span className="character-counter text-muted" style={{marginLeft: '8px'}}>{255 - localFile.description.length}</span>
                                    }
                                    {!localFile.uploadProgress.verifying && !localFile.uploadProgress.completed && (
                                <button
                                    aria-label={getRemoveButtonText(localFile.uploadProgress)}
                                    title={getRemoveButtonText(localFile.uploadProgress)}
                                    className="btn btn-link btn-app btn-sm remove-file"
                                    onClick={onRemoveClick(localFile, index)}
                                    hidden={!localFile.uploadability.ableToUpload}>Delete
                                </button>
                            )}
                            </div>
                            {(localFile.uploadProgress.uploadError || localFile.uploadProgress.aborted) && (
                                <button
                                    aria-label="Failed to upload, Retry"
                                    title="Failed to upload, Retry"
                                    className="btn btn-link btn-xs"
                                    onClick={onRetry(index)}>
                                    <i className="nimbus-icon-backup" />
                                </button>
                            )}
                        </th>
                        <td headers={`th-file${index} th-description`}>
                            <input
                                className="file-description form-control"
                                type="text"
                                value={localFile.description}
                                onChange={onDescriptionChange(localFile, index)}
                                maxLength={255}
                                placeholder={`${shouldDisableDescription(localFile.uploadProgress) ? '' : 'Enter a description for your file'}`}
                                disabled={shouldDisableDescription(localFile.uploadProgress)}
                                hidden={shouldHideDescription(localFile.uploadProgress, localFile.uploadability.ableToUpload, localFile.description.length)} />
                            <ProgressBar valueMin={0}
                                valueMax={100}
                                valueNow={localFile.uploadProgress.percentUploaded}
                                show={canShowProgressBar(localFile.uploadProgress)}
                                progressBarClassName={getProgressBarClassName(localFile.uploadProgress)}
                                progressBarLabel={getProgressBarLabel(localFile.uploadProgress)} />
                        </td>
                        {/* <td headers={`th-file${index} th-uploadable`}>
                            <i className={`${localFile.uploadability.ableToUpload ? 'rh-icon-check-yes' : 'rh-icon-ex-no'}`}
                                title={localFile.uploadability.ableToUploadMessage}
                                aria-label={localFile.uploadability.ableToUploadMessage} />
                        </td> */}
                    </tr>
                ))}
            </tbody>
        </table>
    );
}
