import React, { useState } from "react";
import Col from "react-bootstrap/Col";
import Form from "react-bootstrap/Form";
import Row from "react-bootstrap/Row";
import Button from "../../pageElements/Button";
import { db, auth } from "../../firebase";
import { createUserWithEmailAndPassword } from "firebase/auth";
import { useNavigate } from "react-router-dom";
import Toggle from "../../pageElements/Toggle";
import TextInput from "../../pageElements/TextInput";
import { v4 as uuidv4 } from "uuid";
import { collection, setDoc, doc } from "firebase/firestore";
import { splitEvery } from "../../Utils/Array";
import {
  getFormDataDefaults,
  getValidatedFormData,
  handleFormDataChange,
  isFormDataHasErrors,
} from "../../Utils/Form";
import { objectMap } from "../../Utils/Object";
import { determinePlan } from "../../Utils/Miscutils";
import { signupFields } from "../../Constants/Fields/SignupFields";
import { paymentfields } from "../../Constants/Fields/PaymentFields";
import { signupRadioFields } from "../../Constants/Fields/RadioFields";
import PaymentModal from "../Modals/PaymentModal";
import Radio from "../../pageElements/Radio";
import "../../styles/signup.scss";
import Stripe from "stripe";
import { stripeApiKey } from "../../secrets";

const SignupPage = () => {
  const navigate = useNavigate();
  const [notice, setNotice] = useState("");
  const fieldsChunkSize = 2;
  const [isBusy, setIsBusy] = useState(false);
  const [data, setData] = useState(getFormDataDefaults(signupFields));
  const [paymentData, setPaymentData] = useState(
    getFormDataDefaults(paymentfields)
  );
  const [showPaymentModal, setShowPaymentModal] = useState(false);
  const [showSelectPlan, setShowSelectPlan] = useState(false);
  const [activeRadioOption, setActiveRadioOption] = useState("partner");
  const [selectedPlan, setSelectedPlan] = useState([signupRadioFields[1]]);
  const [isAnnual, setIsAnnual] = useState(1);
  const stripe = new Stripe(stripeApiKey);
  const apiUrl =
    process.env.NODE_ENV === "development"
      ? process.env.REACT_APP_API_DEV
      : process.env.REACT_APP_API_PROD;
  const [showAddAccount, setShowAddAccount] = useState(false);
  const [numberOfAccountsToAdd, setNumberOfAccountsToAdd] = useState();

  const handleChangeInput = (e, name) => {
    const newData = handleFormDataChange(e, name, data, signupFields);
    if (newData !== null) {
      setData(newData);
    }
  };

  const handleChangeAccountSelect = (e, name) => {
    const num = e.target.value;
    const temp = Number(num);
    setNumberOfAccountsToAdd(temp);
  };

  const handleChangePaymentInput = (e, name) => {
    const newPaymentData = handleFormDataChange(
      e,
      name,
      paymentData,
      paymentfields
    );
    if (newPaymentData !== null) {
      setPaymentData(newPaymentData);
    }
  };

  const handleChangeRadioInput = (value) => {
    const tempPlan = signupRadioFields.filter((plan) => {
      if (plan.value === value) {
        return plan;
      }
    });

    setSelectedPlan(tempPlan);
    setActiveRadioOption(tempPlan[0].value);
  };

  const vals = [
    [1, 2, 3, 4, 5, 6, 7, 8],
    [1, 2],
  ];
  const selectAdditionalAccountValues =
    selectedPlan[0].value === "partner" ? vals[1] : vals[0];

  const validateUserData = () => {
    const newData = getValidatedFormData(data, signupFields);
    const hasErrors = isFormDataHasErrors(newData);
    setData(newData);
    return hasErrors ? null : objectMap(({ value }) => value, newData);
  };

  const validatePaymentData = () => {
    const newPaymentData = getValidatedFormData(paymentData, paymentfields);
    const hasErrors = isFormDataHasErrors(newPaymentData);
    setPaymentData(newPaymentData);
    return hasErrors ? null : objectMap(({ value }) => value, newPaymentData);
  };

  async function saveLeadData(dataValues) {
    const signupId = uuidv4();
    const {
      firstName,
      lastName,
      firm,
      telephone,
      streetAddress,
      city,
      state,
      zipCode,
      barNumber,
      practiceArea,
      email,
    } = dataValues;

    const userData = {
      firstName,
      lastName,
      firm,
      telephone,
      streetAddress,
      city,
      state,
      zipCode,
      barNumber,
      practiceArea,
      email,
      signupId,
    };

    try {
      const collecRef = collection(db, "signupLeads");
      await setDoc(doc(collecRef, `${signupId}`), userData);
    } catch (error) {
      console.log(`Error saving new user to db: ${error}`);
    }
  }

  async function saveUserData(authId, dataValues, customerId, subscriptionId) {
    const appUserId = uuidv4();
    const firmId = uuidv4();
    const fbAuthUid = authId;
    const plan = selectedPlan;
    const docsAllowed =
      plan === "associate" ? 1 : plan === "partner" ? 3 : "unlimited";
    const docsGenerated = 0;
    const {
      firstName,
      lastName,
      firm,
      telephone,
      streetAddress,
      city,
      state,
      zipCode,
      barNumber,
      practiceArea,
      email,
    } = dataValues;

    const userData = {
      docsAllowed,
      docsGenerated,
      appUserId,
      fbAuthUid,
      firmId,
      firstName,
      lastName,
      firm,
      telephone,
      streetAddress,
      city,
      state,
      zipCode,
      barNumber,
      practiceArea,
      email,
      customerId: customerId,
      subscriptionId: subscriptionId,
    };

    try {
      const usersRef = collection(db, "users");
      await setDoc(doc(usersRef, fbAuthUid), userData);
    } catch (error) {
      console.log(`Error saving new user to db: ${error}`);
    }
  }

  const handleProceedToPayment = (e) => {
    e.preventDefault();
    setShowPaymentModal(true);
  };

  const handleAdd = () => {
    //add accounts, close section
    setShowAddAccount(!showAddAccount);
    setShowPaymentModal(true);
  };

  const handleOpenSelectPlan = (e) => {
    e.preventDefault();
    if (isBusy) {
      return;
    }
    /*
    const dataValues = validateUserData();
    if (dataValues === null) {
      return;
    }

    saveLeadData(dataValues);
*/
    setShowSelectPlan(!showSelectPlan);
  };

  const handleToggle = (e) => {
    if (isAnnual === e) {
      return;
    } else {
      setIsAnnual(e);
    }
  };

  const handleAddAccounts = () => {
    setShowAddAccount(!showAddAccount);
  };

  const handleCancelAdd = () => {
    setShowAddAccount(!showAddAccount);
  };

  // ******************** STRIPE PAYMENT API CALL ******************** //
  async function handleStripeAuthorization(
    paymentDataValues,
    customerDataValues
  ) {
    const additionalAccounts = numberOfAccountsToAdd
      ? numberOfAccountsToAdd
      : 0;
    let error = false;
    let subscriptionId = null;
    let customerId = null;

    const token = await stripe.tokens.create({
      card: {
        number: paymentDataValues.cardNumber,
        exp_month: paymentDataValues.cardExpirationMonth,
        exp_year: paymentDataValues.cardExpirationYear,
        cvc: paymentDataValues.cardCvvCode,
        name:
          paymentDataValues.cardFirstName +
          " " +
          paymentDataValues.cardLastName,
      },
    });

    const type = selectedPlan[0].value ? selectedPlan[0].value : null;
    const tempAnnual = isAnnual === 1 ? true : false;
    try {
      const response = await fetch(`${apiUrl}/create-subscription`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          planType: type,
          additionalAccounts: additionalAccounts,
          isAnnual: tempAnnual,
          customerData: {
            email: customerDataValues.email,
            name: `${customerDataValues.firstName} ${customerDataValues.lastName}`,
          },
          token,
        }),
      });

      const data = await response.json();

      console.log("data in stripe auth call -------------++++++++++++++", data);
      //subscriptionId = response.subscriptionId;
      //customerId = response.customerId;

      return {
        data,
      };
    } catch (error) {
      console.log(error);
      return error;
    }
  }
  // ******************** END STRIPE PAYMENT API CALL ******************** //

  const handleSignup = async (e) => {
    e.preventDefault();
    console.log("handleSignup");

    const paymentDataValues = validatePaymentData();
    if (paymentDataValues === null) {
      return;
    }

    let dataValues = validateUserData();
    if (dataValues === null) {
      return;
    }

    //const planType = determinePlan(isAnnual, activeRadioOption);
    setIsBusy(true);
    if (paymentDataValues && dataValues) {
      try {
        const data = await handleStripeAuthorization(
          paymentDataValues,
          dataValues
        );
        console.log("----------------------------->>>>>>>>>>>>>>>>>data", data);
        const customerId = data.data.customerId;
        const subscriptionId = data.data.subscriptionId;

        if (data === undefined) {
          setIsBusy(false);
          setNotice("Sorry, something went wrong. Please try again.");
          return;
        } else {
          const userCredential = await createUserWithEmailAndPassword(
            auth,
            dataValues.email,
            dataValues.password
          );

          const user = userCredential.user;
          dataValues = { ...dataValues, ...data };
          console.log(
            "customerId, subscriptionId in handleSignup right before saveUserData",
            customerId,
            subscriptionId
          );
          await saveUserData(user.uid, dataValues, customerId, subscriptionId);
          navigate("/dashboard");
        }
      } catch (error) {
        setIsBusy(false);
        console.log("-------->error", error);
        setNotice(
          error.message || "Sorry, something went wrong. Please try again."
        );
      }
    }
  };

  const showNoticeOnPage = "" !== notice && !showPaymentModal;
  const addAccountCopy =
    selectedPlan[0]?.value === "seniorPartner"
      ? "Add up to eight"
      : "Add up to two";
  const showAddAccountBtn =
    selectedPlan[0].value === "seniorPartner" ||
    selectedPlan[0].value === "partner";

  return (
    <div className="signup-super-container">
      <div className="signup-sub-container">
        <div className="signup-header">
          <h1 className="signup-header-text">Create a Novodraft account</h1>
        </div>
        <Form className="signup-form">
          {splitEvery(
            Object.keys(signupFields).slice(0, -2),
            fieldsChunkSize
          ).map((names, j) => (
            <Row key={`row${j}`}>
              {names.map((name, i) => (
                <Col key={`${name}${i + fieldsChunkSize * j}`} className="mb-3">
                  <TextInput
                    name={name}
                    value={data[name].value}
                    onChange={(e) => handleChangeInput(e, name)}
                    error={data[name].error}
                    message={data[name].message}
                    label={
                      data[name].value.length === 0
                        ? signupFields[name].label
                        : ""
                    }
                    type={signupFields[name].type}
                    values={signupFields[name].values}
                    disabled={isBusy}
                  />
                </Col>
              ))}
            </Row>
          ))}
          <Row>
            <Col className="mb-3">
              <TextInput
                id="signupPassword"
                type="password"
                label={
                  data.password.value.length === 0
                    ? signupFields.password.label
                    : ""
                }
                value={data.password.value}
                error={data.password.error}
                message={data.password.message}
                onChange={(e) => handleChangeInput(e, "password")}
                disabled={isBusy}
              />
            </Col>
          </Row>
          <Row>
            <Col className="mb-3">
              <TextInput
                id="confirmPassword"
                type="password"
                label={
                  data.confirmPassword.value.length === 0
                    ? signupFields.confirmPassword.label
                    : ""
                }
                value={data.confirmPassword.value}
                error={data.confirmPassword.error}
                message={data.confirmPassword.message}
                onChange={(e) => handleChangeInput(e, "confirmPassword")}
                disabled={isBusy}
              />
            </Col>
          </Row>
        </Form>
        <div className="signup-button-box">
          <Button
            className="primary-button signup-proceed"
            type="button"
            size="lg"
            onClick={handleOpenSelectPlan}
            disabled={isBusy}
            labelText="Select A Plan"
          />
        </div>
        {showNoticeOnPage ? (
          <>
            <br></br>
            <div className="alert alert-danger" role="alert">
              {notice}
            </div>
          </>
        ) : (
          <></>
        )}
      </div>
      {showSelectPlan ? (
        <div className="select-plan-container">
          <div className="select-sub-left">
            <div className="select-plan-header">
              <div className="plan-header-right">
                <h5 className="signup-subheader-text">
                  Select a subscription plan
                </h5>
              </div>
              <div className="plan-header-left">
                <div className="select-toggle-box">
                  <p className="select-billing-text">Billed annually</p>
                  <Toggle onClick={handleToggle} />
                  <p className="select-billing-text">Billed montly</p>
                </div>
              </div>
            </div>
            <div className="radio-group-box">
              {signupRadioFields?.map((option, i) => (
                <div className="signup-radio-container">
                  <Radio
                    onClick={handleChangeRadioInput}
                    value={option.value}
                    name={option.name}
                    description={option.description}
                    details={option.details}
                    activeRadioOption={activeRadioOption}
                    price={option.pricing}
                    isAnnual={isAnnual}
                  />
                </div>
              ))}
            </div>
            {showAddAccount ? (
              <div className="show-addaccount-wrapper">
                <div className="show-addaccount-container">
                  <div className="plan-header-right-lower">
                    <h5 className="signup-button-wrapper-text">
                      Add additional accounts
                    </h5>
                    <p className="signup-accounts-info">
                      User profiles will be setup later
                    </p>
                  </div>
                  <div className="signup-select-wrapper">
                    <div className="signup-select-box">
                      <select
                        id="accountNo"
                        className={`form-select`}
                        value={numberOfAccountsToAdd}
                        name={"addAccountsSelect"}
                        onChange={(e) =>
                          handleChangeAccountSelect(e, "addAccountsSelect")
                        }
                      >
                        <option
                          id="ddlProducts"
                          className={`select-option`}
                          value=""
                        ></option>
                        {selectAdditionalAccountValues.map((item, i) => (
                          <option
                            id="ddlProducts"
                            className={`select-option`}
                            key={`item${i}`}
                          >
                            {item}
                          </option>
                        ))}
                      </select>
                    </div>
                  </div>
                  <div className="details-button-box">
                    <Button
                      className="secondary-button back-button"
                      onClick={handleCancelAdd}
                      labelText="Cancel"
                    />
                    <div className="upload-button-box">
                      <Button
                        className="p-2 mr-2 primary-button signup-proceed-btn"
                        onClick={handleAdd}
                        labelText="Add And Proceed To Payment"
                      />
                    </div>
                  </div>
                </div>
              </div>
            ) : (
              <></>
            )}
            <div className="signup-button-box">
              {!showAddAccount ? (
                <>
                  {showAddAccountBtn ? (
                    <Button
                      className="secondary-button cancel-add-account-btn"
                      type="button"
                      size="lg"
                      onClick={handleAddAccounts}
                      disabled={isBusy}
                      labelText="Add Account(s)"
                      style={{ marginTight: "12px;" }}
                    />
                  ) : (
                    <></>
                  )}

                  <Button
                    className="primary-button signup-proceed"
                    type="button"
                    size="lg"
                    onClick={handleProceedToPayment}
                    disabled={isBusy}
                    labelText="Proceed to Payment"
                  />
                </>
              ) : (
                <></>
              )}
            </div>
          </div>
        </div>
      ) : (
        <></>
      )}
      {showPaymentModal ? (
        <PaymentModal
          key="modal-one-xc"
          paymentData={paymentData}
          paymentfields={paymentfields}
          setShowPaymentModal={setShowPaymentModal}
          handleChangePaymentInput={handleChangePaymentInput}
          handleSignup={handleSignup}
          notice={notice}
          setNotice={setNotice}
          selectedPlan={selectedPlan}
          isAnnual={isAnnual === 1 ? true : false}
          numberOfAccountsToAdd={numberOfAccountsToAdd}
          fieldsChunkSize={2}
        />
      ) : (
        <></>
      )}
    </div>
  );
};

export default SignupPage;

/*

    
    const userDataValues = {
      barNumber: "232323",
      city: "broolyn",
      email: "j@s.com",
      firm: "asdf",
      firstName: "ghghg",
      lastName: "hhhhh",
      password: "123344556",
      practiceArea: "dfdfdf",
      state: "New York",
      streetAddress: "123 Main",
      telephone: "(313) 555-5555",
      zipCode: "12345",
    };
    

*/
