import { useEffect } from "react";
import type { ReactElement } from "react";
import { useForm, useFieldArray } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { Plus, Trash2 } from "lucide-react";
import {
  Modal,
  FormField,
  FormSelect,
  PaginatedSelect,
  PrimaryButton,
  SecondaryButton,
} from "@/components/shared";
import { roleService } from "@/services/role-service";
import { departmentService } from "@/services/department-service";
import { designationService } from "@/services/designation-service";
import { moduleService } from "@/services/module-service";
import { supplierService } from "@/services/supplier-service";
import { useAppSelector } from "@/hooks/redux-hooks";

// Validation schema
const newUserSchema = z
  .object({
    email: z.email({ message: "Please enter a valid email address" }),
    password: z
      .string()
      .min(1, "Password is required")
      .min(6, "Password must be at least 6 characters"),
    confirmPassword: z.string().min(1, "Confirm password is required"),
    first_name: z.string().min(1, "First name is required"),
    last_name: z.string().min(1, "Last name is required"),
    status: z.enum(["active", "suspended", "deleted"], {
      message: "Status is required",
    }),
    auth_provider: z.enum(["local"], {
      message: "Auth provider is required",
    }),
    role_module_combinations: z.array(
      z.object({
        role_id: z.string().min(1, "Role is required"),
        module_id: z.string().nullable().optional(),
      })
    ).min(1, "At least one role assignment is required")
     .refine(
       (combinations) => {
         const seen = new Set();
         for (const combo of combinations) {
           const key = `${combo.role_id}-${combo.module_id || "global"}`;
           if (seen.has(key)) return false;
           seen.add(key);
         }
         return true;
       },
       { message: "Duplicate role-module combinations are not allowed" }
     ),
    department_id: z.string().optional(),
    designation_id: z.string().optional(),
    category: z.enum(["tenant_user", "supplier_user"]).default("tenant_user"),
    supplier_id: z.string().optional().nullable(),
  })
  .refine((data) => data.password === data.confirmPassword, {
    message: "Passwords don't match",
    path: ["confirmPassword"],
  });

type NewUserFormData = z.infer<typeof newUserSchema>;

interface NewUserModalProps {
  isOpen: boolean;
  onClose: () => void;
  onSubmit: (data: Omit<NewUserFormData, "confirmPassword">) => Promise<void>;
  isLoading?: boolean;
  defaultTenantId?: string; // If provided, filter roles by tenant_id
}

const statusOptions = [
  { value: "active", label: "Active" },
  { value: "suspended", label: "Suspended" },
  { value: "deleted", label: "Deleted" },
];

export const NewUserModal = ({
  isOpen,
  onClose,
  onSubmit,
  isLoading = false,
  defaultTenantId,
}: NewUserModalProps): ReactElement | null => {
  const {
    control,
    register,
    handleSubmit,
    setValue,
    watch,
    reset,
    setError,
    clearErrors,
    formState: { errors },
  } = useForm<NewUserFormData>({
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    resolver: zodResolver(newUserSchema) as any,
    defaultValues: {
      role_module_combinations: [{ role_id: "", module_id: null }],
      department_id: "",
      designation_id: "",
      category: "tenant_user" as const,
      supplier_id: null,
    },
  });

  const { fields, append, remove } = useFieldArray({
    control,
    name: "role_module_combinations",
  });

  const statusValue = watch("status");
  const departmentIdValue = watch("department_id");
  const designationIdValue = watch("designation_id");
  const categoryValue = watch("category");
  const supplierIdValue = watch("supplier_id");

  const roles = useAppSelector((state) => state.auth.roles);
  const isSuperAdmin = roles.includes("super_admin");

  // Reset form when modal closes
  useEffect(() => {
    if (!isOpen) {
      reset({
        email: "",
        password: "",
        confirmPassword: "",
        first_name: "",
        last_name: "",
        status: "active",
        auth_provider: "local",
        role_module_combinations: [{ role_id: "", module_id: null }],
        department_id: "",
        designation_id: "",
        category: "tenant_user",
        supplier_id: null,
      });
      clearErrors();
    }
  }, [isOpen, reset, clearErrors]);

  // Load roles for dropdown
  const loadRoles = async (page: number, limit: number) => {
    const response = defaultTenantId
      ? await roleService.getByTenant(defaultTenantId, page, limit)
      : await roleService.getAll(page, limit);
    return {
      options: response.data.map((role) => ({
        value: role.id,
        label: role.name,
      })),
      pagination: response.pagination,
    };
  };

  const loadDepartments = async () => {
    const response = await departmentService.list(defaultTenantId, {
      active_only: true,
    });
    return {
      options: response.data.map((dept) => ({
        value: dept.id,
        label: dept.name,
      })),
      pagination: {
        page: 1,
        limit: response.data.length,
        total: response.data.length,
        totalPages: 1,
        hasMore: false,
      },
    };
  };

  const loadDesignations = async () => {
    const response = await designationService.list(defaultTenantId, {
      active_only: true,
    });
    return {
      options: response.data.map((desig) => ({
        value: desig.id,
        label: desig.name,
      })),
      pagination: {
        page: 1,
        limit: response.data.length,
        total: response.data.length,
        totalPages: 1,
        hasMore: false,
      },
    };
  };

  const loadModules = async (page: number, limit: number) => {
    const tenantId = isSuperAdmin ? defaultTenantId : undefined;
    const response = await moduleService.getAvailable(page, limit, tenantId);
    return {
      options: response.data.map((module) => ({
        value: module.id,
        label: module.name,
      })),
      pagination: response.pagination,
    };
  };

  const loadSuppliers = async (page: number, limit: number) => {
    const response = await supplierService.list({
      tenantId: defaultTenantId,
      limit,
      offset: (page - 1) * limit,
    });
    const total = response.pagination?.total ?? response.data?.length ?? 0;
    return {
      options: (response.data || []).map((supplier: any) => ({
        value: supplier.id,
        label: supplier.name,
      })),
      pagination: {
        page,
        limit,
        total,
        totalPages: Math.ceil(total / limit) || 1,
        hasMore: page * limit < total,
      },
    };
  };

  const handleFormSubmit = async (data: NewUserFormData): Promise<void> => {
    clearErrors();
    try {
      const { confirmPassword, ...submitData } = data;
      // Normalize empty strings to null for optional UUID fields
      if (!submitData.department_id) submitData.department_id = undefined;
      if (!submitData.designation_id) submitData.designation_id = undefined;
      
      // If category is tenant_user, supplier_id should always be null
      if (submitData.category === "tenant_user") {
        submitData.supplier_id = null;
      } else if (!submitData.supplier_id) {
        submitData.supplier_id = null;
      }
      
      await onSubmit(submitData);
    } catch (error: any) {
      // Handle validation errors from API
      if (
        error?.response?.data?.details &&
        Array.isArray(error.response.data.details)
      ) {
        const validationErrors = error.response.data.details;
        validationErrors.forEach(
          (detail: { path: string; message: string }) => {
            if (
              detail.path === "email" ||
              detail.path === "password" ||
              detail.path === "first_name" ||
              detail.path === "last_name" ||
              detail.path === "status" ||
              detail.path === "auth_provider" ||
              detail.path === "role_module_combinations"
            ) {
              setError(detail.path as keyof NewUserFormData, {
                type: "server",
                message: detail.message,
              });
            }
          },
        );
      } else {
        // Handle general errors
        // Check for nested error object with message property
        const errorObj = error?.response?.data?.error;
        const errorMessage =
          (typeof errorObj === "object" &&
          errorObj !== null &&
          "message" in errorObj
            ? errorObj.message
            : null) ||
          (typeof errorObj === "string" ? errorObj : null) ||
          error?.response?.data?.message ||
          error?.message ||
          "Failed to create user. Please try again.";
        setError("root", {
          type: "server",
          message:
            typeof errorMessage === "string"
              ? errorMessage
              : "Failed to create user. Please try again.",
        });
      }
    }
  };

  return (
    <Modal
      isOpen={isOpen}
      onClose={onClose}
      title="Create New User"
      description="Invite a new user to this tenant"
      maxWidth="md"
      footer={
        <>
          <SecondaryButton
            type="button"
            onClick={onClose}
            disabled={isLoading}
            className="px-4 py-2.5 text-sm"
          >
            Cancel
          </SecondaryButton>
          <PrimaryButton
            type="button"
            onClick={handleSubmit(handleFormSubmit as any)}
            disabled={isLoading}
            size="default"
            className="px-4 py-2.5 text-sm"
          >
            {isLoading ? "Creating..." : "Create User"}
          </PrimaryButton>
        </>
      }
    >
      <form onSubmit={handleSubmit(handleFormSubmit as any)} className="p-5">
        {/* General Error Display */}
        {errors.root && (
          <div className="p-4 bg-[rgba(239,68,68,0.1)] border border-[#ef4444] rounded-md mb-4">
            <p className="text-sm text-[#ef4444]">{errors.root.message}</p>
          </div>
        )}

        <div className="flex flex-col gap-0">
          {/* Email */}
          <FormField
            label="Email"
            type="email"
            required
            placeholder="Enter email address"
            error={errors.email?.message}
            {...register("email")}
          />

          {/* First Name and Last Name Row */}
          <div className="grid grid-cols-2 gap-5 pb-4">
            <FormField
              label="First Name"
              required
              placeholder="Enter first name"
              error={errors.first_name?.message}
              {...register("first_name")}
            />

            <FormField
              label="Last Name"
              required
              placeholder="Enter last name"
              error={errors.last_name?.message}
              {...register("last_name")}
            />
          </div>

          {/* Password and Confirm Password Row */}
          <div className="grid grid-cols-2 gap-5 pb-4">
            <FormField
              label="Password"
              type="password"
              required
              placeholder="Enter password"
              error={errors.password?.message}
              {...register("password")}
            />

            <FormField
              label="Confirm Password"
              type="password"
              required
              placeholder="Confirm password"
              error={errors.confirmPassword?.message}
              {...register("confirmPassword")}
            />
          </div>

          <div className="grid grid-cols-2 gap-5 pb-4">
            <PaginatedSelect
              label="Department"
              placeholder="Select Department"
              value={departmentIdValue || ""}
              onValueChange={(value) => setValue("department_id", value)}
              onLoadOptions={loadDepartments}
              error={errors.department_id?.message}
            />

            <PaginatedSelect
              label="Designation"
              placeholder="Select Designation"
              value={designationIdValue || ""}
              onValueChange={(value) => setValue("designation_id", value)}
              onLoadOptions={loadDesignations}
              error={errors.designation_id?.message}
            />
          </div>

          {/* User Category */}
          <div className="grid grid-cols-2 gap-5 pb-4">
            <FormSelect
              label="User Category"
              required
              placeholder="Select Category"
              options={[
                { value: "tenant_user", label: "Tenant User" },
                { value: "supplier_user", label: "Supplier User" },
              ]}
              value={categoryValue || "tenant_user"}
                onValueChange={(value) => {
                  const category = value as "tenant_user" | "supplier_user";
                  setValue("category", category, { shouldValidate: true });
                  if (category === "tenant_user") {
                    setValue("supplier_id", null);
                  }
                }}
              error={errors.category?.message}
            />

            {categoryValue === "supplier_user" && (
              <PaginatedSelect
                label="Linked Supplier"
                required
                placeholder="Select Supplier"
                value={supplierIdValue || ""}
                onValueChange={(value) => setValue("supplier_id", value)}
                onLoadOptions={loadSuppliers}
                error={errors.supplier_id?.message}
              />
            )}
          </div>

          <div className="pb-4">
            <FormSelect
              label="Status"
              required
              placeholder="Select Status"
              options={statusOptions}
              value={statusValue}
              onValueChange={(value) =>
                setValue("status", value as "active" | "suspended" | "deleted")
              }
              error={errors.status?.message}
            />
          </div>

          <div className="mt-2 mb-4">
            <div className="flex justify-between items-center mb-2">
              <label className="text-sm font-medium text-gray-700">Role & Module Assignments</label>
              <button
                type="button"
                onClick={() => append({ role_id: "", module_id: null })}
                className="text-sm font-medium text-[#112868] hover:text-[#0b1c4a] flex items-center gap-1"
              >
                <Plus className="w-4 h-4" /> Add Assignment
              </button>
            </div>
            
            {(errors.role_module_combinations as any)?.message && (
              <p className="text-sm text-red-500 mb-2">
                {(errors.role_module_combinations as any).message}
              </p>
            )}

            <div className="space-y-3">
              {fields.map((field, index) => {
                const roleIdValue = watch(`role_module_combinations.${index}.role_id`);
                const moduleIdValue = watch(`role_module_combinations.${index}.module_id`);
                
                return (
                  <div key={field.id} className="flex gap-2 items-start border p-3 rounded-md bg-gray-50 relative">
                    <div className="flex-1 grid grid-cols-2 gap-3">
                      <PaginatedSelect
                        label={`Role ${index + 1}`}
                        required
                        placeholder="Select Role"
                        value={roleIdValue || ""}
                        onValueChange={(value) => setValue(`role_module_combinations.${index}.role_id`, value, { shouldValidate: true })}
                        onLoadOptions={loadRoles}
                        error={errors.role_module_combinations?.[index]?.role_id?.message}
                      />
                      <PaginatedSelect
                        label="Module (Optional)"
                        placeholder="Select Module"
                        value={moduleIdValue || ""}
                        onValueChange={(value) => setValue(`role_module_combinations.${index}.module_id`, value, { shouldValidate: true })}
                        onLoadOptions={loadModules}
                        error={errors.role_module_combinations?.[index]?.module_id?.message}
                      />
                    </div>
                    {fields.length > 1 && (
                      <button
                        type="button"
                        onClick={() => remove(index)}
                        className="mt-8 p-2 text-red-500 hover:bg-red-50 rounded-md transition-colors"
                        title="Remove Assignment"
                      >
                        <Trash2 className="w-4 h-4" />
                      </button>
                    )}
                  </div>
                );
              })}
            </div>
          </div>
        </div>
      </form>
    </Modal>
  );
};
