import {
  useEffect,
  useState
} from "react";

import {
  useNavigate,
  useOutletContext
} from "react-router-dom";

import {
  getFormLookups,
  getPersonalDetails,
  savePersonalDetails
} from "../../../services/publicPortalService";

const initialFormData = {
  surname: "",
  first_name: "",
  middle_name: "",
  gender: "",
  marital_status: "",
  nationality:
    "Ghanaian",
  ghana_card_number: "",
  ssnit_number: "",
  home_town: "",
  home_region_id: "",
  residential_address: "",
  gps_address: "",
  primary_mobile: "",
  secondary_mobile: "",
  official_email: "",
  personal_email: ""
};

const PersonalDetails = () => {
  const navigate =
    useNavigate();

  const {
    refreshProgress
  } = useOutletContext();

  const [formData, setFormData] =
    useState(
      initialFormData
    );

  const [lookups, setLookups] =
    useState({
      regions: [],
      genders: [],
      marital_statuses: []
    });

  const [loading, setLoading] =
    useState(true);

  const [saving, setSaving] =
    useState(false);

  const [error, setError] =
    useState("");

  const [fieldErrors, setFieldErrors] =
    useState({});

  const [successMessage, setSuccessMessage] =
    useState("");

  const [editable, setEditable] =
    useState(true);

  useEffect(() => {
    const loadPage = async () => {
      try {
        setLoading(true);
        setError("");

        const [
          lookupResult,
          personalResult
        ] = await Promise.all([
          getFormLookups(),
          getPersonalDetails()
        ]);

        setLookups(
          lookupResult.data
        );

        setEditable(
          personalResult.data.editable
        );

        const details =
          personalResult.data
            .personal_details;

        setFormData({
          surname:
            details.surname || "",

          first_name:
            details.first_name || "",

          middle_name:
            details.middle_name || "",

          gender:
            details.gender || "",

          marital_status:
            details.marital_status || "",

          nationality:
            details.nationality ||
            "Ghanaian",

          ghana_card_number:
            details.ghana_card_number ||
            "",

          ssnit_number:
            details.ssnit_number || "",

          home_town:
            details.home_town || "",

          home_region_id:
            details.home_region_id
              ? String(
                  details.home_region_id
                )
              : "",

          residential_address:
            details
              .residential_address ||
            "",

          gps_address:
            details.gps_address || "",

          primary_mobile:
            details.primary_mobile || "",

          secondary_mobile:
            details.secondary_mobile ||
            "",

          official_email:
            details.official_email || "",

          personal_email:
            details.personal_email || ""
        });
      } catch (requestError) {
        setError(
          requestError.response?.data
            ?.message ||
          requestError.message ||
          "Unable to load the personal details form."
        );
      } finally {
        setLoading(false);
      }
    };

    loadPage();
  }, []);

  const handleChange = (
    event
  ) => {
    const {
      name,
      value
    } = event.target;

    let normalizedValue =
      value;

    if (
      name ===
      "ghana_card_number"
    ) {
      normalizedValue =
        value.toUpperCase();
    }

    if (
      name ===
      "gps_address"
    ) {
      normalizedValue =
        value.toUpperCase();
    }

    setFormData(
      (currentData) => ({
        ...currentData,
        [name]:
          normalizedValue
      })
    );

    if (fieldErrors[name]) {
      setFieldErrors(
        (currentErrors) => {
          const nextErrors = {
            ...currentErrors
          };

          delete nextErrors[name];

          return nextErrors;
        }
      );
    }

    if (error) {
      setError("");
    }

    if (successMessage) {
      setSuccessMessage("");
    }
  };

  const submitPersonalDetails =
    async ({
      markCompleted
    }) => {
      try {
        setSaving(true);
        setError("");
        setFieldErrors({});
        setSuccessMessage("");

        const result =
          await savePersonalDetails({
            ...formData,

            home_region_id:
              formData.home_region_id
                ? Number(
                    formData
                      .home_region_id
                  )
                : null,

            mark_completed:
              markCompleted
          });

        setSuccessMessage(
          result.message
        );

        await refreshProgress();

        if (markCompleted) {
          navigate(
            "/staff/form/employment-details"
          );
        }
      } catch (requestError) {
        const responseData =
          requestError.response?.data;

        setError(
          responseData?.message ||
          requestError.message ||
          "Unable to save the personal details."
        );

        setFieldErrors(
          responseData?.errors || {}
        );
      } finally {
        setSaving(false);
      }
    };

  const handleSaveDraft = (
    event
  ) => {
    event.preventDefault();

    submitPersonalDetails({
      markCompleted: false
    });
  };

  const handleSaveAndContinue = (
    event
  ) => {
    event.preventDefault();

    submitPersonalDetails({
      markCompleted: true
    });
  };

  if (loading) {
    return (
      <div className="form-page-card">
        <div className="information-banner">
          Loading personal details...
        </div>
      </div>
    );
  }

  return (
    <div className="form-page-card">
      <div className="form-page-heading">
        <div>
          <span>
            Section A
          </span>

          <h2>
            Personal Details
          </h2>

          <p>
            Review the information already
            available and correct any details
            that have changed.
          </p>
        </div>

        <span className="form-step-badge">
          Step 1 of 8
        </span>
      </div>

      {!editable && (
        <div className="form-alert form-alert--error">
          This submission is no longer
          editable.
        </div>
      )}

      {error && (
        <div
          className="form-alert form-alert--error"
          role="alert"
        >
          {error}
        </div>
      )}

      {successMessage && (
        <div className="form-alert form-alert--success">
          {successMessage}
        </div>
      )}

      <form className="staff-record-form">
        <div className="form-grid form-grid--three">
          <div className="form-group">
            <label htmlFor="surname">
              Surname
              <span className="required-mark">
                *
              </span>
            </label>

            <input
              id="surname"
              name="surname"
              type="text"
              value={formData.surname}
              onChange={handleChange}
              disabled={
                saving ||
                !editable
              }
              maxLength={100}
            />

            {fieldErrors.surname && (
              <small className="field-error">
                {fieldErrors.surname}
              </small>
            )}
          </div>

          <div className="form-group">
            <label htmlFor="first_name">
              First name
              <span className="required-mark">
                *
              </span>
            </label>

            <input
              id="first_name"
              name="first_name"
              type="text"
              value={
                formData.first_name
              }
              onChange={handleChange}
              disabled={
                saving ||
                !editable
              }
              maxLength={100}
            />

            {fieldErrors.first_name && (
              <small className="field-error">
                {fieldErrors.first_name}
              </small>
            )}
          </div>

          <div className="form-group">
            <label htmlFor="middle_name">
              Other name(s)
            </label>

            <input
              id="middle_name"
              name="middle_name"
              type="text"
              value={
                formData.middle_name
              }
              onChange={handleChange}
              disabled={
                saving ||
                !editable
              }
              maxLength={100}
            />
          </div>
        </div>

        <div className="form-grid form-grid--two">
          <div className="form-group">
            <label htmlFor="gender">
              Gender
              <span className="required-mark">
                *
              </span>
            </label>

            <select
              id="gender"
              name="gender"
              value={formData.gender}
              onChange={handleChange}
              disabled={
                saving ||
                !editable
              }
            >
              <option value="">
                Select gender
              </option>

              {lookups.genders.map(
                (option) => (
                  <option
                    key={option.value}
                    value={option.value}
                  >
                    {option.label}
                  </option>
                )
              )}
            </select>

            {fieldErrors.gender && (
              <small className="field-error">
                {fieldErrors.gender}
              </small>
            )}
          </div>

          <div className="form-group">
            <label htmlFor="marital_status">
              Marital status
              <span className="required-mark">
                *
              </span>
            </label>

            <select
              id="marital_status"
              name="marital_status"
              value={
                formData.marital_status
              }
              onChange={handleChange}
              disabled={
                saving ||
                !editable
              }
            >
              <option value="">
                Select marital status
              </option>

              {lookups
                .marital_statuses
                .map(
                  (option) => (
                    <option
                      key={option.value}
                      value={option.value}
                    >
                      {option.label}
                    </option>
                  )
                )}
            </select>

            {fieldErrors
              .marital_status && (
              <small className="field-error">
                {
                  fieldErrors
                    .marital_status
                }
              </small>
            )}
          </div>
        </div>

        <div className="form-grid form-grid--two">
          <div className="form-group">
            <label htmlFor="nationality">
              Nationality
              <span className="required-mark">
                *
              </span>
            </label>

            <input
              id="nationality"
              name="nationality"
              type="text"
              value={
                formData.nationality
              }
              onChange={handleChange}
              disabled={
                saving ||
                !editable
              }
              maxLength={100}
            />

            {fieldErrors.nationality && (
              <small className="field-error">
                {
                  fieldErrors.nationality
                }
              </small>
            )}
          </div>

          <div className="form-group">
            <label htmlFor="ghana_card_number">
              Ghana Card number
              <span className="required-mark">
                *
              </span>
            </label>

            <input
              id="ghana_card_number"
              name="ghana_card_number"
              type="text"
              value={
                formData
                  .ghana_card_number
              }
              onChange={handleChange}
              placeholder="GHA-123456789-0"
              disabled={
                saving ||
                !editable
              }
              maxLength={30}
            />

            {fieldErrors
              .ghana_card_number && (
              <small className="field-error">
                {
                  fieldErrors
                    .ghana_card_number
                }
              </small>
            )}
          </div>
        </div>

        <div className="form-grid form-grid--two">
          <div className="form-group">
            <label htmlFor="ssnit_number">
              SSNIT number
            </label>

            <input
              id="ssnit_number"
              name="ssnit_number"
              type="text"
              value={
                formData.ssnit_number
              }
              onChange={handleChange}
              disabled={
                saving ||
                !editable
              }
              maxLength={30}
            />
          </div>

          <div className="form-group">
            <label htmlFor="home_town">
              Home town
              <span className="required-mark">
                *
              </span>
            </label>

            <input
              id="home_town"
              name="home_town"
              type="text"
              value={
                formData.home_town
              }
              onChange={handleChange}
              disabled={
                saving ||
                !editable
              }
              maxLength={150}
            />

            {fieldErrors.home_town && (
              <small className="field-error">
                {fieldErrors.home_town}
              </small>
            )}
          </div>
        </div>

        <div className="form-group">
          <label htmlFor="home_region_id">
            Home region
            <span className="required-mark">
              *
            </span>
          </label>

          <select
            id="home_region_id"
            name="home_region_id"
            value={
              formData.home_region_id
            }
            onChange={handleChange}
            disabled={
              saving ||
              !editable
            }
          >
            <option value="">
              Select region
            </option>

            {lookups.regions.map(
              (region) => (
                <option
                  key={region.id}
                  value={region.id}
                >
                  {region.name}
                </option>
              )
            )}
          </select>

          {fieldErrors.home_region_id && (
            <small className="field-error">
              {
                fieldErrors
                  .home_region_id
              }
            </small>
          )}
        </div>

        <div className="form-group">
          <label htmlFor="residential_address">
            Residential address
            <span className="required-mark">
              *
            </span>
          </label>

          <textarea
            id="residential_address"
            name="residential_address"
            value={
              formData
                .residential_address
            }
            onChange={handleChange}
            rows={4}
            disabled={
              saving ||
              !editable
            }
          />

          {fieldErrors
            .residential_address && (
            <small className="field-error">
              {
                fieldErrors
                  .residential_address
              }
            </small>
          )}
        </div>

        <div className="form-grid form-grid--two">
          <div className="form-group">
            <label htmlFor="gps_address">
              GhanaPost GPS address
              <span className="required-mark">
                *
              </span>
            </label>

            <input
              id="gps_address"
              name="gps_address"
              type="text"
              value={
                formData.gps_address
              }
              onChange={handleChange}
              placeholder="GA-123-4567"
              disabled={
                saving ||
                !editable
              }
              maxLength={30}
            />

            {fieldErrors.gps_address && (
              <small className="field-error">
                {
                  fieldErrors.gps_address
                }
              </small>
            )}
          </div>

          <div className="form-group">
            <label htmlFor="primary_mobile">
              Primary mobile number
              <span className="required-mark">
                *
              </span>
            </label>

            <input
              id="primary_mobile"
              name="primary_mobile"
              type="tel"
              inputMode="tel"
              value={
                formData.primary_mobile
              }
              onChange={handleChange}
              placeholder="0240000000"
              disabled={
                saving ||
                !editable
              }
              maxLength={30}
            />

            {fieldErrors.primary_mobile && (
              <small className="field-error">
                {
                  fieldErrors.primary_mobile
                }
              </small>
            )}
          </div>
        </div>

        <div className="form-grid form-grid--two">
          <div className="form-group">
            <label htmlFor="secondary_mobile">
              Alternative mobile number
            </label>

            <input
              id="secondary_mobile"
              name="secondary_mobile"
              type="tel"
              inputMode="tel"
              value={
                formData.secondary_mobile
              }
              onChange={handleChange}
              disabled={
                saving ||
                !editable
              }
              maxLength={30}
            />

            {fieldErrors
              .secondary_mobile && (
              <small className="field-error">
                {
                  fieldErrors
                    .secondary_mobile
                }
              </small>
            )}
          </div>

          <div className="form-group">
            <label htmlFor="official_email">
              Official email address
              <span className="required-mark">
                *
              </span>
            </label>

            <input
              id="official_email"
              name="official_email"
              type="email"
              value={
                formData.official_email
              }
              onChange={handleChange}
              disabled={
                saving ||
                !editable
              }
              maxLength={150}
            />

            {fieldErrors
              .official_email && (
              <small className="field-error">
                {
                  fieldErrors
                    .official_email
                }
              </small>
            )}
          </div>
        </div>

        <div className="form-group">
          <label htmlFor="personal_email">
            Personal email address
          </label>

          <input
            id="personal_email"
            name="personal_email"
            type="email"
            value={
              formData.personal_email
            }
            onChange={handleChange}
            disabled={
              saving ||
              !editable
            }
            maxLength={150}
          />

          {fieldErrors.personal_email && (
            <small className="field-error">
              {
                fieldErrors.personal_email
              }
            </small>
          )}
        </div>

        <div className="form-action-bar">
          <button
            type="button"
            className="secondary-button"
            onClick={
              handleSaveDraft
            }
            disabled={
              saving ||
              !editable
            }
          >
            {saving
              ? "Saving..."
              : "Save draft"}
          </button>

          <button
            type="button"
            className="primary-button"
            onClick={
              handleSaveAndContinue
            }
            disabled={
              saving ||
              !editable
            }
          >
            {saving
              ? "Saving..."
              : "Save and continue"}
          </button>
        </div>
      </form>
    </div>
  );
};

export default PersonalDetails;