// File Path: monorepo/web/frontend/src/pages/Admin/TaskItem/AssignFacilitatorOrSpeaker/Step5Page.jsx

import React, { useState, useEffect, useRef } from "react";
import { useNavigate, useParams } from "react-router";
import {
  UIXThemeProvider,
  StaffWizardFormStep,
  FormSection,
  InfoField,
  Alert,
} from "../../../../components/UIX";
import {
  UserGroupIcon,
  CheckCircleIcon,
  ExclamationTriangleIcon,
} from "@heroicons/react/24/outline";
import { useTaskManager } from "../../../../services/Services";

function AdminTaskItemAssignFacilitatorOrSpeakerStep5Page() {
  const navigate = useNavigate();
  const { id } = useParams();
  const taskManager = useTaskManager();

  const [wizardData, setWizardData] = useState({});
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [errors, setErrors] = useState({});

  // Use ref to prevent double submission in React StrictMode or accidental double-clicks
  const submissionInProgress = useRef(false);
  const errorRef = useRef(null);

  const wizardSteps = [
    { title: "Event Details" },
    { title: "Select Person" },
    { title: "Acceptance Status" },
    { title: "Review & Submit" },
  ];

  // Load all saved data from sessionStorage
  useEffect(() => {
    const role = sessionStorage.getItem(`assign_facilitator_speaker_${id}_role`);
    const personId = sessionStorage.getItem(`assign_facilitator_speaker_${id}_person_id`);
    const personName = sessionStorage.getItem(`assign_facilitator_speaker_${id}_person_name`);
    const hours = sessionStorage.getItem(`assign_facilitator_speaker_${id}_hours`);
    const accepted = sessionStorage.getItem(`assign_facilitator_speaker_${id}_accepted`);
    const method = sessionStorage.getItem(`assign_facilitator_speaker_${id}_acceptance_method`);
    const reason = sessionStorage.getItem(`assign_facilitator_speaker_${id}_decline_reason`);

    if (!role || !personId || !hours || !accepted) {
      // Missing required data, redirect back to step 1
      navigate(`/admin/task/${id}/assign-facilitator-speaker/step-1`);
      return;
    }

    setWizardData({
      role,
      personId,
      personName: personName || "Unknown",
      hours,
      accepted,
      acceptanceMethod: method || "",
      declineReason: reason || "",
    });
  }, [id, navigate]);

  // Scroll to error when it appears
  useEffect(() => {
    if (errors.message && errorRef.current) {
      errorRef.current.scrollIntoView({ behavior: "smooth", block: "center" });
    }
  }, [errors.message]);

  // Format labels for display
  const getRoleLabel = () => {
    return wizardData.role === "facilitator" ? "Facilitator" : "Speaker";
  };

  const getAcceptanceMethodLabel = (value) => {
    const labels = {
      "pre-approval": "Pre-approval",
      "telephone": "Telephone",
      "email": "Email",
      "text": "Text",
    };
    return labels[value] || value;
  };

  const getDeclineReasonLabel = (value) => {
    const labels = {
      "unavailable": "Unavailable",
      "does-not-want-client": "Does not want this client",
      "unable-to-travel": "Unable to travel",
      "event-not-suitable": "Type of event not suitable",
      "pay-dispute": "Pay dispute",
      "on-vacation": "On vacation",
      "illness-or-injury": "Illness or injury",
    };
    return labels[value] || value;
  };

  // Map string values to numeric constants for API
  const getRoleTypeValue = (role) => {
    return role === "facilitator" ? 1 : 2; // 1=Facilitator, 2=Speaker
  };

  const getAcceptanceMethodValue = (method) => {
    const mapping = {
      "pre-approval": 1,
      "telephone": 2,
      "email": 3,
      "text": 4,
    };
    return mapping[method] || 0;
  };

  const getRejectionReasonValue = (reason) => {
    const mapping = {
      "unavailable": 1,
      "does-not-want-client": 2,
      "unable-to-travel": 3,
      "event-not-suitable": 4,
      "pay-dispute": 5,
      "on-vacation": 6,
      "illness-or-injury": 7,
    };
    return mapping[reason] || 0;
  };

  const onUnauthorized = () => {
    navigate("/login?unauthorized=true");
  };

  const handleSubmit = async () => {
    // Prevent double submission
    if (submissionInProgress.current) {
      if (import.meta.env.DEV) {
        console.log("Step5Page: Submission already in progress, ignoring duplicate request");
      }
      return;
    }

    // Mark submission as in progress
    submissionInProgress.current = true;
    setIsSubmitting(true);
    setErrors({});

    try {
      const roleType = getRoleTypeValue(wizardData.role);
      const hasAccepted = wizardData.accepted === "yes";

      // Build payload for API
      const payload = {
        taskItemId: id,
        roleType: roleType,
        estimatedHours: parseFloat(wizardData.hours),
        hasAccepted: hasAccepted,
      };

      // Add facilitator or speaker ID based on role
      if (roleType === 1) {
        payload.facilitatorId = wizardData.personId;
      } else {
        payload.speakerId = wizardData.personId;
      }

      // Add acceptance method or rejection reason based on acceptance status
      if (hasAccepted) {
        const acceptanceMethodValue = getAcceptanceMethodValue(wizardData.acceptanceMethod);
        if (acceptanceMethodValue > 0) {
          payload.acceptanceMethod = acceptanceMethodValue;
        }
      } else {
        const rejectionReasonValue = getRejectionReasonValue(wizardData.declineReason);
        if (rejectionReasonValue > 0) {
          payload.rejectionReason = rejectionReasonValue;
        }
      }

      if (import.meta.env.DEV) {
        console.log("Step5Page: Submitting assignment with payload:", payload);
      }
      if (import.meta.env.DEV) {
        console.log("Step5Page: Submission timestamp:", new Date().toISOString());
      }

      // Call API to submit assignment
      const result = await taskManager.assignFacilitatorOrSpeaker(payload, onUnauthorized);

      if (import.meta.env.DEV) {
        console.log("Step5Page: Assignment submitted successfully:", result);
      }
      if (import.meta.env.DEV) {
        console.log("Step5Page: Success timestamp:", new Date().toISOString());
      }

      // Clear sessionStorage after successful submission
      sessionStorage.removeItem(`assign_facilitator_speaker_${id}_role`);
      sessionStorage.removeItem(`assign_facilitator_speaker_${id}_person_id`);
      sessionStorage.removeItem(`assign_facilitator_speaker_${id}_person_name`);
      sessionStorage.removeItem(`assign_facilitator_speaker_${id}_hours`);
      sessionStorage.removeItem(`assign_facilitator_speaker_${id}_accepted`);
      sessionStorage.removeItem(`assign_facilitator_speaker_${id}_acceptance_method`);
      sessionStorage.removeItem(`assign_facilitator_speaker_${id}_decline_reason`);

      // Navigate back to tasks list with success message
      navigate("/admin/tasks", {
        state: {
          successMessage: `${getRoleLabel()} assignment has been submitted successfully!`,
        },
      });
    } catch (error) {
      if (import.meta.env.DEV) {
        console.error("Step5Page: Error submitting assignment:", error);
      }

      // Helper function to format field names
      const formatFieldName = (fieldName) => {
        return fieldName
          .replace(/_/g, " ")
          .replace(/([A-Z])/g, " $1")
          .toLowerCase()
          .replace(/^./, (str) => str.toUpperCase());
      };

      // Enhanced error handling with field-specific messages
      if (typeof error === "object" && error !== null) {
        // Customer-related validation errors
        if (error.customerEmail) {
          setErrors({
            message: `Missing Customer Email\n\nThe customer does not have an email address on file, which is required.\n\nPlease update the customer's profile to add an email address.`,
          });
        } else if (error.customerPhone) {
          setErrors({
            message: `Missing Customer Phone\n\nThe customer does not have a phone number on file, which is required.\n\nPlease update the customer's profile to add a phone number.`,
          });
        } else if (error.customerName) {
          setErrors({
            message: `Missing Customer Name\n\nThe customer is missing required name information.\n\nPlease ensure the customer has complete profile information.`,
          });
        } else if (error.customerOrganizationName || error.customerOrganizationShortName) {
          setErrors({
            message: `Missing Organization Information\n\nThe customer's organization is missing required information.\n\nPlease contact your system administrator to update the organization details.`,
          });
        } else if (error.customerDivisionName || error.customerDivisionShortName) {
          setErrors({
            message: `Missing Division Information\n\nThe customer's division is missing required information.\n\nPlease contact your system administrator to update the division details.`,
          });
        }
        // Speaker/Facilitator validation errors
        else if (error.speakerEmail || error.facilitatorEmail) {
          setErrors({
            message: `Missing Contact Email\n\nThe selected speaker/facilitator does not have an email address on file, which is required.\n\nPlease update their profile to add an email address.`,
          });
        } else if (error.speakerPhone || error.facilitatorPhone) {
          setErrors({
            message: `Missing Contact Phone\n\nThe selected speaker/facilitator does not have a phone number on file, which is required.\n\nPlease update their profile to add a phone number.`,
          });
        }
        // Event-related validation errors
        else if (error.eventName || error.eventDescription) {
          setErrors({
            message: `Invalid Event Information\n\nThe event is missing required information.\n\nPlease contact your system administrator to update the event details.`,
          });
        } else if (error.eventCategoryName) {
          setErrors({
            message: `Missing Event Category\n\nThe event category information is missing or invalid.\n\nPlease contact your system administrator.`,
          });
        }
        // General error handling
        else if (error.message) {
          setErrors({
            message: `Error\n\n${error.message}\n\nPlease try again.`,
          });
        } else {
          // Display all error fields if present
          const errorFields = Object.keys(error);
          if (errorFields.length > 0) {
            const errorMessages = errorFields
              .map((field) => `• ${formatFieldName(field)}: ${error[field]}`)
              .join("\n");
            setErrors({
              message: `Validation Errors\n\nThe following fields have errors:\n\n${errorMessages}\n\nPlease correct these errors and try again.`,
            });
          } else {
            setErrors({
              message: "Unexpected Error\n\nAn unexpected error occurred.\n\nPlease try again. If the problem persists, contact support.",
            });
          }
        }
      } else if (error && error.message) {
        setErrors({
          message: `Error\n\n${error.message}\n\nPlease try again.`,
        });
      } else {
        setErrors({
          message: "Unexpected Error\n\nPlease try again. If the problem persists, contact support.",
        });
      }
    } finally {
      setIsSubmitting(false);
      // Reset submission flag to allow retry on error
      submissionInProgress.current = false;
    }
  };

  const handleBack = () => {
    navigate(`/admin/task/${id}/assign-facilitator-speaker/step-4`);
  };

  const handleCancel = () => {
    // Clear all sessionStorage on cancel
    sessionStorage.removeItem(`assign_facilitator_speaker_${id}_role`);
    sessionStorage.removeItem(`assign_facilitator_speaker_${id}_person_id`);
    sessionStorage.removeItem(`assign_facilitator_speaker_${id}_person_name`);
    sessionStorage.removeItem(`assign_facilitator_speaker_${id}_hours`);
    sessionStorage.removeItem(`assign_facilitator_speaker_${id}_accepted`);
    sessionStorage.removeItem(`assign_facilitator_speaker_${id}_acceptance_method`);
    sessionStorage.removeItem(`assign_facilitator_speaker_${id}_decline_reason`);
    navigate("/admin/tasks");
  };

  return (
    <UIXThemeProvider>
      <StaffWizardFormStep
        wizardSteps={wizardSteps}
        currentStep={4}
        wizardTitle="Assign Facilitator or Speaker"
        wizardIcon={UserGroupIcon}
        stepTitle="Review & Submit"
        stepSubtitle="Review all information and submit the assignment"
        stepIcon={CheckCircleIcon}
        errors={errors}
        isLoading={isSubmitting}
        showFormCard={true}
        actionLayout="between"
        contentMaxWidth="4xl"
        showActions={true}
        actions={[
          {
            label: isSubmitting ? "Submitting..." : "Submit Assignment",
            variant: "primary",
            icon: CheckCircleIcon,
            onClick: handleSubmit,
            disabled: isSubmitting,
          },
        ]}
        onBack={handleBack}
        onCancel={handleCancel}
        backLabel="Back"
        cancelLabel="Cancel"
      >
        {/* Assignment Summary Section */}
        <FormSection
          title="Assignment Summary"
          description="Review the assignment details before submitting"
          className="mb-6"
        >
          <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
            <InfoField
              label="Role"
              value={getRoleLabel()}
            />
            <InfoField
              label="Task ID"
              value={id}
            />
          </div>

          <div className="mt-4">
            <InfoField
              label={`Selected ${getRoleLabel()}`}
              value={wizardData.personName}
            />
          </div>

          <div className="mt-4 text-xs text-gray-500">
            Person ID: {wizardData.personId}
          </div>

          <div className="mt-4">
            <InfoField
              label="Estimated Hours"
              value={`${wizardData.hours} hours`}
            />
          </div>
        </FormSection>

        {/* Acceptance Status Section */}
        <FormSection
          title="Acceptance Status"
          description="Assignment acceptance or decline information"
          className="mb-6"
        >
          <div className="mb-4">
            <InfoField
              label="Has Accepted"
              value={wizardData.accepted === "yes" ? "Yes" : "No"}
            />
          </div>

          {wizardData.accepted === "yes" && wizardData.acceptanceMethod && (
            <div className="mt-4">
              <InfoField
                label="Acceptance Method"
                value={getAcceptanceMethodLabel(wizardData.acceptanceMethod)}
              />
            </div>
          )}

          {wizardData.accepted === "no" && wizardData.declineReason && (
            <div className="mt-4">
              <InfoField
                label="Decline Reason"
                value={getDeclineReasonLabel(wizardData.declineReason)}
              />
            </div>
          )}
        </FormSection>

        {/* Error Alert */}
        {errors.message && (
          <div ref={errorRef} className="mb-6">
            <Alert variant="error" icon={ExclamationTriangleIcon}>
              <p className="font-semibold mb-2">Error</p>
              <div className="whitespace-pre-wrap">{errors.message}</div>
            </Alert>
          </div>
        )}

        {/* Status Alert */}
        <Alert
          variant={wizardData.accepted === "yes" ? "success" : "warning"}
          icon={ExclamationTriangleIcon}
        >
          <p className="font-semibold mb-2">
            {wizardData.accepted === "yes" ? "Ready to Submit" : "Declined Assignment"}
          </p>
          <p>
            {wizardData.accepted === "yes"
              ? `Click "Submit Assignment" to finalize the assignment of this ${getRoleLabel().toLowerCase()} to the event.`
              : "This assignment was declined. Submitting will record this information for tracking purposes."}
          </p>
        </Alert>
      </StaffWizardFormStep>
    </UIXThemeProvider>
  );
}

export default AdminTaskItemAssignFacilitatorOrSpeakerStep5Page;
