import { useSelector } from "react-redux";
import { AppState } from "@/state/reducer";
import { getSubmissionStatus, SubmissionState, SubmissionStatus } from "@/state/reducer/submission";
import { useTranslation } from "react-i18next";
import { Box, Button, ButtonProps, Dialog, DialogContent, DialogProps, DialogTitle, StepProps, Typography } from "@material-ui/core";
import { FileFind, FileUploadOutline } from "mdi-material-ui/index";
import { route } from "@/routing";
import { Link as RouterLink } from "react-router-dom";
import { Actions, Step } from "@/components";
import React, { HTMLProps, useState } from "react";
import { Alert, AlertTitle } from "@material-ui/lab";
import { ContactButton, Status } from "@/pages/steps/common";
import { useCurrentEdition, useDeadlines } from "@/hooks";
import { useSpacing } from "@/styles";
import { MultiChoiceValue, Report, ReportSchema, SingleChoiceValue, TextFieldValue } from "@/data/report";
import { createPortal } from "react-dom";
import { getInternshipReport } from "@/state/reducer/report";
import { Edition } from "@/data/edition";

export type ReportPreviewProps = {
    schema: ReportSchema,
    report: Report,
}

export const ReportPreview = ({ schema, report }: ReportPreviewProps) => {
    return <>{ schema.map(field => {
        const value = report.fields[`field_${ field.id }`];
        const { t } = useTranslation();

        const Value = () => {
            switch (field.type) {
                case "checkbox":
                    return <ul>{ ((value as MultiChoiceValue).map(selection => <li>{ selection.pl }</li>)) }</ul>
                case "radio":
                case "select":
                    return <div>{ (value as SingleChoiceValue).pl }</div>
                case "long-text":
                case "short-text":
                    return <p>{ value as TextFieldValue }</p>
            }
        }

        return <>
            <Typography variant="subtitle2">{ field.label.pl }</Typography>
            { value ? <Value/> : t("no-value") }
        </>
    }) }</>
}

export type ReportPreviewDialogProps = {
    report: Report;
} & DialogProps;

export const ReportPreviewDialog = ({ report, ...props }: ReportPreviewDialogProps) => {
    const edition = useCurrentEdition() as Edition;
    const schema = edition.schema || [];
    const { t } = useTranslation();

    return <Dialog { ...props } maxWidth="md" fullWidth>
        <DialogTitle>{ t("steps.report.header") }</DialogTitle>
        <DialogContent><ReportPreview schema={ schema } report={ report }/></DialogContent>
    </Dialog>
}

const ReportActions = () => {
    const status = useSelector<AppState, SubmissionStatus>(state => getSubmissionStatus(state.report));

    const { t } = useTranslation();

    const FormAction = ({ children = t('steps.report.submit'), ...props }: ButtonProps) =>
        <Button to={ route("internship_report") } variant="contained" color="primary" component={ RouterLink }
                startIcon={ <FileUploadOutline/> } { ...props as any }>
            { children }
        </Button>

    const ReviewAction = (props: ButtonProps) => {
        const [open, setOpen,] = useState<boolean>(false);
        const report = useSelector<AppState, Report>(state => getInternshipReport(state.report) as Report);

        return <>
            <Button startIcon={ <FileFind/> }
                    onClick={ () => setOpen(true) }
                    { ...props as any }>
                { t('review') }
            </Button>
            { createPortal(
                <ReportPreviewDialog report={ report } open={ open } onClose={ () => setOpen(false) }/>,
                document.getElementById("modals") as Element,
            ) }
        </>
    }

    switch (status) {
        case "awaiting":
            return <Actions>
                <ReviewAction/>
                <FormAction>{ t('send-again') }</FormAction>
            </Actions>
        case "accepted":
            return <Actions>
                <FormAction variant="outlined" color="secondary">{ t('send-again') }</FormAction>
            </Actions>
        case "declined":
            return <Actions>
                <FormAction>{ t('send-again') }</FormAction>
                <ContactButton/>
            </Actions>
        case "draft":
            return <Actions>
                <FormAction/>
            </Actions>

        default:
            return <Actions/>
    }
}

export const PlanComment = (props: HTMLProps<HTMLDivElement>) => {
    const { comment, declined } = useSelector<AppState, SubmissionState>(state => state.plan);
    const { t } = useTranslation();

    return comment ? <Alert severity={ declined ? "error" : "warning" } { ...props as any }>
        <AlertTitle>{ t('comments') }</AlertTitle>
        { comment }
    </Alert> : null
}

export const ReportStep = (props: StepProps) => {
    const { t } = useTranslation();

    const submission = useSelector<AppState, SubmissionState>(state => state.report);
    const spacing = useSpacing(2);
    const edition = useCurrentEdition();

    const status = getSubmissionStatus(submission);
    const deadlines = useDeadlines();

    const { sent, declined, comment } = submission;

    return <Step { ...props }
                 label={ t('steps.report.header') }
                 active={ true } completed={ sent } declined={ declined } waiting={ status == "awaiting" }
                 until={ deadlines.report }
                 notBefore={ edition?.reportingStart }
                 state={ <Status submission={ submission }/> }>
        <div className={ spacing.vertical }>
            <p>{ t(`steps.report.info.${ status }`) }</p>

            { comment && <Box pb={ 2 }><PlanComment/></Box> }

            <ReportActions/>
        </div>
    </Step>;
}
