import { MultiSelect } from "@/shared/common/ui/multi-select";
import {
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/shared/common/ui/form";
import { Textarea } from "@/shared/common/ui/textarea";
import { useForm, FormProvider } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { Button } from "@/shared/common/ui/button";
import useSettings from "@/record-management/components/hooks/useSettings";
import { useUserDetail } from "@/record-management/components/hooks/useUserDetail";
import {
  AssignIncomingRecordPayload,
  AssignRecordDto,
  PositionDto,
  PositionHolderDto,
} from "@/record-management/dto/userRecords/usersDto";
import { toast } from "sonner";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from "@/shared/common/ui/dialog";
import { useCreateIncomingRecords } from "@/record-management/components/hooks/useCreateIncomingRecord";
import { useTranslation } from "react-i18next";
import { useErrorHandler } from "@/shared/hooks/useErrorHandler";
import { useLocalizedName } from "@/shared/common/localizedName";
import { FormMultiSelectField } from "@/shared/common/form/fields/FormFields";
import { OrganizationsPositions } from "@/record-management/services/api/departmentService";
import { EmployeeWithUnitDto } from "@/user-management/dto/employees/employees";
import { KeyValue } from "@/record-management/types/recordSelectTypes";

interface AssignRecordProps {
  isOpen?: boolean;
  record: AssignRecordDto;
  onSuccess: () => void;
  onClose: () => void;
}

export interface StartAssignRecord {
  id: string;
}

const assignmentSchema = z
  .object({
    receivingDepartments: z.array(z.string()),
    assignedEmployees: z.array(z.string()),
    remarks: z.string(),
  })
  .refine(
    (data) =>
      data.receivingDepartments.length > 0 || data.assignedEmployees.length > 0,
    {
      message: "Either position or employee is required",
      path: ["receivingDepartments"],
    },
  );

const AssigneIncomingRecord = ({
  isOpen = false,
  record,
  onSuccess,
  onClose,
}: AssignRecordProps) => {
  const form = useForm<z.infer<typeof assignmentSchema>>({
    resolver: zodResolver(assignmentSchema),
    defaultValues: {
      receivingDepartments: [],
      assignedEmployees: [],
      remarks: "",
    },
  });

  const {
    listPositionResponse,
    listAllDepartmentResponse,
    currentEmployeesResponse,
  } = useSettings();

  const { permissionKeys } = useUserDetail();
  const { t } = useTranslation();
  const { handleError } = useErrorHandler(t);
  const localizedName = useLocalizedName();
  const departmentOptions = listAllDepartmentResponse.map((d) => ({
    label: localizedName(d.name),
    value: String(d.id), // make sure it’s a string
  }));

  const employeesList: KeyValue[] =
    currentEmployeesResponse?.items
      .filter((e) => e.employeePositions?.[0]?.id) // only include valid IDs
      .map((employee) => ({
        label: localizedName(employee.user.name),
        value: String(employee.employeePositions[0].id),
        employeePositionId: String(employee.employeePositions[0].id),
      })) || [];

  const employeeOptions = Array.isArray(listPositionResponse)
    ? listPositionResponse.flatMap((unit: PositionHolderDto) =>
        unit.employeePositions.map((pos) => ({
          label: localizedName(unit.user?.name) || "Unnamed employee",
          value: pos.id,
          positionId: pos.positionId,
        })),
      )
    : [];

  const {
    assignIncomingRecord,
    startAssignIncomingRecordMutation: startAssigningRecord,
    isPending,
  } = useCreateIncomingRecords();

  const handleFormSubmit = form.handleSubmit(async (values) => {
    try {
      if (!record?.id) throw new Error("Record id missing");

      const selectedDepartments = values.receivingDepartments || [];
      const selectedEmployees = values.assignedEmployees || [];

      const employeePositions = selectedEmployees
        .map((employeeId) => {
          const empIdStr = employeeId.toString();
          const match = employeeOptions.find(
            (emp) => emp.value.toString() === empIdStr,
          );
          if (!match) return null;
          return {
            positionId: match.positionId,
            employeePositionId: empIdStr,
          };
        })
        .filter((pos): pos is NonNullable<typeof pos> => pos !== null);

      if (selectedDepartments.length === 0 && employeePositions.length === 0)
        throw new Error("No departments or employees selected for assignment.");

      const employeePositionIds = employeePositions.map(
        (p) => p.employeePositionId,
      );

      // Prepare payload logic
      let payload: AssignIncomingRecordPayload;

      // ✅ If multiple record boxes exist, start assignment first
      if (record.recordBoxes.length === 0) {
        startAssigningRecord(record.id, {
          onSuccess: (response) => {
            payload = {
              recordBoxId: response.recordBoxes[0],
              recordId: response.recordId,
              employeePositionIds,
              positionIds:
                selectedDepartments.length > 0 ? selectedDepartments : [],
              comment: values.remarks,
            };

            assignIncomingRecord(payload, {
              onSuccess: () => {
                form.reset();
                onSuccess();
                onClose();
              },
              onError: (error) => {
                handleError(error);
              },
            });
          },
          onError: (error) => {
            handleError(error);
          },
        });
      } else {
        // ✅ Directly assign without starting
        payload = {
          recordBoxId: record.recordBoxes[0].id,
          recordId: record.id,
          employeePositionIds,
          positionIds:
            selectedDepartments.length > 0 ? selectedDepartments : [],
          comment: values.remarks,
        };

        assignIncomingRecord(payload, {
          onSuccess: () => {
            form.reset();
            onSuccess();
            onClose();
          },
          onError: (error) => {
            handleError(error);
          },
        });
      }
    } catch (err) {
      console.error("Form submit error:", err);
      toast.error("Something went wrong while submitting the form");
    }
  });

  return (
    <Dialog
      open={isOpen}
      onOpenChange={(open) => {
        if (!isPending) {
          if (!open) onClose();
        }
      }}
    >
      <DialogContent
        className="sm:max-w-[425px] bg-white dark:bg-gray-800 max-h-[90vh] flex flex-col"
        onEscapeKeyDown={(e) => isPending && e.preventDefault()}
        onPointerDownOutside={(e) => isPending && e.preventDefault()}
      >
        <DialogHeader>
          <DialogTitle>{t("userIncoming.Assign Record")}</DialogTitle>
          <DialogDescription>
            {t("userIncoming.Assign this record to one or more departments")}
          </DialogDescription>
        </DialogHeader>

        <FormProvider {...form}>
          <form onSubmit={handleFormSubmit} className="flex flex-col flex-1 overflow-hidden">
            <div className="flex-1 overflow-y-auto px-4 space-y-4">
              <FormMultiSelectField
                control={form.control}
                name="receivingDepartments"
                label={t("userIncoming.Department")}
                options={departmentOptions}
                placeholder={t("userIncoming.Department")}
                maxCount={5}
              />

              <FormMultiSelectField
                control={form.control}
                name="assignedEmployees"
                label={t("userIncoming.Employees")}
                options={employeesList}
                placeholder={t("userIncoming.Employees")}
                maxCount={5}
              />

              {!permissionKeys.includes("can:dispatchRecords") && (
                <FormField
                  control={form.control}
                  name="remarks"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>{t("userIncoming.Remark")}</FormLabel>
                      <Textarea
                        rows={4}
                        placeholder={t("userIncoming.Remark") + "..."}
                        {...field}
                      />
                      <FormMessage />
                    </FormItem>
                  )}
                />
              )}

            </div>

            <DialogFooter className="border-t border-gray-200 dark:border-gray-700 pt-4 mt-4">
              <Button type="button" variant="outline" onClick={onClose}>
                {t("common.Cancel")}
              </Button>
              <Button type="submit" disabled={isPending}>
                {isPending
                  ? t("userIncoming.Assigning...")
                  : t("userIncoming.Assign")}
              </Button>
            </DialogFooter>
          </form>
        </FormProvider>
      </DialogContent>
    </Dialog>
  );
};

export default AssigneIncomingRecord;
