/*
 *  Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *  SPDX-License-Identifier: Apache-2.0
 */

import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import React, { useState, MouseEvent } from "react";
import { ChartType, DatasetType } from "../models";
import { useTranslation } from "react-i18next";
import Alert from "./Alert";
import BarChartWidget from "./BarChartWidget";
import Button from "./Button";
import ColumnChartWidget from "./ColumnChartWidget";
import LineChartWidget from "./LineChartWidget";
import Link from "./Link";
import PartWholeChartWidget from "./PartWholeChartWidget";
import RadioButtons from "./RadioButtons";
import Spinner from "./Spinner";
import TextField from "./TextField";
import { faTimes } from "@fortawesome/free-solid-svg-icons";
import Dropdown from "./Dropdown";
import DatasetParsingService from "../services/DatasetParsingService";
import PrimaryActionBar from "./PrimaryActionBar";
import PieChartWidget from "./PieChartWidget";
import DonutChartWidget from "./DonutChartWidget";
import { useWindowSize } from "../hooks";
import UtilsService from "../services/UtilsService";

interface Props {
    widgetId: string;
    errors: any;
    register: Function;
    json: Array<any>;
    originalJson: Array<any>;
    headers: Array<string>;
    csvJson: Array<any>;
    datasetLoading: boolean;
    datasetType: DatasetType | undefined;
    onCancel: (event: MouseEvent<HTMLButtonElement>) => void;
    backStep: (event: MouseEvent<HTMLButtonElement>) => void;
    advanceStep: (event: MouseEvent<HTMLButtonElement>) => void;
    fileLoading: boolean;
    processingWidget: boolean;
    fullPreviewButton: JSX.Element;
    previewPanelId: string;
    fullPreview: boolean;
    submitButtonLabel: string;
    sortByColumn?: string;
    sortByDesc?: boolean;
    setSortByColumn: Function;
    setSortByDesc: Function;
    title: string;
    summary: string;
    chartType: ChartType;
    showTitle: boolean;
    summaryBelow: boolean;
    significantDigitLabels: boolean;
    horizontalScroll: boolean;
    stackedChart: boolean;
    dataLabels: boolean;
    computePercentages: boolean;
    showTotal: boolean;
    columnsMetadata: Array<any>;
    configHeader: JSX.Element;
}

function VisualizeChart(props: Props) {
    const { t } = useTranslation();
    const [showAlert, setShowAlert] = useState(true);
    const [widthPercent, setWidthPercent] = useState(0);
    const windowSize = useWindowSize();
    const isMobile = windowSize.width <= 600;

    const handleSortDataChange = (event: React.FormEvent<HTMLInputElement>) => {
        const target = event.target as HTMLInputElement;
        if (target.value !== "") {
            const sortData = target.value.split("###");
            const header = sortData[0];
            const desc = sortData[1] === "desc";
            props.setSortByColumn(header);
            props.setSortByDesc(desc);
        } else {
            props.setSortByColumn(undefined);
            props.setSortByDesc(undefined);
        }
    };

    return (
        <div className="grid-row">
            <div className="tablet:grid-col-6" hidden={props.fullPreview}>
                <PrimaryActionBar>
                    {props.configHeader}
                    {props.errors.title && (
                        <Alert
                            type="error"
                            message={t("VisualizeChartComponent.ResolveErrors")}
                            slim
                        ></Alert>
                    )}

                    <fieldset className="usa-fieldset">
                        <legend className={`usa-hint ${isMobile ? "grid-col-12" : "grid-col-6"}`}>
                            {t("AddChartScreen.Configure")}
                        </legend>

                        <TextField
                            id="title"
                            name="title"
                            label={t("VisualizeChartComponent.ChartTitle")}
                            hint={t("VisualizeChartComponent.ChartTitleHint")}
                            error={
                                props.errors.title && t("VisualizeChartComponent.ChartTitleError")
                            }
                            required
                            register={props.register}
                        />

                        <div className="usa-checkbox">
                            <input
                                className="usa-checkbox__input"
                                id="display-title"
                                type="checkbox"
                                name="showTitle"
                                defaultChecked={true}
                                ref={props.register()}
                            />
                            <label className="usa-checkbox__label" htmlFor="display-title">
                                {t("AddTextScreen.ShowTitle")}
                            </label>
                        </div>

                        <RadioButtons
                            id="chartType"
                            name="chartType"
                            label={t("VisualizeChartComponent.ChartType")}
                            hint={t("VisualizeChartComponent.ChartTypeHint")}
                            register={props.register}
                            error={
                                props.errors.chartType &&
                                t("VisualizeChartComponent.ChartTypeError")
                            }
                            defaultValue={ChartType.LineChart}
                            required
                            options={[
                                {
                                    value: ChartType.LineChart,
                                    label: t("Line"),
                                },
                                {
                                    value: ChartType.BarChart,
                                    label: t("Bar"),
                                },
                                {
                                    value: ChartType.ColumnChart,
                                    label: t("Column"),
                                },
                                {
                                    value: ChartType.PartWholeChart,
                                    label: t("PartToWhole"),
                                },
                                {
                                    value: ChartType.PieChart,
                                    label: t("Pie"),
                                },
                                {
                                    value: ChartType.DonutChart,
                                    label: t("Donut"),
                                },
                            ]}
                        />
                        <div className="margin-top-3">
                            <Dropdown
                                id="sortData"
                                name="sortData"
                                label={t("SortData")}
                                options={DatasetParsingService.getDatasetSortOptions(
                                    props.originalJson,
                                    props.headers,
                                    t,
                                    props.chartType,
                                )}
                                onChange={handleSortDataChange}
                                defaultValue={UtilsService.getSortData(
                                    props.sortByColumn,
                                    props.sortByDesc,
                                )}
                                register={props.register}
                            />
                        </div>

                        <div>
                            <label className="usa-label text-bold">{t("ChartOptionsLabel")}</label>
                            <div className="usa-hint">{t("ChartOptionsDescription")}</div>
                            <div className="usa-checkbox">
                                <input
                                    className="usa-checkbox__input"
                                    id="significantDigitLabels"
                                    type="checkbox"
                                    name="significantDigitLabels"
                                    defaultChecked={false}
                                    ref={props.register()}
                                />
                                <label
                                    className="usa-checkbox__label"
                                    htmlFor="significantDigitLabels"
                                >
                                    {t("SignificantDigitLabels")}
                                </label>
                            </div>

                            <div
                                className="usa-checkbox"
                                hidden={
                                    props.chartType !== ChartType.BarChart &&
                                    props.chartType !== ChartType.ColumnChart
                                }
                            >
                                <input
                                    className="usa-checkbox__input"
                                    id="stackedChart"
                                    type="checkbox"
                                    name="stackedChart"
                                    defaultChecked={!!props.stackedChart}
                                    ref={props.register()}
                                />
                                <label className="usa-checkbox__label" htmlFor="stackedChart">
                                    {t("VisualizeChartComponent.StackedChart")}
                                </label>
                            </div>

                            <div
                                className="usa-checkbox"
                                hidden={
                                    props.chartType !== ChartType.PieChart &&
                                    props.chartType !== ChartType.DonutChart
                                }
                            >
                                <input
                                    className="usa-checkbox__input"
                                    id="dataLabels"
                                    type="checkbox"
                                    name="dataLabels"
                                    defaultChecked={false}
                                    ref={props.register()}
                                />
                                <label className="usa-checkbox__label" htmlFor="dataLabels">
                                    {t("VisualizeChartComponent.ShowDataLabels")}
                                </label>
                            </div>

                            <div
                                className="usa-checkbox"
                                hidden={
                                    props.chartType !== ChartType.PieChart &&
                                    props.chartType !== ChartType.DonutChart
                                }
                            >
                                <input
                                    className="usa-checkbox__input"
                                    id="computePercentages"
                                    type="checkbox"
                                    name="computePercentages"
                                    defaultChecked={false}
                                    ref={props.register()}
                                />
                                <label className="usa-checkbox__label" htmlFor="computePercentages">
                                    {t("VisualizeChartComponent.ComputePercentages")}
                                </label>
                            </div>

                            <div
                                className="usa-checkbox"
                                hidden={props.chartType !== ChartType.DonutChart}
                            >
                                <input
                                    className="usa-checkbox__input"
                                    id="showTotal"
                                    type="checkbox"
                                    name="showTotal"
                                    defaultChecked={true}
                                    ref={props.register()}
                                />
                                <label className="usa-checkbox__label" htmlFor="showTotal">
                                    {t("VisualizeChartComponent.ShowTotal")}
                                </label>
                            </div>

                            <div
                                className="usa-checkbox"
                                hidden={
                                    (props.chartType !== ChartType.LineChart &&
                                        props.chartType !== ChartType.ColumnChart) ||
                                    widthPercent <= 100
                                }
                            >
                                <input
                                    className="usa-checkbox__input"
                                    id="horizontalScroll"
                                    type="checkbox"
                                    name="horizontalScroll"
                                    defaultChecked={!!props.horizontalScroll}
                                    ref={props.register()}
                                />
                                <label className="usa-checkbox__label" htmlFor="horizontalScroll">
                                    {t("VisualizeChartComponent.DisplayHorizontalScroll")}
                                </label>
                            </div>
                        </div>

                        <TextField
                            id="summary"
                            name="summary"
                            label={t("VisualizeChartComponent.ChartSummary")}
                            hint={
                                <>
                                    {t("VisualizeChartComponent.ChartSummaryHint")}{" "}
                                    <Link target="_blank" to={"/admin/markdown"} external>
                                        {t("AddTextScreen.ViewMarkdownSyntax")}
                                    </Link>
                                </>
                            }
                            register={props.register}
                            multiline
                            rows={5}
                        />

                        <div className="usa-checkbox">
                            <input
                                className="usa-checkbox__input"
                                id="summary-below"
                                type="checkbox"
                                name="summaryBelow"
                                defaultChecked={false}
                                ref={props.register()}
                            />
                            <label className="usa-checkbox__label" htmlFor="summary-below">
                                {t("VisualizeChartComponent.ChartShowSummary")}
                            </label>
                        </div>
                        <br />
                        <br />
                        <hr />
                        <Button
                            variant="outline"
                            type="button"
                            onClick={props.backStep}
                            className="margin-top-1"
                        >
                            {t("BackButton")}
                        </Button>
                        <Button
                            type="submit"
                            disabled={
                                !props.json.length || props.fileLoading || props.processingWidget
                            }
                            className="margin-top-1"
                        >
                            {props.submitButtonLabel}
                        </Button>
                        <Button
                            variant="unstyled"
                            className="text-base-dark hover:text-base-darker active:text-base-darkest margin-top-1"
                            type="button"
                            onClick={props.onCancel}
                        >
                            {t("Cancel")}
                        </Button>
                    </fieldset>
                </PrimaryActionBar>
            </div>
            <section
                className={props.fullPreview ? "tablet:grid-col-12" : "tablet:grid-col-6"}
                aria-label={t("ContentPreview")}
            >
                <div
                    hidden={!props.json.length}
                    className={`${!props.fullPreview ? "margin-left-4 sticky-preview" : ""}`}
                >
                    {isMobile ? <br /> : props.fullPreviewButton}
                    <div id={props.previewPanelId}>
                        {props.datasetLoading ? (
                            <Spinner
                                className="text-center margin-top-6"
                                label={t("LoadingSpinnerLabel")}
                            />
                        ) : (
                            <>
                                {showAlert &&
                                props.datasetType === DatasetType.StaticDataset &&
                                props.csvJson.length ? (
                                    <Alert
                                        type="info"
                                        message={
                                            <div className="grid-row margin-left-6">
                                                <div className="grid-col-11">
                                                    {t(
                                                        "VisualizeChartComponent.ChartCorrectDisplay",
                                                    )}{" "}
                                                    <Link
                                                        to="/admin/formatting"
                                                        target="_blank"
                                                        external
                                                    >
                                                        {t("LearnHowToFormatCSV")}
                                                    </Link>
                                                </div>
                                                <div className="grid-col-1">
                                                    <div className="margin-1">
                                                        <Button
                                                            variant="unstyled"
                                                            className="margin-0-important text-base-dark hover:text-base-darker active:text-base-darkest"
                                                            onClick={() => setShowAlert(false)}
                                                            type="button"
                                                            ariaLabel={t("GlobalClose")}
                                                        >
                                                            <FontAwesomeIcon
                                                                icon={faTimes}
                                                                size="sm"
                                                            />
                                                        </Button>
                                                    </div>
                                                </div>
                                            </div>
                                        }
                                        slim
                                    />
                                ) : (
                                    ""
                                )}
                                {props.chartType === ChartType.LineChart && (
                                    <LineChartWidget
                                        id={props.widgetId}
                                        title={props.showTitle ? props.title : ""}
                                        downloadTitle={props.title}
                                        summary={props.summary}
                                        lines={props.json.length ? Object.keys(props.json[0]) : []}
                                        data={props.json}
                                        summaryBelow={props.summaryBelow}
                                        isPreview={!props.fullPreview}
                                        horizontalScroll={props.horizontalScroll}
                                        setWidthPercent={setWidthPercent}
                                        significantDigitLabels={props.significantDigitLabels}
                                        columnsMetadata={props.columnsMetadata}
                                        height={300}
                                    />
                                )}
                                {props.chartType === ChartType.ColumnChart && (
                                    <ColumnChartWidget
                                        id={props.widgetId}
                                        title={props.showTitle ? props.title : ""}
                                        downloadTitle={props.title}
                                        summary={props.summary}
                                        columns={
                                            props.json.length ? Object.keys(props.json[0]) : []
                                        }
                                        data={props.json}
                                        summaryBelow={props.summaryBelow}
                                        isPreview={!props.fullPreview}
                                        horizontalScroll={props.horizontalScroll}
                                        stackedChart={props.stackedChart}
                                        setWidthPercent={setWidthPercent}
                                        significantDigitLabels={props.significantDigitLabels}
                                        columnsMetadata={props.columnsMetadata || []}
                                        height={300}
                                    />
                                )}
                                {props.chartType === ChartType.BarChart && (
                                    <BarChartWidget
                                        id={props.widgetId}
                                        title={props.showTitle ? props.title : ""}
                                        downloadTitle={props.title}
                                        summary={props.summary}
                                        bars={props.json.length ? Object.keys(props.json[0]) : []}
                                        data={props.json}
                                        summaryBelow={props.summaryBelow}
                                        significantDigitLabels={props.significantDigitLabels}
                                        columnsMetadata={props.columnsMetadata || []}
                                        stackedChart={props.stackedChart}
                                        height={250}
                                    />
                                )}
                                {props.chartType === ChartType.PartWholeChart && (
                                    <PartWholeChartWidget
                                        id={props.widgetId}
                                        title={props.showTitle ? props.title : ""}
                                        downloadTitle={props.title}
                                        summary={props.summary}
                                        parts={props.json.length ? Object.keys(props.json[0]) : []}
                                        data={props.json}
                                        summaryBelow={props.summaryBelow}
                                        significantDigitLabels={props.significantDigitLabels}
                                        columnsMetadata={props.columnsMetadata}
                                    />
                                )}
                                {props.chartType === ChartType.PieChart && (
                                    <PieChartWidget
                                        id={props.widgetId}
                                        title={props.showTitle ? props.title : ""}
                                        downloadTitle={props.title}
                                        summary={props.summary}
                                        parts={props.json.length ? Object.keys(props.json[0]) : []}
                                        data={props.json}
                                        summaryBelow={props.summaryBelow}
                                        significantDigitLabels={props.significantDigitLabels}
                                        hideDataLabels={!props.dataLabels}
                                        isPreview={!props.fullPreview}
                                        columnsMetadata={props.columnsMetadata}
                                        computePercentages={props.computePercentages}
                                    />
                                )}
                                {props.chartType === ChartType.DonutChart && (
                                    <DonutChartWidget
                                        id={props.widgetId}
                                        title={props.showTitle ? props.title : ""}
                                        downloadTitle={props.title}
                                        summary={props.summary}
                                        parts={props.json.length ? Object.keys(props.json[0]) : []}
                                        data={props.json}
                                        summaryBelow={props.summaryBelow}
                                        significantDigitLabels={props.significantDigitLabels}
                                        hideDataLabels={!props.dataLabels}
                                        showTotal={props.showTotal}
                                        isPreview={!props.fullPreview}
                                        columnsMetadata={props.columnsMetadata}
                                        computePercentages={props.computePercentages}
                                    />
                                )}
                            </>
                        )}
                    </div>
                </div>
            </section>
        </div>
    );
}

export default VisualizeChart;