"use client";
import { Combobox } from "@/components/combobox";
import { SearchReportTo } from "@/components/pages/add-emp/searchReportTo";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Input } from "@/components/ui/input";
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { useToast } from "@/components/ui/use-toast";
import Axios from "@/lib/Axios";
import { RespError } from "@/types/auth";
import { CustomerDataT } from "@/types/customer";
import { UserListT } from "@/types/user";
import { yupResolver } from "@hookform/resolvers/yup";
import { Separator } from "@radix-ui/react-separator";
import { useMutation } from "@tanstack/react-query";
import { AxiosError, AxiosResponse } from "axios";
import { PlusIcon, Trash2 } from "lucide-react";
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
import { useFieldArray, useForm } from "react-hook-form";
import CustomerFormPreview from "../../_helper/customerFormPreview";
import OrdersAndNotes from "../../_helper/ordersAndNotes";
import { format } from "date-fns";
import {
  AddressSchemaT,
  CustomerManageSchemaT,
  DncCheckerSchemaT,
  FormType,
  addressSchema,
  customerManageSchema,
  dncCheckerSchema,
} from "../../_helper/schema";
import useUserStore from "@/store/useUserStore";
import { string } from "yup";

export type CustomerDetailsPlaceholder = {
  dnc: string;
  assigned_to_id: string;
  title: string;
  iso: string;
};

type FormKeys = keyof CustomerManageSchemaT & keyof AddressSchemaT;

const titles = ["Mr", "Miss", "Mrs", "Ms", "Dr", "Rev"];
const iso = ["GB-ENG", "GB-NIR", "GB-SCT", "GB-WLS"];

const dncFields = ["email", "home_phone", "mobile_phone"];

const CustomerManage = ({ params }: { params: { slug: string } }) => {
  const [dncChecker, setDncChecker] = useState<boolean>();
  const [customerAddress, setCustomerAddress] = useState<any[]>([]);

  const schema = !!params?.slug?.length
    ? customerManageSchema
    : customerManageSchema.concat(addressSchema);

  const [setschemaAccordingDnc, setSetschemaAccordingDnc] =
    useState<FormType>();

  const {
    register,
    handleSubmit,
    setValue,
    reset,
    watch,
    getValues,
    control,
    formState: { errors, isSubmitting },
  } = useForm<FormType>({
    defaultValues: {
      is_land_line_default: false,
    },
    resolver: yupResolver(setschemaAccordingDnc as any),
  });

  const dnc = watch("DNC");
  const defaultNumber = watch("is_land_line_default");

  const { name } = register("is_land_line_default");

  const [placeholder, setPlaceholder] = useState<CustomerDetailsPlaceholder>({
    dnc: "",
    assigned_to_id: "",
    title: "",
    iso: "",
  });

  const { fields, append, prepend, remove, swap, move, insert } = useFieldArray(
    {
      control,
      name: "address",
    }
  );

  const { toast } = useToast();
  const router = useRouter();

  const mutationSend = useMutation<
    AxiosResponse<any>,
    AxiosError<RespError>,
    any
  >({
    mutationFn: sendData,
    onSuccess: (data) => {
      toast({
        title: "Success",
        description: "Customer has been saved successfully",
      });
      router.push("/customer");
    },
    onError: (error) => {
      // Check if the error response has a message field
      const errorMessage = error.response?.data?.message || "An unexpected error occurred";
      toast({
        variant: "destructive",
        title: "Error",
        description: errorMessage,
      });
    },
  });

  const datas = useUserStore((state) => state.data);
  const [hydrated, setHydrated] = useState(false);
  const [createdAt, setCreatedAt] = useState<string | null>(null);

  useEffect(() => {
    setHydrated(true);
  }, []);

  // Redirect to /login if data is null or blank, but only after hydration
  useEffect(() => {
    if (hydrated && (!datas || !datas.tokens?.access)) {
      router.push("/login");
    }
  }, [hydrated, datas, router]);

  // Get user role and permissions
  const userRole = datas?.role;
  const userPermissions = datas?.permissions || [];
  const canChangeAssignedTo =
    userRole === "Admin" ||
    userRole === "Owner" ||
    userPermissions.some((perm: any) => perm.codename === "can_change_assigned_to");

  function sendData(data?: CustomerManageSchemaT) {
    if (!!params?.slug?.length) {
      return Axios.patch("/customer/management/" + params?.slug[0] + "/", data);
    } else {
      return Axios.post("/customer/management/", data);
    }
  }

  async function getData() {
    try {
      // Use .data.data to get the actual customer object from the API response
      const resp = await Axios.get("/customer/management/" + params?.slug[0])
        .then((res) => res.data.data);

      setDncChecker(resp.DNC);

      // Store created date/time for header display
      if (resp.created_at || resp.createdAt) {
        setCreatedAt(resp.created_at || resp.createdAt);
      }

      // Set placeholder values
      const newPlaceholder: CustomerDetailsPlaceholder = {
        dnc: resp.DNC ? "Allow" : "Not Allow",
        assigned_to_id: resp.assigned_to?.user?.name ?? "",
        title: resp.title ?? "",
        iso: resp.iso ?? "",
      };
      setPlaceholder(newPlaceholder);

      // Store customer address for display
      setCustomerAddress(resp.address || []);

      // Base form data
      const obj: CustomerManageSchemaT = {
        DNC: resp.DNC,
        first_name: resp.first_name ?? "",
        last_name: resp.last_name ?? "",
        iso: resp.iso ?? "",
        assigned_to_id: resp.assigned_to?.id?.toString() ?? "",
        title: resp.title ?? "",
        is_land_line_default: resp.is_land_line_default ?? false,
      };

      // If DNC is false, include contact fields
      if (!resp.DNC) {
        const contactFields: DncCheckerSchemaT = {
          email: resp.email ?? "",
          home_phone: resp.home_phone ?? "",
          mobile_phone: resp.mobile_phone ?? "",
        };
        reset({ ...obj, ...contactFields });
      } else {
        reset(obj);
      }

      // Optionally, you can store notes and address in state if you want to pass them to child components
      // setCustomerNotes(resp.customer_notes);
      // setCustomerAddress(resp.address);
    } catch (error) {
      toast({
        variant: "destructive",
        title: "Error",
        description: "Failed to fetch customer data",
      });
    }
  }

  async function onSubmit(dt: CustomerManageSchemaT & AddressSchemaT) {
    const data = JSON.parse(
      JSON.stringify(dt)
    ) as unknown as CustomerManageSchemaT & AddressSchemaT;

    Object.keys(data).forEach((key) => {
      if (typeof data[key as FormKeys] === "string") {
        if (data[key as FormKeys] === "") {
          (data as any)[key as FormKeys] = null;
        }
      }
    });

    let countPrimaryAddress = 0;
    if (fields.length > 0 && !params?.slug?.[0]) {
      data.address?.forEach((address) => {
        if (address.primary === true) countPrimaryAddress += 1;
      });

      if (countPrimaryAddress === 0) {
        toast({
          title: "Address",
          description: "Select one primary address ",
          variant: "destructive",
        });
        return;
      }
      if (countPrimaryAddress > 1) {
        toast({
          title: "Address",
          description: "Select only one primary address ",
          variant: "destructive",
        });
        return;
      }
    }

    if (dncChecker) {
      dncFields.forEach((item) => {
        delete (data as any)[item];
      });
    }

    await mutationSend.mutateAsync(data);
  }

  useEffect(() => {
    console.log(errors);
  }, [errors]);

  useEffect(() => {
    if (!!params?.slug?.length) {
      getData();
    } else {
      const shma = schema.concat(dncCheckerSchema) as unknown as FormType;
      setSetschemaAccordingDnc(shma);
    }
  }, []);

  useEffect(() => {
    if (!!params?.slug?.length) {
      if (dncChecker === false) {
        const shma = schema.concat(dncCheckerSchema) as unknown as FormType;
        setSetschemaAccordingDnc(shma);
      } else {
        setSetschemaAccordingDnc(schema as any);
      }
    }
  }, [dncChecker]);

  if (!hydrated) return null;

  return (
    <>
      <div className="grid grid-cols-2 gap-14 h-[20rem] mt-10 mb-20">
        <form
          onSubmit={handleSubmit(onSubmit)}
          className="left-card border rounded-sm h-full overflow-hidden overflow-y-scroll"
        >
          <div className="bg-secondary flex items-center justify-between gap-10 py-3 pl-6 pr-6">
            <div className="flex items-center gap-4">
              <div className="relative">
                <Avatar className="w-16 h-16">
                  <AvatarImage src="/assets/images/user.png" />
                  <AvatarFallback>Profile</AvatarFallback>
                </Avatar>
              </div>
              <p className="text-white text-xl">Customer Details</p>
            </div>
            {createdAt && (
              <div className="text-right text-white text-sm">
                <p className="font-medium">
                  Created on{" "}
                  {format(
                    new Date(createdAt),
                    "dd MMM, yyyy"
                  )}
                </p>
                {/* <p className="text-xs opacity-90">
                  at{" "}
                  {format(
                    new Date(createdAt),
                    "h:mm aa"
                  )}
                </p> */}
              </div>
            )}
          </div>

          <p className="px-10 my-8 font-semibold text-xl">Basic Details</p>

          <div className="px-10 grid grid-cols-2 gap-8 mt-8">
            <div className="flex gap-2">
              <div className="w-32">
                <div className="h-7">
                  {placeholder.title && (
                    <label htmlFor="" className="text-sm">
                      Title
                    </label>
                  )}
                </div>
                <Select
                  value={watch("title") || ""}
                  onValueChange={(e) => {
                    setValue("title", e);
                    setPlaceholder((prev) => ({ ...prev, title: e }));
                  }}
                >
                  <SelectTrigger className="">
                    <SelectValue placeholder={placeholder.title || "Title"} />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectGroup>
                      {titles.map((title, key) => (
                        <SelectItem key={key} value={title}>
                          {title}.
                        </SelectItem>
                      ))}
                    </SelectGroup>
                  </SelectContent>
                </Select>
                <p className="text-xs text-red-500">{errors.title?.message}</p>
              </div>
              <Input
                makePlacholderAsLabel
                capitalize
                {...register("first_name")}
                placeholder="First name"
                className="rounded-none"
                errorMsg={errors.first_name?.message}
              />
            </div>
            <Input
              makePlacholderAsLabel
              capitalize
              {...register("last_name")}
              placeholder="Last name"
              className="rounded-none"
              errorMsg={errors.last_name?.message}
            />
            {!dncChecker && (
              <>
                <Input
                  makePlacholderAsLabel
                  capitalize
                  {...register("home_phone")}
                  placeholder="Landline no"
                  className="rounded-none"
                  errorMsg={errors.home_phone?.message}
                />
                <Input
                  makePlacholderAsLabel
                  capitalize
                  {...register("mobile_phone")}
                  placeholder="Mobile no"
                  className="rounded-none"
                  errorMsg={errors.mobile_phone?.message}
                />
                <div className="flex flex-col self-center">
                  <label htmlFor="" className="text-sm">
                    Select default number
                  </label>
                  <div className="flex gap-5">
                    <div className="flex items-center">
                      <input
                        checked={defaultNumber === false}
                        onChange={(e) =>
                          setValue(
                            "is_land_line_default",
                            JSON.parse(e.target.value)
                          )
                        }
                        name={name}
                        className="w-fit bg-pink-100"
                        type="radio"
                        value="false"
                        id="Landline No"
                      />
                      <label className="text-sm ml-2" htmlFor="Landline No">
                        Landline No.
                      </label>
                    </div>
                    <div className="flex items-center">
                      <input
                        checked={defaultNumber === true}
                        onChange={(e) =>
                          setValue(
                            "is_land_line_default",
                            JSON.parse(e.target.value)
                          )
                        }
                        name={name}
                        value="true"
                        className="w-fit bg-pink-100"
                        type="radio"
                        id="mobile no"
                      />
                      <label className="text-sm ml-2" htmlFor="mobile no">
                        Mobile No.
                      </label>
                    </div>
                  </div>
                </div>
                <Input
                  makePlacholderAsLabel
                  {...register("email")}
                  placeholder="Email ID"
                  className="rounded-none"
                  errorMsg={errors.email?.message}
                />
              </>
            )}

            <div className="w-32">
              <div className="h-7">
                {placeholder.iso && (
                  <label htmlFor="" className="text-sm">
                    ISO
                  </label>
                )}
              </div>
              <Select
                value={watch("iso") || ""}
                onValueChange={(e) => {
                  setValue("iso", e);
                  setPlaceholder((prev) => ({ ...prev, iso: e }));
                }}
              >
                <SelectTrigger className="">
                  <SelectValue placeholder={placeholder.iso || "ISO"} />
                </SelectTrigger>
                <SelectContent>
                  <SelectGroup>
                    {iso.map((title, index) => (
                      <SelectItem key={index} value={title}>
                        {title}.
                      </SelectItem>
                    ))}
                  </SelectGroup>
                </SelectContent>
              </Select>
              <p className="text-xs text-red-500">{errors.iso?.message}</p>
            </div>

            {/* Conditionally render Assign to */}
            {canChangeAssignedTo && (
              <div className="">
                <div className="h-6">
                  {placeholder.assigned_to_id && (
                    <label htmlFor="" className="text-sm">
                      Assign to
                    </label>
                  )}
                </div>
                <Combobox<UserListT>
                  placeholder={placeholder.assigned_to_id || "Assign to"}
                  onSelect={(e) => {
                    if (e === null) {
                      setValue("assigned_to_id", "");
                      setPlaceholder((prev) => ({
                        ...prev,
                        assigned_to_id: "",
                      }));
                      return;
                    }
                    setValue("assigned_to_id", String(e.id));
                    setPlaceholder((prev) => ({
                      ...prev,
                      assigned_to_id: e.user.name,
                    }));
                  }}
                >
                  <SearchReportTo />
                </Combobox>
                <p className="text-xs text-red-500">
                  {errors.assigned_to_id?.message}
                </p>
              </div>
            )}
          </div>

          <div className="mb-4 px-10 my-8">
            <input
              onChange={(e) => {
                setValue("DNC", e.target.checked);
                setDncChecker(e.target.checked);
              }}
              id="dnc"
              type="checkbox"
              checked={dnc ?? false}
              className="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
            />
            <label
              htmlFor="dnc"
              className="ms-2 text-sm font-medium text-gray-900 dark:text-gray-300"
            >
              DNC
            </label>
            <p className="text-xs text-red-500">{errors.DNC?.message}</p>
          </div>

          {/* Address section for both create and edit modes */}
          {!params?.slug?.length && (
            <div className="px-10 my-8">
              <div className="flex justify-between">
                <p className="text-xl text-gray-500">Create Address</p>
                <PlusIcon
                  className="text-gray-500 border cursor-pointer"
                  onClick={() => {
                    append({
                      address1: "",
                      address2: "",
                      country: "United Kingdom",
                      county: "",
                      post_code: "" as any,
                      town_city: "",
                      primary: false,
                    });
                  }}
                />
              </div>
              <Separator className="h-[1px] bg-gray-200" />
              <p className="text-xs text-red-500 mt-5">
                {errors.address?.message}
              </p>
              <div className="">
                {fields.map((address, index, arr) => (
                  <div className="" key={index}>
                    <div className="flex justify-between mt-8">
                      <p className="text-xl text-gray-500">
                        Address {index + 1}
                      </p>
                      <Trash2
                        className="text-gray-500 cursor-pointer p-1"
                        onClick={() => {
                          remove(index);
                        }}
                      />
                    </div>

                    <div className="grid grid-cols-2 gap-8 mt-5" key={address.id}>
                      <Input
                        capitalize
                        makePlacholderAsLabel
                        {...register(`address.${index}.address1`)}
                        placeholder="address 1"
                        className="rounded-none"
                        errorMsg={errors.address?.[index]?.address1?.message}
                      />
                      <Input
                        capitalize
                        makePlacholderAsLabel
                        {...register(`address.${index}.address2`)}
                        placeholder="Address 2"
                        className="rounded-none"
                        errorMsg={errors.address?.[index]?.address2?.message}
                      />
                      <Input
                        capitalize
                        makePlacholderAsLabel
                        {...register(`address.${index}.town_city`)}
                        placeholder="Town city"
                        className="rounded-none"
                        errorMsg={errors.address?.[index]?.town_city?.message}
                      />
                      <Input
                        capitalize
                        makePlacholderAsLabel
                        {...register(`address.${index}.county`)}
                        placeholder="County"
                        className="rounded-none"
                        errorMsg={errors.address?.[index]?.county?.message}
                      />
                      
                      <Input
                        capitalize
                        makePlacholderAsLabel
                        {...register(`address.${index}.post_code`)}
                        placeholder="Post code"
                        className="rounded-none"
                        errorMsg={errors.address?.[index]?.post_code?.message}
                      />
                      <Input
                        capitalize
                        makePlacholderAsLabel
                        {...register(`address.${index}.country`)}
                        placeholder="Country"
                        className="rounded-none"
                        errorMsg={errors.address?.[index]?.country?.message}
                      />
                      <div className="flex items-center space-x-2">
                        <Checkbox
                          id={"addressCheck" + index}
                          onCheckedChange={(e) => {
                            setValue(`address.${index}.primary`, e as boolean);
                          }}
                        />
                        <label
                          htmlFor={"addressCheck" + index}
                          className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
                        >
                          Set primary address
                        </label>
                      </div>
                    </div>

                    {arr.length !== index + 1 && (
                      <Separator className="h-[1px] bg-gray-200 mt-8" />
                    )}
                  </div>
                ))}
              </div>
            </div>
          )}

          {/* Read-only address section for edit mode */}
          {!!params?.slug?.length && customerAddress.length > 0 && (
            <div className="px-10 my-8">
              <div className="flex justify-between">
                <p className="text-xl text-gray-500">Address Information</p>
              </div>
              <Separator className="h-[1px] bg-gray-200" />
              <div className="">
                {customerAddress.map((address, index) => (
                  <div className="" key={index}>
                    <div className="flex justify-between mt-8">
                      <p className="text-xl text-gray-500">
                        Address {index + 1} {address.primary && "(Primary)"}
                      </p>
                    </div>

                    <div className="grid grid-cols-2 gap-8 mt-5">
                      <div className="space-y-1">
                        <label className="text-sm text-gray-600">Address 1</label>
                        <div className="p-3 bg-gray-50 rounded border text-sm">
                          {address.address1 || "N/A"}
                        </div>
                      </div>
                      <div className="space-y-1">
                        <label className="text-sm text-gray-600">Address 2</label>
                        <div className="p-3 bg-gray-50 rounded border text-sm">
                          {address.address2 || "N/A"}
                        </div>
                      </div>
                      <div className="space-y-1">
                        <label className="text-sm text-gray-600">Town City</label>
                        <div className="p-3 bg-gray-50 rounded border text-sm">
                          {address.town_city || "N/A"}
                        </div>
                      </div>
                      <div className="space-y-1">
                        <label className="text-sm text-gray-600">County</label>
                        <div className="p-3 bg-gray-50 rounded border text-sm">
                          {address.county || "N/A"}
                        </div>
                      </div>
                      <div className="space-y-1">
                        <label className="text-sm text-gray-600">Post Code</label>
                        <div className="p-3 bg-gray-50 rounded border text-sm">
                          {address.post_code || "N/A"}
                        </div>
                      </div>
                      <div className="space-y-1">
                        <label className="text-sm text-gray-600">Country</label>
                        <div className="p-3 bg-gray-50 rounded border text-sm">
                          {address.country || "N/A"}
                        </div>
                      </div>
                    </div>

                    {customerAddress.length !== index + 1 && (
                      <Separator className="h-[1px] bg-gray-200 mt-8" />
                    )}
                  </div>
                ))}
              </div>
            </div>
          )}

          <div className="flex justify-center">
            <Button
              type="submit"
              disabled={isSubmitting}
              className="w-80 mx-auto my-5"
            >
              SAVE
            </Button>
          </div>
        </form>

        {!!params?.slug?.length ? (
          <OrdersAndNotes id={Number(params?.slug?.[0])} />
        ) : (
          <CustomerFormPreview placeholder={placeholder} watch={watch} />
        )}
      </div>
    </>
  );
};

export default CustomerManage;