"use client";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import {
  Loader,
  Mail,
  Package,
  Pencil,
  Phone,
  PlusIcon,
  PoundSterling,
  Smartphone,
} from "lucide-react";

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { toast } from "@/components/ui/use-toast";
import Axios from "@/lib/Axios";
import { RespError } from "@/types/auth";
import { AddressT, CustomerDataT } from "@/types/customer";
import { yupResolver } from "@hookform/resolvers/yup";
import { useMutation, useQuery } from "@tanstack/react-query";
import { AxiosError, AxiosResponse } from "axios";
import Link from "next/link";
import { useEffect, useState } from "react";
import { useFieldArray, useForm } from "react-hook-form";
import {
  AddressNSchemaT,
  AddressSchemaT,
  addressN,
  addressSchema,
} from "./schema";
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Checkbox } from "@/components/ui/checkbox";
import { Separator } from "@/components/ui/separator";
import { getCurrentUserId } from "@/lib/jwtUtils";
import { Badge } from "@/components/ui/badge";
import useUserStore from "@/store/useUserStore";

export default function CustomerViewDetails({
  customerId,
}: {
  customerId: number;
}) {
  const { data, error, isLoading, isSuccess, refetch } = useQuery({
    queryKey: ["customer-details"],
    queryFn: fetchData,
  });

  const [primaryAddress, setPrimaryAddress] = useState<AddressT>();
  const [showEdit, setShowEdit] = useState<boolean>(false);
  const [addressManager, setAddressManager] = useState<boolean>(false);

  async function fetchData() {
    return Axios.get("/customer/management/" + customerId + "/").then((res) => {
      const customer = res.data.data;
      const address = (customer.address as AddressT[]).find((add) => add.primary);
      if (address) setPrimaryAddress(address);
      return customer;
    });
  }

  // Get user data for access control
  const userData = useUserStore((state) => state.data);
  
  // Check if current user has access to this customer
  const currentUserId = getCurrentUserId(userData);
  const userRole = userData?.role;
  
  // Admin and Owner have access to all customers
  const isAdminOrOwner = userRole === 'Admin' || userRole === 'Owner';
  
  const isCreatedByUser = data?.created_by?.id === currentUserId;
  const isAssignedToUser = data?.assigned_to?.id === currentUserId;
  const hasAccess = isAdminOrOwner || isCreatedByUser || isAssignedToUser;

  return (
    <div className="left-card border rounded-sm h-[50rem] overflow-hidden overflow-y-scroll">
      <div className="bg-secondary flex items-center justify-between gap-10 py-3 px-5 pl-6 h-16">
        <p className="text-white text-xl ">Customer Details</p>
        <div className="flex items-center gap-5">
          {hasAccess && (
            <div className="">
              <p className="text-sm flex gap-2 bg-white p-2 items-center rounded-sm">
                Credit Note:{" "}
                <span className="flex items-center text-danger">
                  <PoundSterling className="w-4 h-4" />
                  <span className="font-semibold">0</span>
                </span>
              </p>
            </div>
          )}
          {hasAccess && (
            <Link
              href={`/customer/customer-manage/${data?.id}/?firstName=${data?.first_name}&lastName=${data?.last_name}`}
              className="text-white cursor-pointer"
            >
              <Pencil className="w-5" />
            </Link>
          )}
        </div>
      </div>
      <div className="relative grid grid-cols-2 items-center py-8 w-12/12 gap-8 px-8">
        <div className="relative">
          <Avatar className="w-16 h-16">
            <AvatarImage src="/assets/images/user.png" />
            <AvatarFallback>Profile</AvatarFallback>
          </Avatar>
        </div>

        <div className="space-y-5">
          <p className="text-danger">{data?.id ?? "NA"}</p>

          <p className="">
  {`${data?.title ? `${data.title} ` : ""}${data?.first_name ?? ""} ${
    data?.last_name ?? ""
  }`}
</p>
        </div>
      </div>
      <div className="px-8">
        <div className="bg-gray-200 w-full h-[1px]"></div>
      </div>
      <div className="space-y-8 px-8 mt-5">
        {/* Status field - always visible */}
        <div className="grid grid-cols-2 justify-start gap-8">
          <p className="text-danger text-lg">Status</p>
          <div className="flex gap-2 items-center text-sm">
            <Badge
              className={`${
                data?.DNC ? "bg-brownish" : "bg-primary"
              }`}
            >
              {data?.DNC ? "DNC" : "Active"}
            </Badge>
          </div>
        </div>

        {/* Contact Info - only show if user has access */}
        {hasAccess && (
          <div className="grid grid-cols-2 justify-start gap-8 relative">
            <p className="text-danger text-lg">Contact Info</p>
            <div className="text-sm space-y-2">
              <div className="flex gap-2 items-center">
                <div className="">
                  <Mail className="w-5" />
                </div>{" "}
                {data?.email ?? ""}
              </div>
              <div className="flex gap-2 items-center">
                <div className="">
                  <Smartphone className="w-5" />
                </div>
                {data?.mobile_phone ?? ""}
              </div>
              <div className="flex gap-2 items-center">
                <div className="">
                  <Phone className="w-5" />
                </div>
                {data?.home_phone ?? ""}
              </div>
            </div>
          </div>
        )}
        <div className="">
          <div className="border-b"></div>

          <div className="grid grid-cols-2 justify-start gap-8 mt-5">
            <p className="text-danger text-lg">Created By</p>
            <div className="flex gap-2 items-center text-sm">
              {data?.created_by?.user?.name ?? ""}
            </div>
          </div>
        </div>

        <div className="">
          <div className="border-b"></div>
          <div className="grid grid-cols-2 justify-start  gap-8 mt-5">
            <p className="text-danger text-lg ">Assigned To</p>
            <div className="flex gap-2 items-center text-sm">
              {data?.assigned_to?.user?.name ?? ""}
            </div>
          </div>
        </div>

        {/* Primary Address - only show if user has access */}
        {hasAccess && (
          <div className="">
            <div className="border-b"></div>

            <div className="grid grid-cols-2 justify-start gap-8 mt-5 relative">
              <p className="text-danger text-lg">Primary Address</p>
              <div className="flex gap-2 w-[90%] items-start text-sm">
                <div className="">
                  <Package className="w-5" />
                </div>
                <div className="">
                  <p className="">
                    {primaryAddress?.address1 ?? ""}{" "}
                    {primaryAddress?.address1 && ","}
                  </p>
                  <p className="">
                    {primaryAddress?.address2 ?? ""}
                    {primaryAddress?.address2 && ","}
                  </p>
                  <p className="">
                    {primaryAddress?.town_city ?? ""}{" "}
                    {primaryAddress?.town_city && ","}
                  </p>
                  <p className="">
                    {primaryAddress?.country ?? ""}{" "}
                    {primaryAddress?.country && ","}
                  </p>
                  <p className="">
                    {primaryAddress?.post_code ?? ""}{" "}
                    {primaryAddress?.post_code && ","}
                  </p>
                </div>
              </div>
              <span
                className="absolute right-1 cursor-pointer"
                onClick={() => {
                  setShowEdit((prev) => !prev);
                }}
              >
                <Pencil className="w-5" />
              </span>
            </div>
          </div>
        )}

        {/* Orders - only show if user has access */}
        {hasAccess && (
          <div className="">
            <div className="border-b"></div>
            <div className="grid grid-cols-2 justify-start  gap-8 mt-5">
              <p className="text-danger text-lg w-10">Orders</p>
              <div className="flex gap-2 items-center text-sm">
                <Package className="w-5" />0 nos
              </div>
            </div>
          </div>
        )}
      </div>
      {hasAccess && showEdit && (
        <EditPrimaryAddress
          refetch={refetch}
          defaultValue={primaryAddress!}
          id={customerId}
          customerData={data}
        />
      )}

      {hasAccess && (
        <p
          className="px-8 my-6 text-xs text-brownish cursor-pointer"
          onClick={() => {
            setAddressManager((prev) => !prev);
          }}
        >
          Change Primary Address
        </p>
      )}

      {hasAccess && addressManager && (
        <ChangePrimaryAddress customerData={data} refetch={refetch} />
      )}
    </div>
  );
}

function EditPrimaryAddress({
  id,
  defaultValue,
  refetch,
  customerData,
}: {
  id: number;
  defaultValue: AddressT;
  refetch: () => Promise<any>;
  customerData: CustomerDataT | undefined;
}) {
  const {
    register,
    handleSubmit,
    setValue,
    reset,
    watch,
    control,
    formState: { errors, isSubmitting },
  } = useForm<AddressNSchemaT>({
    resolver: yupResolver(addressN),
    defaultValues: {
      ...(defaultValue as unknown as AddressNSchemaT),
    },
  });

  const mutationSend = useMutation<
    AxiosResponse<any>,
    AxiosError<RespError>,
    any
  >({
    mutationFn: sendData,
    onSuccess: async (data) => {
      toast({
        title: "Success",
        description: "Customer has been saved successfully",
      });

      await refetch();
    },
    onError: (error) => {
      const errorObj: Record<any, string[]> = error.response?.data.data!;
      let message = "";
      for (let key in errorObj) {
        if (errorObj.hasOwnProperty(key)) {
          let value = errorObj[key];
          message += key + " " + value[0] + "\n";
        }
      }
      toast({
        variant: "destructive",
        title: "Error",
        description: message,
      });
    },
  });

  function sendData(data?: AddressNSchemaT) {
    return Axios.patch("/customer/management/" + id + "/update_address/", data);
  }

  async function onSubmit(data: AddressNSchemaT) {
    const newData = { ...data, address_id: defaultValue.id };

    await mutationSend.mutateAsync(newData);
  }

  useEffect(() => {
    reset(defaultValue as unknown as AddressNSchemaT);
  }, [defaultValue]);

  return (
    <div className="mt-10">
      <form onSubmit={handleSubmit(onSubmit)}>
        <div className="grid grid-cols-2 gap-8 mt-9 px-8 ">
          <Input
            capitalize
            makePlacholderAsLabel
            {...register(`address1`)}
            placeholder="address 1"
            className="rounded-none"
            errorMsg={errors.address1?.message}
          />

          <Input
            capitalize
            makePlacholderAsLabel
            {...register(`address2`)}
            placeholder="Address 2"
            className="rounded-none"
            errorMsg={errors.address2?.message}
          />

          <Input
            capitalize
            makePlacholderAsLabel
            {...register(`town_city`)}
            placeholder="Town city"
            className="rounded-none"
            errorMsg={errors.town_city?.message}
          />

          <Input
            capitalize
            makePlacholderAsLabel
            {...register(`county`)}
            placeholder="County"
            className="rounded-none"
            errorMsg={errors.county?.message}
          />

          <Input
            capitalize
            makePlacholderAsLabel
            {...register(`country`)}
            placeholder="Country"
            className="rounded-none"
            errorMsg={errors.country?.message}
          />

          <Input
            makePlacholderAsLabel
            capitalize
            {...register(`post_code`)}
            placeholder="Post code"
            className="rounded-none"
            errorMsg={errors.post_code?.message}
          />
        </div>
        <div className="flex justify-center">
          <Button
            type="submit"
            disabled={isSubmitting}
            className="w-80 mx-auto my-5"
          >
            SAVE
          </Button>
        </div>
      </form>
    </div>
  );
}

function ChangePrimaryAddress({
  refetch,
  customerData,
}: {
  refetch: () => Promise<any>;
  customerData: CustomerDataT | undefined;
}) {
  const {
    register,
    handleSubmit,
    setValue,
    reset,
    watch,
    control,
    formState: { errors, isSubmitting },
  } = useForm<AddressSchemaT>({
    resolver: yupResolver(addressSchema),
  });

  const { fields, append, prepend, remove, swap, move, insert } = useFieldArray(
    {
      control, // control props comes from useForm (optional: if you are using FormProvider)
      name: "address", // unique name for your Field Array
    }
  );

  const mutationChangePrimaryAddress = useMutation<
    AxiosResponse<{
      data: CustomerDataT;
      message: string;
    }>,
    AxiosError<RespError>,
    any
  >({
    mutationFn: (id: number) => changePrimaryAddress(id),
    onError: (error, variables, context) => {
      const errorObj: Record<any, string[]> = error.response?.data.data!;
      let message = "";
      for (let key in errorObj) {
        if (errorObj.hasOwnProperty(key)) {
          let value = errorObj[key];
          message += key + " " + value[0] + "\n";
        }
      }
      toast({
        variant: "destructive",
        title: "Error",
        description: message,
      });
    },
    onSuccess: async (data, variables, context) => {
      toast({
        variant: "default",
        title: "Success",
        description: data.data.message,
      });
      await refetch();
    },
  });

  const mutationSend = useMutation<
    AxiosResponse<any>,
    AxiosError<RespError>,
    any
  >({
    mutationFn: sendData,
    onSuccess: async (data) => {
      toast({
        title: "Success",
        description: "Customer has been saved successfully ",
      });
      reset();

      await refetch();
    },
    onError: (error) => {
      const errorObj: Record<any, string[]> = error.response?.data.data!;
      let message = "";
      for (let key in errorObj) {
        if (errorObj.hasOwnProperty(key)) {
          let value = errorObj[key];
          message += key + " " + value[0] + "\n";
        }
      }
      toast({
        variant: "destructive",
        title: "Error",
        description: message,
      });
    },
  });

  function sendData(data?: AddressNSchemaT) {
    return Axios.patch("/customer/management/" + customerData?.id + "/", data);
  }

  async function onSubmit(data: AddressSchemaT) {
    const newData = { ...data };

    await mutationSend.mutateAsync(newData);
  }

  function changePrimaryAddress(id: number) {
    const data = {
      primary: true,
      address_id: id,
    };
    return Axios.patch(
      "/customer/management/" + customerData?.id + "/update_address/",
      data
    );
  }

  return (
    <div className="mt-10">
      <div className="flex justify-around items-center">
        <p className="text-danger font-semibold text-base">
          Change Primary Address To{" "}
        </p>
        <div className="w-80 flex items-center gap-1">
          <Select
            onValueChange={(e) => {
              mutationChangePrimaryAddress.mutateAsync(e);
            }}
          >
            <SelectTrigger className="">
              <SelectValue placeholder="Change Primary Address" />
            </SelectTrigger>

            <SelectContent>
              <SelectGroup>
                {customerData?.address.map((address) => {
                  return (
                    <SelectItem
                      key={address.id}
                      value={address.id + ""}
                    >{`${address.address1} ${address.address2} ${address.county} ${address.post_code} ${address.town_city} ${address.country}`}</SelectItem>
                  );
                })}
              </SelectGroup>
            </SelectContent>
          </Select>
          {mutationChangePrimaryAddress.isPending && (
            <div className="">
              <Loader className="w-8 animate-spin	" />
            </div>
          )}
        </div>
      </div>
      <p
        className="px-8 mt-5 cursor-pointer "
        onClick={() => {
          if (fields.length === 0)
            append({
              address1: "",
              address2: "",
              country: "United Kingdom",
              county: "",
              post_code: "" as any,
              town_city: "",
              primary: false,
            });
        }}
      >
        <span className=""> Add New Address</span>{" "}
        <PlusIcon className="text-gray-500 border inline-block cursor-pointer " />
      </p>
      <form onSubmit={handleSubmit(onSubmit)}>
        <div className="px-8">
          {fields.map((address, index, arr) => {
            return (
              <div className="" key={index}>
                <div className="flex justify-between mt-8">
                  <p className="text-xl text-gray-500">Address </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
                    {...register(`address.${index}.address1`)}
                    placeholder="address Line 1"
                    className="rounded-none"
                    errorMsg={errors.address?.[index]?.address1?.message}
                  />

                  <Input
                    capitalize
                    {...register(`address.${index}.address2`)}
                    placeholder="Address Line 2"
                    className="rounded-none"
                    errorMsg={errors.address?.[index]?.address2?.message}
                  />

                  <Input
                    capitalize
                    {...register(`address.${index}.town_city`)}
                    placeholder="Town city"
                    className="rounded-none"
                    errorMsg={errors.address?.[index]?.town_city?.message}
                  />

                  <Input
                    capitalize
                    {...register(`address.${index}.county`)}
                    placeholder="County"
                    className="rounded-none"
                    errorMsg={errors.address?.[index]?.county?.message}
                  />

                  <Input
                    capitalize
                    {...register(`address.${index}.country`)}
                    placeholder="Country"
                    className="rounded-none"
                    errorMsg={errors.address?.[index]?.country?.message}
                  />

                  <Input
                    capitalize
                    {...register(`address.${index}.post_code`)}
                    placeholder="Post code"
                    className="rounded-none"
                    errorMsg={errors.address?.[index]?.post_code?.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>
        {fields.length > 0 && (
          <div className="flex justify-center">
            <Button
              type="submit"
              disabled={isSubmitting}
              className="w-80 mx-auto my-5"
            >
              Add Address
            </Button>
          </div>
        )}
      </form>
    </div>
  );
}
