import { ReactNode, useEffect, useState } from "react";
import { useLoaderData, useNavigate, useSearchParams } from "react-router-dom";
import { AppLayout, BreadcrumbGroup, Container, Flashbar, FlashbarProps, Header, SpaceBetween, TextContent, Wizard } from "@cloudscape-design/components";
import OtpInput from 'react-otp-input';
import { CountdownBar } from "../components/CountdownBar";
import { fetchUrlEncoded } from "../helpers/FetchHelper";
import { readSync } from "fs";

export function OnboardingPage() {
  const navigate = useNavigate();
  const [ step, setStep ] = useState(0);
  const [ alerts, setAlerts ] = useState<FlashbarProps.MessageDefinition[]>([]);
  
  const [ otp, setOtp ] = useState("");
  const [ buzzerNumber, setBuzzerNumber ] = useState("");

  const dismissAlert = (id: string) => {
    setAlerts(alerts => alerts.filter(alert => alert.id !== id));
  }

  const dismissInProgressAlerts = () => {
    setAlerts(alerts => alerts.filter(alert => alert.type !== 'in-progress'));
  }

  const createAlert = (type: FlashbarProps.Type, content: ReactNode): FlashbarProps.MessageDefinition => {
    const id = `${Math.random()}`;
    return {
      id,
      type,
      content,
      dismissible: type !== 'in-progress',
      onDismiss: () => dismissAlert(id),
    }
  }

  const addAlert = (type: FlashbarProps.Type, content: ReactNode): string => {
    const newAlert = createAlert(type, content);
    setAlerts(alerts => [
      newAlert,
      ...alerts,
    ]);

    return newAlert.id as string;
  }

  useEffect(() => {
    if (otp.length === 4) {
      // see if this is valid otp
      fetchUrlEncoded('/api/door/checkOtp', {
        otp,
      }).then(res => res.json())
        .then(res => {
          if (res.msg) {
            addAlert("error", res.msg);
            return;
          }
          const apiNumber = res.buzzer;
      
          setBuzzerNumber(apiNumber);
          addAlert("success", `Successfully verified Buzzer as ${apiNumber}`);
          setTimeout(() => {
            setStep(3);
          }, 1_000);
        });
    }
  }, [otp]);

  return (
    <AppLayout
      contentType="wizard"
      navigationHide
      toolsHide
      breadcrumbs={
        <BreadcrumbGroup
          items={[
            { text: 'Door', href: '#' },
            { text: 'Onboarding', href: '#' },
          ]}
        />
      }
      notifications={
        <Flashbar 
          stackItems={true}
          items={alerts}
        />
      }
      content={
        <Wizard
          i18nStrings={{
            stepNumberLabel: stepNumber =>
              `Step ${stepNumber}`,
            collapsedStepsLabel: (stepNumber, stepsCount) =>
              `Step ${stepNumber} of ${stepsCount}`,
            skipToButtonLabel: (step, stepNumber) =>
              `Skip to ${step.title}`,
            navigationAriaLabel: "Steps",
            cancelButton: "Cancel",
            previousButton: "Previous",
            nextButton: "Next",
            submitButton: "Finish",
            optional: "optional"
          }}
          activeStepIndex={step}
          onSubmit={() => {
            navigate(`/?onboardForm&buzzer=${buzzerNumber}`)
          }}
          onNavigate={({ detail }) => {
            if (detail.requestedStepIndex < step) {
              dismissInProgressAlerts();
              setStep(detail.requestedStepIndex);
              return;
            }
            
            if (detail.requestedStepIndex === 2) {
              fetchUrlEncoded('/api/door/auth', {
                door: "onboardingflag",
                key: 1234
              })
                .then(res => res.json())
                .then(res => {
                  if (res.status === "CLOSED" || !res.msg) {
                    addAlert('error', 'Something went wrong, please try again');
                  } else {
                    addAlert("in-progress", (
                      <CountdownBar
                        label="Onboarding Timeout"
                        description="Complete Onboarding before timeout"
                        additionalInfo="Onboarding times out after 15 minutes, please complete the onboarding before then"
                        timeSeconds={15 * 60} 
                        onExpiry={() => {
                          addAlert("error", "Onboarding timed out: please try again");
                          setStep(1);
                        }}
                      />
                    ));
                    setStep(detail.requestedStepIndex);
                  }
                });
              return;
            }

            if (detail.requestedStepIndex === 3) {
              if (buzzerNumber === "") {
                addAlert('error', "Please enter 4 digit verification code to proceed");
                return;
              }
            }

            setStep(detail.requestedStepIndex);
          }}
          onCancel={() => {
            setStep(0);
            dismissInProgressAlerts();
          }}
          steps={[
            {
              title: "Set your Buzzer Number",
              description:"Before onboarding Doorman, you need to configure your Buzzer number",
              content: (
                <Container
                  header={
                    <Header variant="h2">
                      Set your Buzzer Number
                    </Header>
                  }
                >
                  This would usually involve contacting your building to change your Buzzer to call Doorman's phone number:
                  <Header variant="h3">604-757-1824</Header>
                  Once you have done this, continue along the onboarding process!
                </Container>
              )
            },
            {
              title: "Get to the Buzzer",
              description:"To continue onboarding this Door, you should go physically to the Buzzer",
              content: (
                <Container
                  header={
                    <Header variant="h2">
                      Get to the buzzer
                    </Header>
                  }
                >
                  The next step will require you to dial your Buzzer so Doorman can identify who is calling. Once you arrive at your Buzzer, advance to the next step.
                </Container>
              )
            },
            {
              title: "Identify",
              description: "Enter the 4 digit code that you hear back from Doorman",
              content: (
                <Container
                  header={
                    <Header variant="h2">
                      Identify
                    </Header>
                  }
                >
                  For this step, you need to dial your Buzzer. It should call Doorman, and you will hear a message with a generated 4 digit code. 
                  <br/>
                  Enter the 4 digit code below to proceed
                  <OtpInput
                    containerStyle={{
                      width: "100%",
                      justifyContent: "center",
                    }}
                    inputStyle={{
                      margin: '0.5rem',
                      height: '3rem',
                      width: '2rem',
                      fontSize: '2rem',
                    }}
                    value={otp}
                    numInputs={4}
                    onChange={(e) => setOtp(e)}
                    renderInput={(props) => <input {...props} />}
                  />
                </Container>
              )
            },
            {
              title: "Complete Onboarding Form",
              description: "Redirect to complete the rest of onboarding form",
              content: (
                <Container
                  header={
                    <Header variant="h2">
                      Complete Onboarding Form
                    </Header>
                  }
                >
                  Your buzzer number was identified as:
                  <Header>{buzzerNumber}</Header>
                  Click Finish below to be redirected to complete the rest of the onboarding for Doorman
                </Container>
              )
            },
          ]}
        />
      }
    />
  );
};
