import { AppLayout, BreadcrumbGroup, Button, Container, Flashbar, FlashbarProps, Form, FormField, Header, Link, SpaceBetween } from "@cloudscape-design/components";
import { useLoaderData, useSearchParams } from "react-router-dom";
import { DoorResponse } from "../types/DoorResponse";
import { useForm } from "react-hook-form";
import { InputTokenGroup } from "../components/InputTokenGroup";
import { ReactNode, useState } from "react";

export type DoorEditForm = DoorResponse & { pin: string, fallbackNumber: string, discordUser: string };

export const EditPage = () => {
  const doorResponse = useLoaderData() as DoorResponse;
  const door = doorResponse.id;
  const { register, setValue, setError, getValues, watch, formState, clearErrors } = useForm<DoorEditForm>({
    defaultValues: doorResponse,
    mode: "all",
  });
  

  const [ alerts, setAlerts ] = useState<FlashbarProps.MessageDefinition[]>([]);

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


  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;
  }


  const fallbackNumbers = watch("fallbackNumbers");
  const discordUsers = watch("discordUsers");

  const fallbackNumbersError = formState.errors.fallbackNumbers?.message;
  const discordUsersError = formState.errors.discordUsers?.message;

  return (     
    <AppLayout
      contentType="form"
      navigationHide
      toolsHide
      breadcrumbs={
        <BreadcrumbGroup
          items={[
            { text: 'Door', href: '#' },
            { text: door, href: `?edit&door=${door}` },
          ]}
        />
      }
      notifications={
        <Flashbar 
          stackItems={true}
          items={alerts}
        />
      }
      content={
        <Form
          actions={
            <SpaceBetween direction="horizontal" size="xs">
              <Button formAction="none" variant="link" href={`?door=${door}`}>
                Cancel
              </Button>
              <Button 
                variant="primary"
                onClick={() => {
                  fetch(`/api/door/edit?door=${door}&newConfig=${encodeURIComponent(JSON.stringify(getValues()))}`)
                  .then(res => res.json())
                  .then(res => {
                    addAlert("success", `Created approval, check Discord notifcation from Doorman to confirm and approve the changes`);
                  })
                }}
              >
                Submit
              </Button>
            </SpaceBetween>
          }
          header={<Header variant="h1">Edit Door</Header>}
        >
          <Container
            header={
              <Header variant="h2">
                Door - {door}
              </Header>
            }
          >
            <SpaceBetween direction="vertical" size="l">
              <FormField label="Buzzer Number (read-only)" constraintText="The phone number of your buzzer system">
                <input readOnly {...register("buzzer")} />
              </FormField>
              <FormField label="PIN" constraintText={"The code to unlock the buzzer"}>
                <input type="password" {...register("pin")}/>
              </FormField>
              <FormField label="Buzzer Code" constraintText={"The number that you dial on your buzzer"}>
                <input {...register("buzzerCode")} />
              </FormField>
              <FormField label="Timeout" constraintText="Time in seconds for the door to remain unlocked">
                <input type="number" {...register("timeout", {
                  valueAsNumber: true,
                })} />
              </FormField>
              <FormField label="Unlock key" constraintText="Key to press to buzz up on Intercom">
                <input {...register("pressKey")} />
              </FormField>
              <FormField 
                errorText={fallbackNumbersError}
                label="Fallback numbers" 
                constraintText="Phone numbers to dial through in case door is not unlocked"
              >
                <InputTokenGroup
                  registerInput={register("fallbackNumber")}
                  tokenGroupProps={{ items: fallbackNumbers.map(n => ({ label: n }))}}
                  onAdd={() => {
                    clearErrors("fallbackNumbers");
                    setValue("fallbackNumbers", [...fallbackNumbers, getValues().fallbackNumber])
                    setValue("fallbackNumber", "")
                  }}
                  onDismiss={(i) => {
                    clearErrors("fallbackNumbers");

                    if (fallbackNumbers.length === 1) {
                      setError("fallbackNumbers", { message: "Can't remove last entry", type: "value" })
                      return;
                    }
                    fallbackNumbers.splice(i, 1);
                    setValue("fallbackNumbers", [...fallbackNumbers]);
                  }}
                />
              </FormField>
              <FormField 
                label="Discord Users" 
                errorText={discordUsersError}
                constraintText={
                  <>
                    <Link fontSize={"body-s"} href="https://support.discord.com/hc/en-us/articles/206346498-Where-can-I-find-my-User-Server-Message-ID#h_01HRSTXPS5H5D7JBY2QKKPVKNA">Discord users</Link> to receive notifications
                  </>
                }
              >
                <InputTokenGroup
                  type="string"
                  registerInput={register("discordUser")}
                  tokenGroupProps={{ items: discordUsers.map(n => ({ label: n }))}}
                  onAdd={() => {
                    clearErrors("discordUsers");
                    setValue("discordUsers", [...discordUsers, getValues().discordUser])
                    setValue("discordUser", "")
                  }}
                  onDismiss={(i) => {
                    clearErrors("discordUsers");

                    if (discordUsers.length === 1) {
                      setError("discordUsers", { message: "Can't remove last entry" })
                      return;
                    }
                    discordUsers.splice(i, 1);
                    setValue("discordUsers", [...discordUsers]);
                  }}
                />
              </FormField>
              <FormField label="Welcome Message" constraintText="Message to display after a successful unlock">
                <textarea {...register("greeting")}/>
              </FormField>
            </SpaceBetween>
          </Container>
        </Form>
      }
    />
  );
};
