// RegistrationStepper.tsx
"use client";

import React, { useEffect, useMemo, useState } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { Button } from "@/shared/common/ui/button";
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/shared/common/ui/form";
import { Input } from "@/shared/common/ui/input";
import { Mail, User, Phone, Text, Building } from "lucide-react";
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
} from "@/shared/common/ui/card";
import { Stepper } from "./Stepper";
import VerifyOtp from "../verifyOTP";
import UploadDocumentsStep from "./UploadDocumentsStep";
import { useRegisterExternalPortalUser } from "@/external-portal/hooks/useRegisterExternalPortalUser";
import { submitApplication } from "@/external-portal/services/portalOutgoingService";
import { toast } from "sonner";
import { useNavigate } from "react-router-dom";
import { useDocumentRequirement } from "@/shared/hooks/useOrganizationReport";
import { FilterEnum } from "@/shared/services/organizationsService";
import { DocumentReq } from "./UploadDocumentsStep";
import { useErrorHandler } from "@/shared/hooks/useErrorHandler";
import { useTranslation } from "react-i18next";
import { useDocumentUploads } from "@/external-portal/hooks/useDocumentUploads";
import { DocumentPayloadDto } from "@/shared/dto/External-Portal/External-PortalDto";
import { useDeleteExternalUser } from "@/super-admin/hooks/useExternalUsers";
import Cookies from "js-cookie";

type FilesRecord = Record<string, File | string | null>;

// registration schema
const registrationSchema = z.object({
  email: z.string().email("Invalid email address"),
  username: z.string().min(3, "Username must be at least 3 characters"),
  phoneNumber: z.string().min(10, "Phone number must be at least 10 digits"),
  name: z.object({
    en: z.string().min(2, "English name must be at least 2 characters"),
    am: z.string().min(2, "Amharic name must be at least 2 characters"),
  }),
  userType: z.enum(["individual", "external_organization"]),
});

type RegistrationFormValues = z.infer<typeof registrationSchema>;

const RegistrationStepper: React.FC = () => {
  const [currentStep, setCurrentStep] = useState(0);
  const [formData, setFormData] = useState<RegistrationFormValues | null>(null);
  const [uploadedFiles, setUploadedFiles] = useState<FilesRecord>({});
  const [submitting, setSubmitting] = useState(false);
  const [step1Completed, setStep1Completed] = useState(false);
  const { t } = useTranslation();
  const { registerExternalPortalUser, isRegistering } =
    useRegisterExternalPortalUser();
  const { handleError } = useErrorHandler(t);
  const { uploadDocuments } = useDocumentUploads();

  const form = useForm<RegistrationFormValues>({
    resolver: zodResolver(registrationSchema),
    defaultValues: {
      email: "",
      username: "",
      phoneNumber: "",
      userType: "external_organization",
      name: { en: "", am: "" },
    },
  });

  const userType = form.watch("userType");
  const mappedType =
    userType === "external_organization" ? "organization" : userType;
  const filterData: FilterEnum | undefined =
    mappedType && Object.values(FilterEnum).includes(mappedType as FilterEnum)
      ? (mappedType as FilterEnum)
      : undefined;

  // fetch requirement docs to know which are required
  const { requirementDoc } = useDocumentRequirement(filterData);
  const requiredDocs = useMemo(
    () =>
      requirementDoc?.items?.filter((d: DocumentReq) => !d.isOptional) ?? [],
    [requirementDoc]
  );

  const attachedCount = useMemo(
    () => Object.values(uploadedFiles).filter((f) => f !== null).length,
    [uploadedFiles]
  );

  //validation
  const isStep1Complete = useMemo(() => {
    if (!form.formState.isValid) return false;

    // Check if all required documents are uploaded
    const hasAllRequiredDocs = requiredDocs.every(
      (doc) => uploadedFiles[doc.id] instanceof File
    );

    return hasAllRequiredDocs && form.formState.isValid;
  }, [form.formState.isValid, requiredDocs, uploadedFiles]);
  useEffect(() => {
    setStep1Completed(isStep1Complete);
  }, [isStep1Complete]);
  useEffect(() => {
    setStep1Completed(isStep1Complete);
  }, [isStep1Complete]);

  const resetRegistrationFlow = () => {
    setCurrentStep(0);
    setFormData(null);
    setUploadedFiles({});
    setSubmitting(false);
    setStep1Completed(false);
    form.reset({
      email: "",
      username: "",
      phoneNumber: "",
      userType: "external_organization",
      name: { en: "", am: "" },
    });
  };

  useEffect(() => {
    resetRegistrationFlow();

    const handlePageShow = (event: PageTransitionEvent) => {
      if (event.persisted) {
        resetRegistrationFlow();
      }
    };

    window.addEventListener("pageshow", handlePageShow);
    return () => window.removeEventListener("pageshow", handlePageShow);
  }, []);
  const onRegistrationSubmit = async (data: RegistrationFormValues) => {
    // 1️⃣ Validate documents
    const missingDocs: string[] = requiredDocs
      .filter((doc) => !uploadedFiles[doc.id])
      .map((doc) => `${doc.title?.en || "Document"} is required.`);

    // 2️⃣ Collect form errors from react-hook-form
    const formErrorMessages = Object.values(form.formState.errors)
      .map((err: any) => err?.message)
      .filter(Boolean);

    // 3️⃣ Combine all errors
    const allErrors = [...formErrorMessages, ...missingDocs];

    // 4️⃣ Stop submission and show toast if errors exist
    if (allErrors.length > 0) {
      allErrors.forEach((msg) => toast.error(msg));
      return;
    }

    setSubmitting(true);
    try {
      // 5️⃣ Create external portal user
      const response = await registerExternalPortalUser(data);
      if (!response?.success) {
        form.setError("root", {
          type: "manual",
          message: response?.response?.data?.message,
        });

        return;
      }

      // 6️⃣ Save tokens
      const token = response.response?.data?.token;
      const refreshToken = response.response?.data?.refreshToken;
      Cookies.set("auth-token", token || "");
      Cookies.set("refresh-token", refreshToken || "");

      // 7️⃣ Upload documents
      await uploadAllFiles();
      await submitApplication();
      toast.success(t("registration.verifyOtp.messages.registrationComplete"));
      setFormData(data);
      setStep1Completed(true);
      setCurrentStep(1); // move to OTP verification
    } catch (err) {
      if (err instanceof Error && err.message.includes("Duplicate entry")) {
        form.setError("root", {
          type: "manual",
          message: t("registration.verifyOtp.errors.alreadyRegistered"),
        });
      } else {
        handleError(err);
      }
    } finally {
      setSubmitting(false);
    }
  };

  const uploadAllFiles = async (): Promise<void> => {
    const filesToUpload = Object.entries(uploadedFiles).filter(
      ([, file]) => file instanceof File
    );

    if (filesToUpload.length === 0) {
      throw new Error(
        "No documents uploaded. Registration requires documents."
      );
    }

    const uploadPromises = filesToUpload.map(async ([docId, file]) => {
      if (file instanceof File) {
        const payload: DocumentPayloadDto = {
          documentId: docId,
          type: filterData || FilterEnum.EXTERNAL,
          fileInfo: {
            size: file.size,
            fileName: file.name,
            contentType: file.type,
            originalname: file.name,
          },
        };

        return uploadDocuments(payload, file).catch((err) => {
          throw new Error(
            `Failed to upload ${file.name} for document ${docId}: ${err}`
          );
        });
      }
    });

    await Promise.all(uploadPromises);
  };

  const onVerifyComplete = async () => {
    setSubmitting(true);
    try {
      toast.success("Application submitted successfully.");
      const refreshToken = Cookies.get("refresh-token");
      if (!refreshToken) {
        throw new Error("No refresh token found");
      }
    } catch (err) {
      console.error("submit error", err);
      toast.error("Failed to submit application.");
    } finally {
      setSubmitting(false);
    }
  };
  const handleStepChange = (step: number) => {
    if (step === 1 && !step1Completed) {
      toast.error(
        "Please complete the registration form and upload all required documents first"
      );
      return;
    }
    setCurrentStep(step);
  };
  const steps = [
    {
      title: t("registration.steps.registerUpload.title"),
      description: t("registration.steps.registerUpload.description"),
      content: (
        <Form {...form}>
          <form
            onSubmit={form.handleSubmit(onRegistrationSubmit)}
            className="space-y-6">
            <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
              {/* Left: form */}
              <div className="space-y-4">
                

                <FormField
                  control={form.control}
                  name="email"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>
                        {userType === "external_organization"
                          ? t("registration.form.organizationEmail")
                          : t("registration.form.individualEmail")}
                        <span className="text-red-500" aria-hidden="true">
                          *
                        </span>
                      </FormLabel>
                      <FormControl>
                        <div className="relative">
                          <Mail className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-400" />
                          <Input
                            {...field}
                            className="pl-10"
                            placeholder={
                              userType === "external_organization"
                                ? t(
                                    "registration.form.organizationEmailPlaceholder"
                                  )
                                : t(
                                    "registration.form.individualEmailPlaceholder"
                                  )
                            }
                          />
                        </div>
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />

                <FormField
                  control={form.control}
                  name="username"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>
                        {userType === "external_organization"
                          ? t("registration.form.organizationUsername")
                          : t("registration.form.individualUsername")}
                        <span className="text-red-500" aria-hidden="true">
                          *
                        </span>
                      </FormLabel>
                      <FormControl>
                        <div className="relative">
                          <User className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-400" />
                          <Input
                            {...field}
                            className="pl-10"
                            placeholder={
                              userType === "external_organization"
                                ? t(
                                    "registration.form.organizationUsernamePlaceholder"
                                  )
                                : t(
                                    "registration.form.individualUsernamePlaceholder"
                                  )
                            }
                          />
                        </div>
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />

                <FormField
                  control={form.control}
                  name="phoneNumber"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>
                        {userType === "external_organization"
                          ? t("registration.form.organizationPhone")
                          : t("registration.form.individualPhone")}
                        <span className="text-red-500" aria-hidden="true">
                          *
                        </span>
                      </FormLabel>
                      <FormControl>
                        <div className="relative">
                          <Phone className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-400" />
                          <Input
                            {...field}
                            className="pl-10"
                            placeholder={
                              userType === "external_organization"
                                ? t(
                                    "registration.form.organizationPhonePlaceholder"
                                  )
                                : t(
                                    "registration.form.individualPhonePlaceholder"
                                  )
                            }
                          />
                        </div>
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />

                <FormField
                  control={form.control}
                  name="name.en"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>
                        {userType === "external_organization"
                          ? t("registration.form.organizationNameEn")
                          : t("registration.form.individualNameEn")}
                        <span className="text-red-500" aria-hidden="true">
                          *
                        </span>
                      </FormLabel>
                      <FormControl>
                        <div className="relative">
                          <Text className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-400" />
                          <Input
                            {...field}
                            className="pl-10"
                            placeholder={
                              userType === "external_organization"
                                ? t(
                                    "registration.form.organizationNameEnPlaceholder"
                                  )
                                : t(
                                    "registration.form.individualNameEnPlaceholder"
                                  )
                            }
                          />
                        </div>
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />

                <FormField
                  control={form.control}
                  name="name.am"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>
                        {userType === "external_organization"
                          ? t("registration.form.organizationNameAm")
                          : t("registration.form.individualNameAm")}
                        <span className="text-red-500" aria-hidden="true">
                          *
                        </span>
                      </FormLabel>
                      <FormControl>
                        <Input
                          {...field}
                          placeholder={
                            userType === "external_organization"
                              ? t(
                                  "registration.form.organizationNameAmPlaceholder"
                                )
                              : t(
                                  "registration.form.individualNameAmPlaceholder"
                                )
                          }
                        />
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />

                {form.formState.errors.root?.message && (
                  <div className="text-sm text-destructive mt-2">
                    {String(form.formState.errors.root.message)}
                  </div>
                )}
              </div>

              {/* Right: Uploads */}
              <div className="space-y-4">
                <div className="flex items-center justify-between">
                  <div>
                    <h3 className="text-lg font-semibold">
                      {t("registration.documents.requiredDocuments")}
                    </h3>
                    <p className="text-sm text-gray-500">
                      {t("registration.documents.requirementsUpdate")}
                    </p>
                  </div>
                  <div className="text-sm text-gray-600">
                    {attachedCount} {t("registration.documents.attached")}
                  </div>
                </div>

                <div className="p-2 border rounded-md max-h-[60vh] overflow-auto">
                  <UploadDocumentsStep
                    registrationType={userType}
                    uploadedFiles={uploadedFiles}
                    setUploadedFiles={setUploadedFiles}
                  />
                </div>

                <p className="text-sm text-gray-500">
                  {t("registration.documents.tip")}
                </p>
              </div>

              {/* Submit Button - Span full width */}
              <div className="md:col-span-2">
                <Button
                  type="submit"
                  disabled={isRegistering || submitting}
                  className="w-full bg-primary-600">
                  {isRegistering || submitting
                    ? t("registration.form.processing")
                    : userType === "external_organization"
                    ? t("registration.form.organizationSubmitButton")
                    : t("registration.form.individualSubmitButton")}
                </Button>
              </div>
            </div>
          </form>
        </Form>
      ),
    },
    {
      title: t("registration.steps.verifyOtp.title"),
      description: t("registration.steps.verifyOtp.description"),
      content: (
        <VerifyOtp
          email={formData?.email}
          phone={formData?.phoneNumber}
          onComplete={onVerifyComplete}
          isExternalOrg={true}
        />
      ),
    },
  ];
  return (
    <div className="min-h-screen bg-gradient-to-br from-gray-50 to-gray-100 flex items-center justify-center p-4">
      <Card className="w-full max-w-5xl">
        <CardHeader>
          <div className="flex items-center justify-center mb-4">
            <Building className="h-8 w-8 mr-2" />
            <CardTitle className="text-2xl font-bold">Registration</CardTitle>
          </div>
          <Stepper
            steps={steps}
            currentStep={currentStep}
            setCurrentStep={handleStepChange}
            disabled={submitting}
          />
        </CardHeader>
        <CardContent>{steps[currentStep].content}</CardContent>
      </Card>
    </div>
  );
};

export default RegistrationStepper;
