import { useEffect, type ReactElement, useState } from "react";
import { useForm, type SubmitHandler } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import {
  Modal,
  FormField,
  FormSelect,
  PrimaryButton,
  SecondaryButton,
  PaginatedSelect,
} from "@/components/shared";
import type {
  Department,
  CreateDepartmentRequest,
  UpdateDepartmentRequest,
} from "@/types/department";
import { departmentService } from "@/services/department-service";

// Validation schema
const departmentSchema = z.object({
  name: z.string().min(1, "Name is required"),
  code: z.string().min(1, "Code is required"),
  description: z.string().optional(),
  is_active: z.boolean(),
  parent_id: z.string().nullable().optional(),
  sort_order: z.number().int().min(0).optional(),
});

type DepartmentFormData = z.infer<typeof departmentSchema>;

const statusOptions = [
  { value: "true", label: "Active" },
  { value: "false", label: "Inactive" },
];

interface NewDepartmentModalProps {
  isOpen: boolean;
  onClose: () => void;
  onSubmit: (data: CreateDepartmentRequest) => Promise<void>;
  isLoading?: boolean;
  tenantId?: string | null;
}

export const NewDepartmentModal = ({
  isOpen,
  onClose,
  onSubmit,
  isLoading = false,
  tenantId,
}: NewDepartmentModalProps): ReactElement | null => {
  const {
    register,
    handleSubmit,
    setValue,
    watch,
    reset,
    clearErrors,
    formState: { errors },
  } = useForm<DepartmentFormData>({
    resolver: zodResolver(departmentSchema),
    defaultValues: {
      is_active: true,
      parent_id: null,
      sort_order: 0,
    },
  });

  const statusValue = watch("is_active");
  const parentIdValue = watch("parent_id");

  useEffect(() => {
    if (!isOpen) {
      reset();
      clearErrors();
    }
  }, [isOpen, reset, clearErrors]);

  const loadDepartments = async () => {
    const response = await departmentService.list(tenantId, {
      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 handleFormSubmit: SubmitHandler<DepartmentFormData> = async (data) => {
    await onSubmit(data as CreateDepartmentRequest);
  };

  return (
    <Modal
      isOpen={isOpen}
      onClose={onClose}
      title="Create New Department"
      description="Add a new department to the system"
      maxWidth="md"
      footer={
        <>
          <SecondaryButton onClick={onClose} disabled={isLoading}>
            Cancel
          </SecondaryButton>
          <PrimaryButton
            onClick={handleSubmit(handleFormSubmit)}
            disabled={isLoading}
          >
            {isLoading ? "Creating..." : "Create Department"}
          </PrimaryButton>
        </>
      }
    >
      <form
        onSubmit={handleSubmit(handleFormSubmit)}
        className="p-5 flex flex-col gap-4"
      >
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
          <FormField
            label="Department Name"
            required
            placeholder="e.g. Engineering"
            error={errors.name?.message}
            {...register("name")}
          />
          <FormField
            label="Department Code"
            required
            placeholder="e.g. ENG"
            error={errors.code?.message}
            {...register("code")}
          />
        </div>

        <FormField
          label="Description"
          placeholder="Enter department description"
          error={errors.description?.message}
          {...register("description")}
        />

        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
          <PaginatedSelect
            label="Parent Department"
            placeholder="Select parent (optional)"
            value={parentIdValue || ""}
            onValueChange={(value) => setValue("parent_id", value || null)}
            onLoadOptions={loadDepartments}
            error={errors.parent_id?.message}
          />
          <FormField
            label="Sort Order"
            type="number"
            placeholder="0"
            error={errors.sort_order?.message}
            {...register("sort_order", { valueAsNumber: true })}
          />
        </div>

        <FormSelect
          label="Status"
          required
          options={statusOptions}
          value={String(statusValue)}
          onValueChange={(value) => setValue("is_active", value === "true")}
          error={errors.is_active?.message}
        />
      </form>
    </Modal>
  );
};

interface EditDepartmentModalProps {
  isOpen: boolean;
  onClose: () => void;
  onSubmit: (id: string, data: UpdateDepartmentRequest) => Promise<void>;
  department: Department | null;
  isLoading?: boolean;
  tenantId?: string | null;
}

export const EditDepartmentModal = ({
  isOpen,
  onClose,
  onSubmit,
  department,
  isLoading = false,
  tenantId,
}: EditDepartmentModalProps): ReactElement | null => {
  const [initialParentOption, setInitialParentOption] = useState<{
    value: string;
    label: string;
  } | null>(null);

  const {
    register,
    handleSubmit,
    setValue,
    watch,
    reset,
    clearErrors,
    formState: { errors },
  } = useForm<DepartmentFormData>({
    resolver: zodResolver(departmentSchema),
  });

  const statusValue = watch("is_active");
  const parentIdValue = watch("parent_id");

  useEffect(() => {
    if (isOpen && department) {
      reset({
        name: department.name,
        code: department.code,
        description: department.description || "",
        is_active: department.is_active,
        parent_id: department.parent_id,
        sort_order: department.sort_order || 0,
      });

      if (department.parent_id && department.parent_name) {
        setInitialParentOption({
          value: department.parent_id,
          label: department.parent_name,
        });
      } else {
        setInitialParentOption(null);
      }
    } else if (!isOpen) {
      reset();
      clearErrors();
      setInitialParentOption(null);
    }
  }, [isOpen, department, reset, clearErrors]);

  const loadDepartments = async () => {
    const response = await departmentService.list(tenantId, {
      active_only: true,
    });
    // Filter out current department to prevent self-referencing
    let options = response.data
      .filter((d) => d.id !== department?.id)
      .map((dept) => ({
        value: dept.id,
        label: dept.name,
      }));

    // Ensure initial parent is in options if not already there
    if (initialParentOption) {
      if (!options.find((o) => o.value === initialParentOption.value)) {
        options = [initialParentOption, ...options];
      }
    }

    return {
      options,
      pagination: {
        page: 1,
        limit: options.length,
        total: options.length,
        totalPages: 1,
        hasMore: false,
      },
    };
  };

  const handleFormSubmit: SubmitHandler<DepartmentFormData> = async (data) => {
    if (department) {
      await onSubmit(department.id, data as UpdateDepartmentRequest);
    }
  };

  return (
    <Modal
      isOpen={isOpen}
      onClose={onClose}
      title="Edit Department"
      description="Update department details"
      maxWidth="md"
      footer={
        <>
          <SecondaryButton onClick={onClose} disabled={isLoading}>
            Cancel
          </SecondaryButton>
          <PrimaryButton
            onClick={handleSubmit(handleFormSubmit)}
            disabled={isLoading}
          >
            {isLoading ? "Updating..." : "Update Department"}
          </PrimaryButton>
        </>
      }
    >
      <form
        onSubmit={handleSubmit(handleFormSubmit)}
        className="p-5 flex flex-col gap-4"
      >
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
          <FormField
            label="Department Name"
            required
            placeholder="e.g. Engineering"
            error={errors.name?.message}
            {...register("name")}
          />
          <FormField
            label="Department Code"
            required
            placeholder="e.g. ENG"
            error={errors.code?.message}
            {...register("code")}
          />
        </div>

        <FormField
          label="Description"
          placeholder="Enter department description"
          error={errors.description?.message}
          {...register("description")}
        />

        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
          <PaginatedSelect
            label="Parent Department"
            placeholder="Select parent (optional)"
            value={parentIdValue || ""}
            onValueChange={(value) => setValue("parent_id", value || null)}
            onLoadOptions={loadDepartments}
            error={errors.parent_id?.message}
          />
          <FormField
            label="Sort Order"
            type="number"
            placeholder="0"
            error={errors.sort_order?.message}
            {...register("sort_order", { valueAsNumber: true })}
          />
        </div>

        <FormSelect
          label="Status"
          required
          options={statusOptions}
          value={String(statusValue)}
          onValueChange={(value) => setValue("is_active", value === "true")}
          error={errors.is_active?.message}
        />
      </form>
    </Modal>
  );
};

interface ViewDepartmentModalProps {
  isOpen: boolean;
  onClose: () => void;
  department: Department | null;
}

export const ViewDepartmentModal = ({
  isOpen,
  onClose,
  department,
}: ViewDepartmentModalProps): ReactElement | null => {
  return (
    <Modal
      isOpen={isOpen}
      onClose={onClose}
      title="Department Details"
      description="View full information about this department"
      maxWidth="md"
      footer={<SecondaryButton onClick={onClose}>Close</SecondaryButton>}
    >
      {department && (
        <div className="p-5 grid grid-cols-1 md:grid-cols-2 gap-6">
          <div className="flex flex-col gap-4">
            <h3 className="text-sm font-semibold text-[#0f1724]">
              Basic Information
            </h3>
            <div className="grid grid-cols-1 gap-4">
              <div>
                <p className="text-xs font-medium text-[#9aa6b2] uppercase">
                  Name
                </p>
                <p className="text-sm text-[#0f1724] mt-1">{department.name}</p>
              </div>
              <div>
                <p className="text-xs font-medium text-[#9aa6b2] uppercase">
                  Code
                </p>
                <p className="text-sm text-[#0f1724] mt-1">{department.code}</p>
              </div>
              <div>
                <p className="text-xs font-medium text-[#9aa6b2] uppercase">
                  Status
                </p>
                <p className="text-sm text-[#0f1724] mt-1 capitalize">
                  {department.is_active ? "Active" : "Inactive"}
                </p>
              </div>
            </div>
          </div>

          <div className="flex flex-col gap-4">
            <h3 className="text-sm font-semibold text-[#0f1724]">
              Hierarchy & Stats
            </h3>
            <div className="grid grid-cols-1 gap-4">
              <div>
                <p className="text-xs font-medium text-[#9aa6b2] uppercase">
                  Parent Department
                </p>
                <p className="text-sm text-[#0f1724] mt-1">
                  {department.parent_name || "-"}
                </p>
              </div>
              <div>
                <p className="text-xs font-medium text-[#9aa6b2] uppercase">
                  Level
                </p>
                <p className="text-sm text-[#0f1724] mt-1">
                  {department.level}
                </p>
              </div>
              <div>
                <p className="text-xs font-medium text-[#9aa6b2] uppercase">
                  Sort Order
                </p>
                <p className="text-sm text-[#0f1724] mt-1">
                  {department.sort_order}
                </p>
              </div>
              <div>
                <p className="text-xs font-medium text-[#9aa6b2] uppercase">
                  Sub-departments
                </p>
                <p className="text-sm text-[#0f1724] mt-1">
                  {department.child_count || 0}
                </p>
              </div>
              <div>
                <p className="text-xs font-medium text-[#9aa6b2] uppercase">
                  Users
                </p>
                <p className="text-sm text-[#0f1724] mt-1">
                  {department.user_count || 0}
                </p>
              </div>
            </div>
          </div>

          <div className="col-span-1 md:col-span-2">
            <p className="text-xs font-medium text-[#9aa6b2] uppercase">
              Description
            </p>
            <p className="text-sm text-[#0f1724] mt-1 bg-[#f5f7fa] p-3 rounded-md border border-[rgba(0,0,0,0.05)]">
              {department.description || "No description provided."}
            </p>
          </div>

          <div className="col-span-1 md:col-span-2 text-xs text-[#9aa6b2]">
            <span>
              Created: {new Date(department.created_at).toLocaleString()}
            </span>
            <span className="mx-2">|</span>
            <span>
              Updated: {new Date(department.updated_at).toLocaleString()}
            </span>
          </div>
        </div>
      )}
    </Modal>
  );
};
