import React, { useState, useEffect } from "react";
import { ChevronLeft } from "lucide-react";
import { useDispatch, useSelector } from "react-redux";
import {
  updatePersonalDetails,
  updateEducationalDetails,
  updateFamilyDetails,
  updateLifestyleDetails,
  updatePartnerPreferences,
  submitForm,
} from "../redux/registrationFormSlice";
import PersonalDetailsForm from "./PersonalDetailsForm";
import EducationalDetailsForm from "./EducationalDetailsForm";
import FamilyDetailsForm from "./FamilyDetailsForm";
import LifestyleDetailsForm from "./LifestyleDetailsForm";
import PartnerPreferencesForm from "./PartnerPreferencesForm";
import PreviewScreen from "./PreviewScreen";
import { useLocation } from "react-router-dom";
import {
  useRegisterStep1,
  useRegisterStep2,
  useRegisterStep3,
  useRegisterStep4,
  useRegisterStep5,
} from "../hooks/useRegister";
import { setAccessToken } from "../api/axiosInstance";
import toast from "react-hot-toast";

const STEP_FIELD_ORDER = {
  1: [
    "name",
    "gender",
    "mobileNumber",
    "dob",
    "height",
    "weight",
    "maritalStatus",
    "religion",
    "profileFor",
    "caste",
    "subCaste",
    "gothram",
    "raasi",
    "star",
    "email",
    "password",
    "confirmPassword",
    "state",
    "city",
    "pincode",
    "profiles",
  ],
  2: [
    "fieldOfStudy",
    "qualification",
    "collegeName",
    "occupation",
    "organization",
    "employeeType",
    "income",
    "workLocation",
  ],
  3: [
    "fatherName",
    "fatherOccupation",
    "motherName",
    "motherOccupation",
    "brotherCount",
    "sisterCount",
    "familyStatus",
    "nativePlace",
  ],
  4: ["diets", "hobbies", "dob", "tob", "placeOfBirth"],
  5: [
    "ageRange",
    "castes",
    "subCastes",
    "occupations",
    "educations",
    "hobbies",
    "annualIncome",
    "states",
    "districts",
  ],
};

const STEP1_SERVER_FIELD_MAP = {
  name: "name",
  mobile: "mobileNumber",
  mobile_number: "mobileNumber",
  mobileNumber: "mobileNumber",
  phone: "mobileNumber",
  email: "email",
  gender: "gender",
  dob: "dob",
  height: "height",
  weight: "weight",
  marital_status: "maritalStatus",
  maritalStatus: "maritalStatus",
  religion: "religion",
  profile_for: "profileFor",
  profileFor: "profileFor",
  caste: "caste",
  sub_caste: "subCaste",
  subCaste: "subCaste",
  gothram: "gothram",
  raasi: "raasi",
  star: "star",
  state: "state",
  district: "city",
  city: "city",
  pincode: "pincode",
  password: "password",
  confirm_password: "confirmPassword",
  confirmPassword: "confirmPassword",
  profiles: "profiles",
  profile_images: "profiles",
};
const Stepper = ({ currentStep, onStepClick }) => {
  

  const steps = [
    { num: 1, label: "Personal" },
    { num: 2, label: "Educational" },
    { num: 3, label: "Family" },
    { num: 4, label: "Lifestyle" },
    { num: 5, label: "Partner" },
    { num: 6, label: "Preview" },
  ];

  return (
    <div className="flex items-center justify-between px-4 py-6">
      {steps.map((step, index) => (
        <React.Fragment key={step.num}>
          <div
            className="flex flex-col items-center cursor-pointer"
            onClick={() => onStepClick(step.num)}
          >
            <div
              className={`w-8 h-8 rounded-full flex items-center justify-center text-sm font-semibold ${
                currentStep >= step.num
                  ? "bg-red-600 text-white"
                  : "bg-gray-300 text-gray-600"
              }`}
            >
              {step.num}
            </div>
          </div>
          {index < steps.length - 1 && (
            <div
              className={`flex-1 h-0.5 mx-1 ${
                currentStep > step.num ? "bg-red-600" : "bg-gray-300"
              }`}
            />
          )}
        </React.Fragment>
      ))}
    </div>
  );
};

const StepperForm = () => {
  const dispatch = useDispatch();
 const location = useLocation();

  const personalDetails = useSelector(
    (state) => state.registerform.personalDetails
  );
  const educationalDetails = useSelector(
    (state) => state.registerform.educationalDetails
  );
  const familyDetails = useSelector((state) => state.registerform.familyDetails);
  const lifestyleDetails = useSelector(
    (state) => state.registerform.lifestyleDetails
  );
  const partnerPreferences = useSelector(
    (state) => state.registerform.partnerPreferences
  );

  const initialStep = location.state?.step || 1;

  const [currentStep, setCurrentStep] = useState(initialStep);
  const [errors, setErrors] = useState({});

  const registerStep1 = useRegisterStep1();
  const registerStep2 = useRegisterStep2();
  const registerStep3 = useRegisterStep3();
  const registerStep4 = useRegisterStep4();
  const registerStep5 = useRegisterStep5();

  const normalizeStep1Field = (key) => {
    if (!key) return key;
    const trimmed = String(key).trim();
    if (!trimmed) return trimmed;

    // Map backend profile_images errors (e.g., profile_images.0) to the profiles field
    if (trimmed.startsWith("profile_images")) {
      return "profiles";
    }

    return (
      STEP1_SERVER_FIELD_MAP[trimmed] ||
      STEP1_SERVER_FIELD_MAP[trimmed.toLowerCase()] ||
      trimmed
    );
  };

  const coerceErrorMessage = (value) => {
    if (Array.isArray(value)) {
      return value.filter(Boolean).join(" ");
    }
    if (typeof value === "string") return value;
    if (value && typeof value === "object") {
      return (
        value.message ||
        value.msg ||
        value.error ||
        value.detail ||
        ""
      );
    }
    if (value === null || value === undefined) return "";
    return String(value);
  };

  const mapServerErrors = (error) => {
    const data = error?.response?.data ?? error?.data ?? error;
    if (!data) return {};
    const payload = data.errors ?? data.error ?? data.data ?? data;

    if (typeof payload === "string") {
      return { _form: payload };
    }

    if (Array.isArray(payload)) {
      const out = {};
      payload.forEach((item) => {
        if (!item) return;
        if (typeof item === "string") {
          out._form = out._form ? `${out._form} ${item}` : item;
          return;
        }
        const key = item.field || item.name || item.param || item.key;
        const message =
          item.message || item.msg || item.error || item.detail || "";
        if (key) {
          out[normalizeStep1Field(key)] =
            String(message || "Invalid value");
        }
      });
      return out;
    }

    if (typeof payload === "object") {
      const out = {};
      Object.entries(payload).forEach(([key, value]) => {
        if (
          (key === "message" || key === "error" || key === "detail") &&
          typeof value === "string"
        ) {
          out._form = out._form ? `${out._form} ${value}` : value;
          return;
        }
        const normalizedKey = normalizeStep1Field(key);
        const message = coerceErrorMessage(value);
        if (!normalizedKey) return;
        out[normalizedKey] = message || "Invalid value";
      });
      return out;
    }

    return {};
  };

  const focusFirstError = (errorMap, fieldOrder = []) => {
    if (!errorMap || Object.keys(errorMap).length === 0) return;
    const order = fieldOrder.filter((key) => errorMap[key]);
    const firstKey =
      order[0] ||
      Object.keys(errorMap).find((key) => key !== "_form");
    if (!firstKey) return;
    setTimeout(() => {
      const byAria = document.querySelector(
        `[aria-labelledby~="${firstKey}-label"]`
      );
      if (byAria && typeof byAria.focus === "function") {
        byAria.focus();
        return;
      }
      const byName = document.querySelector(`[name="${firstKey}"]`);
      if (byName && typeof byName.focus === "function") {
        byName.focus();
        return;
      }
      const byId = document.getElementById(firstKey);
      if (byId && typeof byId.focus === "function") {
        byId.focus();
      }
    }, 0);
  };

  const clearFieldErrors = (fields) => {
    if (!fields) return;
    const list = Array.isArray(fields) ? fields : [fields];
    setErrors((prev) => {
      if (!prev || Object.keys(prev).length === 0) return prev;
      let changed = false;
      const next = { ...prev };
      list.forEach((field) => {
        if (field in next) {
          delete next[field];
          changed = true;
        }
      });
      if (next._form) {
        delete next._form;
        changed = true;
      }
      return changed ? next : prev;
    });
  };


   useEffect(() => {
    // in case user comes again with a different step
    if (location.state?.step) {
      setCurrentStep(location.state.step);
      window.scrollTo(0, 0);
    }
  }, [location.state?.step]);




  const validateStep = (step) => {
    const newErrors = {};

    if (step === 1) {
      const required = [
        "name",
        "mobileNumber",
        "gender",
        "dob",
        "maritalStatus",
        "profileFor",
        "caste",
        "email",
        "password",
        "confirmPassword",
        "state",
        "city",
        "pincode",
      ];

      required.forEach((field) => {
        if (!personalDetails[field]) {
          newErrors[field] = "This field is required";
        }
      });

      if (
        personalDetails.email &&
        !/\S+@\S+\.\S+/.test(personalDetails.email)
      ) {
        newErrors.email = "Invalid email format";
      }
      if (
        personalDetails.mobileNumber &&
        personalDetails.mobileNumber.length !== 10
      ) {
        newErrors.mobileNumber = "Mobile number must be 10 digits";
      }
      if (personalDetails.height && Number(personalDetails.height) > 10) {
        newErrors.height = "Height must be 10 or less";
      }
      if (personalDetails.weight && Number(personalDetails.weight) > 300) {
        newErrors.weight = "Weight must be 300 or less";
      }
      if (
        personalDetails.password &&
        personalDetails.confirmPassword &&
        personalDetails.password !== personalDetails.confirmPassword
      ) {
        newErrors.confirmPassword = "Passwords do not match";
      }
    } else if (step === 2) {
      const required = [
        "qualification",
        "fieldOfStudy",
        "occupation",
        "organization",
        "employeeType",
        "income",
      ];
      required.forEach((field) => {
        if (!educationalDetails[field]) {
          newErrors[field] = "This field is required";
        }
      });
    } else if (step === 3) {
      const required = [
        "fatherName",
        "motherName",
        "familyStatus",
      ];
      required.forEach((field) => {
        if (!familyDetails[field]) {
          newErrors[field] = "This field is required";
        }
      });
    } else if (step === 4) {
      const required = ["diets", "hobbies", "dob", "tob"];
      required.forEach((field) => {
        const value = lifestyleDetails[field];
        if (Array.isArray(value)) {
          if (value.length === 0) newErrors[field] = "This field is required";
        } else if (!value) {
          newErrors[field] = "This field is required";
        }
      });
    } else if (step === 5) {
      const required = [
        "ageRange",
        "castes",
        "subCastes",
        "occupations",
        "educations",
        "hobbies",
        "annualIncome",
        "states",
        "districts",
      ];
      required.forEach((field) => {
        const value = partnerPreferences[field];
        if (Array.isArray(value)) {
          if (value.length === 0) {
            newErrors[field] = "This field is required";
          }
          return;
        }
        if (!value) {
          newErrors[field] = "This field is required";
        }
      });
    }

    setErrors(newErrors);

    if (Object.keys(newErrors).length > 0) {
      focusFirstError(newErrors, STEP_FIELD_ORDER[step] || []);
    }

    return Object.keys(newErrors).length === 0;
  };

  const buildRegisterStep1Payload = async () => {
    const formData = new FormData();
    formData.append("name", personalDetails.name);
    formData.append("mobile", personalDetails.mobileNumber);
    formData.append("email", personalDetails.email);
    formData.append("pincode", personalDetails.pincode);
    formData.append("gender", personalDetails.gender);
    formData.append("dob", personalDetails.dob);
    formData.append("height", personalDetails.height || "");
    formData.append("weight", personalDetails.weight || "");
    formData.append("marital_status", personalDetails.maritalStatus);
    formData.append("religion", personalDetails.religion);
    formData.append("profile_for", personalDetails.profileFor || "");
    formData.append("caste", personalDetails.caste);
    formData.append("sub_caste", personalDetails.subCaste || "");
    formData.append("gothram", personalDetails.gothram || "");
    formData.append("raasi", personalDetails.raasi || "");
    formData.append("star", personalDetails.star || "");
    formData.append("state", personalDetails.state);
    formData.append("district", personalDetails.city);
    formData.append("password", personalDetails.password || "");
    formData.append("fcm_token", localStorage.getItem("fcm_token") || "");

    if (personalDetails.profiles && Array.isArray(personalDetails.profiles)) {
      for (const [index, item] of personalDetails.profiles.entries()) {
        // If the file object is intact (e.g., just added), use it directly.
        if (item.file && (item.file instanceof Blob || (typeof item.file === 'object' && item.file !== null && item.file.name))) {
          formData.append(`profile_images[${index}]`, item.file);
        }
        // If the file object was lost due to Redux serialization,
        // try to recover it from the blob URL preview.
        else if (
          item.preview &&
          typeof item.preview === "string"
        ) {
          try {
            const response = await fetch(item.preview);
            const blob = await response.blob();
            const fileName = item.name || `profile_image_${index}.jpg`;
            const fileType = item.type || "image/jpeg";
            const recoveredFile = new File([blob], fileName, { type: fileType });
            formData.append(`profile_images[${index}]`, recoveredFile);
          } catch (e) {
            console.error(`Could not recover file from blob URL: ${item.preview}`, e);
          }
        }
      }
    }
    return formData;
  };

  const buildRegisterStep2Payload = () => {
    const formData = new FormData();
    formData.append("college_name", educationalDetails.collegeName || "");
    formData.append("study_field", educationalDetails.fieldOfStudy || "");
    formData.append("education", educationalDetails.qualification || "");
    formData.append("occupation", educationalDetails.occupation || "");
    formData.append("company_name", educationalDetails.organization || "");
    formData.append("employee_type", educationalDetails.employeeType || "");
    formData.append("annual_income", educationalDetails.income || "");
    formData.append("work_location", educationalDetails.workLocation || "");
    return formData;
  };

  const buildRegisterStep3Payload = () => {
    const formData = new FormData();
    formData.append("father_name", familyDetails.fatherName);
    formData.append("father_occupation", familyDetails.fatherOccupation || "");
    formData.append("mother_name", familyDetails.motherName);
    formData.append("mother_occupation", familyDetails.motherOccupation || "");
    formData.append("family_status", familyDetails.familyStatus);
    formData.append("native_place", familyDetails.nativePlace || "");
    formData.append("brother_count", familyDetails.brotherCount || 0);
    formData.append("sister_count", familyDetails.sisterCount || 0);

    (familyDetails.brothers || []).forEach((brother, index) => {
      formData.append(`brothers[${index}][name]`, brother?.name || "");
      formData.append(`brothers[${index}][occupation]`, brother?.occupation || "");
      formData.append(`brothers[${index}][marital_status]`, brother?.maritalStatus || "");
      formData.append(`brothers[${index}][have_childrens]`, brother?.haveChildrens ?? "");
    });

    (familyDetails.sisters || []).forEach((sister, index) => {
      formData.append(`sisters[${index}][name]`, sister?.name || "");
      formData.append(`sisters[${index}][occupation]`, sister?.occupation || "");
      formData.append(`sisters[${index}][marital_status]`, sister?.maritalStatus || "");
      formData.append(`sisters[${index}][have_childrens]`, sister?.haveChildrens ?? "");
    });

    return formData;
  };

  const buildRegisterStep4Payload = () => {
    const formData = new FormData();
    formData.append("dob", lifestyleDetails.dob || "");
    formData.append("tob", lifestyleDetails.tob || "");
    formData.append("place_of_birth", lifestyleDetails.placeOfBirth || "");

    (lifestyleDetails.diets || []).forEach((id, index) => {
      formData.append(`diets[${index}]`, id);
    });

    (lifestyleDetails.hobbies || []).forEach((id, index) => {
      formData.append(`hobbies[${index}]`, id);
    });

    const graha = lifestyleDetails.graha || {};
    Object.keys(graha).forEach((house) => {
      const values = graha[house] || [];
      values.forEach((value, index) => {
        formData.append(`graha_${house}[${index}]`, value);
      });
    });

    const amsam = lifestyleDetails.amsam || {};
    Object.keys(amsam).forEach((house) => {
      const values = amsam[house] || [];
      values.forEach((value, index) => {
        formData.append(`amsam_${house}[${index}]`, value);
      });
    });

    return formData;
  };

  const buildRegisterStep5Payload = () => {
    const formData = new FormData();
    formData.append("age_range", partnerPreferences.ageRange || "");
    formData.append("annual_income", partnerPreferences.annualIncome || "");

    (partnerPreferences.castes || []).forEach((id, index) => {
      formData.append(`castes[${index}]`, id);
    });

    (partnerPreferences.subCastes || []).forEach((id, index) => {
      formData.append(`sub_castes[${index}]`, id);
    });

    (partnerPreferences.occupations || []).forEach((id, index) => {
      formData.append(`occupations[${index}]`, id);
    });

    (partnerPreferences.educations || []).forEach((id, index) => {
      formData.append(`educations[${index}]`, id);
    });

    (partnerPreferences.hobbies || []).forEach((id, index) => {
      formData.append(`hobbies[${index}]`, id);
    });

    (partnerPreferences.states || []).forEach((id, index) => {
      formData.append(`states[${index}]`, id);
    });

    (partnerPreferences.districts || []).forEach((id, index) => {
      formData.append(`districts[${index}]`, id);
    });

    return formData;
  };

  const extractAccessToken = (res) =>
    res?.access_token ||
    res?.accessToken ||
    res?.token ||
    res?.data?.access_token ||
    res?.data?.accessToken ||
    res?.data?.token ||
    res?.result?.access_token ||
    res?.result?.accessToken ||
    res?.result?.token ||
    null;

  const handleStepSubmit = async () => {
    const isValid = validateStep(currentStep);
    if (!isValid) return;

    try {
      if (currentStep === 1) {
        const payload = await buildRegisterStep1Payload();
        const res = await registerStep1.mutateAsync(payload);
        const token = extractAccessToken(res);
        if (token) {
          setAccessToken(token);
        }
      } else if (currentStep === 2) {
        const payload = buildRegisterStep2Payload();
        await registerStep2.mutateAsync(payload);
      } else if (currentStep === 3) {
        const payload = buildRegisterStep3Payload();
        await registerStep3.mutateAsync(payload);
      } else if (currentStep === 4) {
        const payload = buildRegisterStep4Payload();
        await registerStep4.mutateAsync(payload);
      } else if (currentStep === 5) {
        const payload = buildRegisterStep5Payload();
        await registerStep5.mutateAsync(payload);
      }
      setErrors({});
      setCurrentStep((prev) => Math.min(prev + 1, 6));
      window.scrollTo(0, 0);
    } catch (e) {
      const serverErrors = mapServerErrors(e);
      let handled = false;

      if (Object.keys(serverErrors).length > 0) {
        const hasFieldErrors = Object.keys(serverErrors).some(
          (key) => key !== "_form"
        );
        if (hasFieldErrors) {
          setErrors(serverErrors);
          focusFirstError(serverErrors, STEP_FIELD_ORDER[currentStep]);
          // For step 1, we know mapping is correct so field errors are sufficient feedback
          if (currentStep === 1) handled = true;
        }
        if (serverErrors._form) {
          toast.error(serverErrors._form, { position: "top-right" });
          handled = true;
        }
      }

      if (!handled) {
        const msg = e?.response?.data?.message || e?.message || "Failed to submit step. Please try again.";
        toast.error(msg, { position: "top-right" });
      }
    }
  };

  const handleSkip = () => {
    setErrors({});
    setCurrentStep((prev) => Math.min(prev + 1, 6));
    window.scrollTo(0, 0);
  };

  const handleStepClick = (step) => {
    setCurrentStep(step);
    setErrors({});
    window.scrollTo(0, 0);
  };

  const handleEdit = (step) => {
    setCurrentStep(step);
    setErrors({});
    window.scrollTo(0, 0);
  };

  const handleFinalSubmit = async () => {
    for (let i = 1; i <= 5; i++) {
      const ok = validateStep(i);
      if (!ok) {
        setCurrentStep(i);
        return;
      }
    }

    try {
      // final combined API call - replace with your final API
      await new Promise((resolve) => setTimeout(resolve, 500));
      toast.success("Form submitted successfully!", { position: "top-right" });
    } catch (e) {
      toast.error("Failed to submit form.", { position: "top-right" });
    }
  };

  const renderStepContent = () => {
    switch (currentStep) {
      case 1:
        return (
          <PersonalDetailsForm
            onSubmitStep={handleStepSubmit}
            errors={errors}
            onFieldChange={clearFieldErrors}
          />
        );
      case 2:
        return (
          <EducationalDetailsForm
            onSubmitStep={handleStepSubmit}
            onSkipStep={handleSkip}
            errors={errors}
            onFieldChange={clearFieldErrors}
          />
        );
      case 3:
        return (
          <FamilyDetailsForm
            onSubmitStep={handleStepSubmit}
            onSkipStep={handleSkip}
            errors={errors}
            onFieldChange={clearFieldErrors}
          />
        );
      case 4:
        return (
          <LifestyleDetailsForm
            onSubmitStep={handleStepSubmit}
            onSkipStep={handleSkip}
            errors={errors}
            onFieldChange={clearFieldErrors}
          />
        );
      case 5:
        return (
          <PartnerPreferencesForm
            onSubmitStep={handleStepSubmit}
            onSkipStep={handleSkip}
            errors={errors}
            onFieldChange={clearFieldErrors}
          />
        );
      case 6:
        return <PreviewScreen onEdit={handleEdit} onSubmit={handleFinalSubmit} />;
      default:
        return null;
    }
  };

  const getTitle = () => {
    const titles = {
      1: "Personal Details",
      2: "Educational & Professional Details",
      3: "Family Details",
      4: "Lifestyle & Habits",
      5: "Partner Preferences",
      6: "Details Preview",
    };
    return titles[currentStep] || "";
  };

  return (
    <div className="">
      <div className="max-w-[1400px] mx-auto bg-white  ">
        {/* Header */}
        <div className="my-4 rounded-[10px] py-4  bg-[#e3ffed]  w-full max-w-[1200px] mx-auto">

            <Stepper currentStep={currentStep} onStepClick={handleStepClick} />
          <div className="flex items-center p-4 justify-center">
            {currentStep > 1 && currentStep < 6 && (
              <button
                onClick={() => setCurrentStep((prev) => prev - 1)}
                className="mr-3"
              >
                <ChevronLeft size={24} />
              </button>
            )}
            <h1 className="text-[24px] font-semibold text-center uppercase bg-[#fff2f2] py-2 px-3 rounded-5">{getTitle()}</h1>
          </div>
        
        </div>

        {/* Content */}
        <div className="pb-6">{renderStepContent()}</div>
      </div>
    </div>
  );
};

export default StepperForm;
