import {
  useCallback,
  useEffect,
  useMemo,
  useState
} from "react";

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

import {
  getFormProgress
} from "../services/publicPortalService";

/* =========================================================
   STAFF FORM STEPS
   ========================================================= */

const formSteps = [
  {
    key:
      "personal_details",

    path:
      "/staff/form/personal-details",

    label:
      "Personal Details",

    order:
      1
  },

  {
    key:
      "employment_details",

    path:
      "/staff/form/employment-details",

    label:
      "Employment Details",

    order:
      2
  },

  {
    key:
      "next_of_kin",

    path:
      "/staff/form/next-of-kin",

    label:
      "Next of Kin",

    order:
      3
  },

  {
    key:
      "dependents",

    path:
      "/staff/form/dependents",

    label:
      "Dependents",

    order:
      4
  },

  {
    key:
      "emergency_contact",

    path:
      "/staff/form/emergency-contact",

    label:
      "Emergency Contact",

    order:
      5
  },

  {
    key:
      "qualifications",

    path:
      "/staff/form/qualifications",

    label:
      "Qualifications",

    order:
      6
  },

  {
    key:
      "documents",

    path:
      "/staff/form/documents",

    label:
      "Supporting Documents",

    order:
      7
  },

  {
    key:
      "declaration",

    path:
      "/staff/form/declaration",

    label:
      "Declaration",

    order:
      8
  }
];

/* =========================================================
   DEFAULT PROGRESS
   ========================================================= */

const initialProgress = {
  submission_reference: "",
  submission_status: "draft",
  editable: true,
  completed_sections: 0,
  total_sections:
    formSteps.length,
  percentage: 0,
  sections: []
};

/* =========================================================
   STATUS LABEL
   ========================================================= */

const formatSectionStatus = (
  status
) => {
  const statusLabels = {
    not_started:
      "Not started",

    in_progress:
      "In progress",

    completed:
      "Completed"
  };

  return (
    statusLabels[status] ||
    "Not started"
  );
};

/* =========================================================
   COMPONENT
   ========================================================= */

const StaffFormLayout = () => {
  const location =
    useLocation();

  const navigate =
    useNavigate();

  const [
    progress,
    setProgress
  ] = useState(
    initialProgress
  );

  const [
    progressLoading,
    setProgressLoading
  ] = useState(true);

  const [
    progressError,
    setProgressError
  ] = useState("");

  /* =========================================================
     CURRENT ROUTE STEP
     ========================================================= */

  const currentStepIndex =
    useMemo(
      () => {
        const matchedIndex =
          formSteps.findIndex(
            (
              step
            ) =>
              location.pathname.startsWith(
                step.path
              )
          );

        return matchedIndex >= 0
          ? matchedIndex
          : 0;
      },
      [
        location.pathname
      ]
    );

  const currentStep =
    formSteps[
      currentStepIndex
    ];

  /* =========================================================
     LOAD DATABASE PROGRESS
     ========================================================= */

  const loadProgress =
    useCallback(
      async ({
        showLoading = false
      } = {}) => {
        const submissionToken =
          sessionStorage.getItem(
            "staffSubmissionToken"
          );

        if (!submissionToken) {
          navigate(
            "/staff/identify",
            {
              replace: true
            }
          );

          return null;
        }

        try {
          if (showLoading) {
            setProgressLoading(
              true
            );
          }

          setProgressError("");

          const result =
            await getFormProgress();

          const progressData =
            result?.data || {};

          const normalizedProgress = {
            ...initialProgress,
            ...progressData,

            sections:
              Array.isArray(
                progressData.sections
              )
                ? progressData.sections
                : []
          };

          setProgress(
            normalizedProgress
          );

          return normalizedProgress;
        } catch (
          requestError
        ) {
          if (
            requestError.response
              ?.status === 401
          ) {
            navigate(
              "/staff/identify",
              {
                replace: true
              }
            );

            return null;
          }

          setProgressError(
            requestError.response?.data
              ?.message ||
              requestError.message ||
              "Unable to load form progress."
          );

          return null;
        } finally {
          if (showLoading) {
            setProgressLoading(
              false
            );
          }
        }
      },
      [
        navigate
      ]
    );

  useEffect(
    () => {
      loadProgress({
        showLoading: true
      });
    },
    [
      loadProgress
    ]
  );

  /* =========================================================
     REFRESH PROGRESS

     Child form pages call this after saving.
     ========================================================= */

  const refreshProgress =
    useCallback(
      async () => {
        return loadProgress({
          showLoading: false
        });
      },
      [
        loadProgress
      ]
    );

  /* =========================================================
     SECTION STATUS MAP
     ========================================================= */

  const sectionStatusMap =
    useMemo(
      () => {
        return new Map(
          progress.sections.map(
            (
              section
            ) => [
              section.section_key,
              section.status
            ]
          )
        );
      },
      [
        progress.sections
      ]
    );

  const completedSections =
    Number(
      progress.completed_sections
    ) || 0;

  const totalSections =
    Number(
      progress.total_sections
    ) || formSteps.length;

  const percentage =
    Number.isFinite(
      Number(
        progress.percentage
      )
    )
      ? Math.max(
          0,
          Math.min(
            100,
            Number(
              progress.percentage
            )
          )
        )
      : 0;

  /* =========================================================
     NAVIGATION
     ========================================================= */

  const handleStepNavigation =
    (
      stepPath
    ) => {
      if (
        location.pathname ===
        stepPath
      ) {
        return;
      }

      navigate(
        stepPath
      );
    };

  const handleReturnToWelcome =
    () => {
      navigate(
        "/staff/welcome"
      );
    };

  /* =========================================================
     OUTLET CONTEXT
     ========================================================= */

  const outletContext =
    useMemo(
      () => ({
        refreshProgress,

        progress,

        currentStep:
          currentStepIndex + 1,

        currentStepIndex,

        totalSteps:
          formSteps.length,

        currentStepDetails:
          currentStep,

        formSteps
      }),
      [
        refreshProgress,
        progress,
        currentStepIndex,
        currentStep
      ]
    );

  /* =========================================================
     RENDER
     ========================================================= */

  return (
    <div className="staff-form-shell">
      {/* =====================================================
          SIDEBAR
          ===================================================== */}

      <aside className="staff-form-sidebar">
        <div className="form-progress-heading">
          <span>
            Form progress
          </span>

          <strong>
            {progressLoading
              ? "Loading progress..."
              : `${completedSections} of ${totalSections} sections completed`}
          </strong>
        </div>

        <div
          className="progress-track"
          role="progressbar"
          aria-label="Staff form completion"
          aria-valuemin="0"
          aria-valuemax="100"
          aria-valuenow={
            percentage
          }
        >
          <div
            className="progress-track__bar"
            style={{
              width:
                `${percentage}%`
            }}
          />
        </div>

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

        <nav
          className="form-section-navigation"
          aria-label="Staff form sections"
        >
          {formSteps.map(
            (
              step,
              index
            ) => {
              const isActive =
                index ===
                currentStepIndex;

              const sectionStatus =
                sectionStatusMap.get(
                  step.key
                ) ||
                "not_started";

              const isCompleted =
                sectionStatus ===
                "completed";

              return (
                <button
                  type="button"
                  key={
                    step.key
                  }
                  className={[
                    "form-section-link",

                    isActive
                      ? "form-section-link--active"
                      : "",

                    isCompleted
                      ? "form-section-link--completed"
                      : ""
                  ]
                    .filter(
                      Boolean
                    )
                    .join(" ")}
                  onClick={() =>
                    handleStepNavigation(
                      step.path
                    )
                  }
                  aria-current={
                    isActive
                      ? "step"
                      : undefined
                  }
                >
                  <span className="form-section-link__number">
                    {isCompleted
                      ? "✓"
                      : step.order}
                  </span>

                  <span className="form-section-link__content">
                    <strong className="form-section-link__label">
                      {step.label}
                    </strong>

                    <small
                      className={`form-section-link__status form-section-link__status--${sectionStatus}`}
                    >
                      {formatSectionStatus(
                        sectionStatus
                      )}
                    </small>
                  </span>
                </button>
              );
            }
          )}
        </nav>

        <div className="staff-form-sidebar__actions">
          <button
            type="button"
            className="secondary-button"
            onClick={
              handleReturnToWelcome
            }
          >
            Back to welcome
          </button>
        </div>
      </aside>

      {/* =====================================================
          ACTIVE FORM PAGE
          ===================================================== */}

      <main className="staff-form-content">
        <Outlet
          context={
            outletContext
          }
        />
      </main>
    </div>
  );
};

export default StaffFormLayout;