"use client"
import { ReactElement, createRef, useEffect, useState } from "react";
import { DataFieldset } from "./DataFieldset"
import { DataField } from "./DataField";
import { Button } from "./Button";
import Card from "./Card";
import CryptoJS from 'crypto-js';
import { SelectRequestBody, TableConditionGroups } from "./DataStructure";
import axios from "axios";
import { Notification, NotificationProps } from "./Notification";

export interface AuthenticationSettings{
  table: string,
  emailId: string,
  passwordId: string,
  secretId: string,
  roleId: string
}

interface Props{
  type: "Login" | "Forgot Password" | "Reset Password";
  header?: ReactElement;
  footer?: ReactElement;
  className?: string;
  apiURL?: string;
  settings: AuthenticationSettings;
  onLogin: (role?: any, userId?: string) => void;
  onRegisterFallback?: () => void;
}

export const AuthenticationForm = (props: Props) => {
  const containerClassName = `${props.className}`;
  const [formType, setFormType] = useState(props.type);
  const [userData, setUserData] = useState<any>({});
  const [showNotification, setShowNotification] = useState(false);
  const [notificationProps, setNotificationProps] = useState<NotificationProps>({
    type: "Info",
    title: "",
    description: "",
  });
  const endPointURL = `${props.apiURL}/api/select`;

  const handleAuthentication = async () => {
    const columns: string[] = [];
    const whereConditions: TableConditionGroups[] = []
    const formData = new FormData();

    switch(formType){
      case "Login":
        const passwordHash = CryptoJS.MD5(userData.password).toString();
        columns.push('id');
        columns.push(props.settings.roleId);
        whereConditions.push({
          condition: [
            {
              queryColumn: props.settings.emailId,
              value: userData.email,
              operator: "=",
              logicalOperator: "AND"
            },
            {
              queryColumn: props.settings.passwordId,
              value: passwordHash,
              operator: "="
            }
          ],
        });
      break;
    }

    const selectQuery: SelectRequestBody = {
      table: props.settings.table,
      columns: columns,
      where: whereConditions.length > 0 ? whereConditions : undefined,
    }

    formData.append("query", JSON.stringify(selectQuery));
    
    try{
      const queryRes = await axios.post(endPointURL, formData, {
        headers: {
          'Content-Type': 'multipart/form-data',
        },
      });
      
      if(queryRes.data && queryRes.data["rows"] && queryRes.data["rows"].length > 0){
        localStorage.setItem('userId', queryRes.data['rows'][0].id);
        props.onLogin(queryRes.data['rows'][0][props.settings.roleId], queryRes.data['rows'][0].id);
      }else{
        
        setNotificationProps({
          type: "Error",
          title: `Authentication Failed!`,
          description: `Can't find matched credentials in the database.`
        });
        setShowNotification(true);
      }
    }catch(err) {}
  }

  const renderFooterNavigator = () => {
    switch(formType) {
      case "Login":
        return (
          <div className="m-auto text-center flex flex-col">
            <Button
              text="Forget your password? Reset now."
              additionalClassName="!p-0 text-center"
              bgColor="bg-transparent"
              color="text-primary-400 hover:text-neutral-400"
              size="sm"
              onClick={() => {
                setFormType('Forgot Password');
              }}
            />
            <Button
              text="No account yet? Register now!"
              additionalClassName="!p-0 text-center"
              bgColor="bg-transparent"
              color="text-primary-400 hover:text-neutral-400"
              size="sm"
              onClick={() => {
                if(props.onRegisterFallback){
                  props.onRegisterFallback();
                }
              }}
            />
          </div>
        )
      case "Forgot Password":
        return (
          <div className="m-auto text-center">
            <Button
              text="Found your password? Login now."
              additionalClassName="!p-0 text-center"
              bgColor="bg-transparent"
              color="text-primary-400 hover:text-neutral-400"
              size="sm"
              onClick={() => {
                setFormType('Login');
              }}
            />
          </div>
        )
    }
  }
  
  const renderLoginForm = () => {
    return (
      <Card containerClassName={containerClassName}>
        {props.header}
        <DataFieldset columns={1} className="mb-8">
          <DataField 
            dataStructure={{
              fieldId: "email",
              type: "string",
              displayName: "Email Address",
              length: 200,
              required: true
            }}
            onChange={(inputValue) => {
              const localValue = {...userData};
              localValue['email'] = inputValue;
              setUserData(localValue);
            }}
          />
          <DataField
            dataStructure={{
              fieldId: "password",
              type: "password",
              displayName: "Password",
              hideFromList: true,
              length: 500,
              required: true
            }}
            onChange={(inputValue) => {
              const localValue = {...userData};
              localValue['password'] = inputValue;
              setUserData(localValue);
            }}
          />
        </DataFieldset>
        <Button
          text="Log in"
          additionalClassName="py-2 px-5 w-full bg-primary-400 text-white rounded-md font-semibold mb-5"
          onClick={() => {
            handleAuthentication();
          }}
          size="lg"
        />
        {renderFooterNavigator()}
        {props.footer}
      </Card>
    )
  }

  const renderForgetPasswordForm = () => {
    return (
      <Card containerClassName={containerClassName}>
        {props.header}
        <DataFieldset columns={1} className="mb-8">
          <DataField 
            dataStructure={{
              fieldId: "email",
              type: "string",
              displayName: "Email Address",
              length: 200,
              required: true
            }}
          />
        </DataFieldset>
        <Button
          text="Reset password"
          additionalClassName="py-2 px-5 w-full bg-primary-400 text-white rounded-md font-semibold mb-5"
          onClick={() => {
          }}
          size="lg"
        />
        {renderFooterNavigator()}
        {props.footer}
      </Card>
    )
  }

  const renderResetPasswordForm = () => {
    return (
      <Card containerClassName={containerClassName}>
        {props.header}
        <DataFieldset columns={1} className="mb-8">
          <DataField 
            dataStructure={{
              fieldId: "email",
              type: "string",
              displayName: "Email Address",
              length: 200,
              required: true
            }}
          />
          <DataField
            dataStructure={{
              fieldId: "password",
              type: "password",
              displayName: "New Password",
              hideFromList: true,
              length: 500,
              required: true
            }}
          />
          <DataField
            dataStructure={{
              fieldId: "confirm_password",
              type: "password",
              displayName: "Confirm New Password",
              isConfirmation: true,
              hideFromList: true,
              length: 500,
              required: true
            }}
          />
        </DataFieldset>
        <Button
          text="Reset Password"
          additionalClassName="py-2 px-5 w-full bg-primary-400 text-white rounded-md font-semibold mb-5"
          onClick={() => {
          }}
          size="lg"
        />
        {renderFooterNavigator()}
        {props.footer}
      </Card>
    )
  }


  const renderForm = () => {
    switch(formType){
      case "Login":
        return renderLoginForm();
      case "Forgot Password":
        return renderForgetPasswordForm();
      case "Reset Password":
        return renderResetPasswordForm();
    }
    return <></>
  }

  return (
    <>
      {renderForm()}
      <Notification
        {...notificationProps}
        onClose={() => {
          setShowNotification(false);
        }}
        show={showNotification}
      />
    </>
  )
}