"use client";

import Button from "@/components/common/Button";
import SideDrawer from "@/components/common/SideDrawer";
import { toast } from "react-toastify";
import { LuCirclePlus } from "react-icons/lu";
import { MdOutlineDeleteOutline, MdOutlineEdit } from "react-icons/md";
import Select from "react-select";
import { useState, useEffect } from "react";
import Pagination from "@/components/Pagination/Paginate";
import DataNotFound from "@/components/common/DataNotFound";
import {
  useForm,
  FormProvider,
  Controller,
  SubmitHandler,
} from "react-hook-form";
import { useAppSelector, useAppDispatch } from "@/app/store/hooks";
import { zodResolver } from "@hookform/resolvers/zod";
import { useTranslations } from "next-intl";
import Input from "@/components/common/CustomInputField";
import { useRouter } from "next/navigation";
import { checkAuthErrorGet } from "@/lib/checkAuthError";
import MobilePageHeader from "@/components/common/MobilePageHeader";

interface BankAccountFormData {
  bankName: string;
  accountNumber: string;
  accountHolderName: string;
  bankCodeType?: string;
  bankCodeLabel?: string;
  bankCode: string;
  country: string;
  isPrimary: boolean;
}

interface BankAccount {
  id: string;
  _id?: string;
  bankName: string;
  accountNumber: string;
  accountHolderName: string;
  bankCodeType: string;
  bankCodeLabel: string;
  bankCode: string;
  country: string;
  isPrimary: boolean;
  createdAt?: string;
}

import { z } from "zod";
import {
  createAccount,
  deleteAccount,
  indexAccounts,
  setPrimaryAccount,
  updateAccount,
} from "@/lib/actions/bankActions";
import Link from "next/link";
import { IoMdAddCircleOutline } from "react-icons/io";
import { useSelectTheme } from "@/hooks/useSelectTheme";
import AccountDropdown from "@/components/common/AccountDropdown";
import RouteLoader from "@/components/common/RouteLoader";
import Loader from "@/components/common/Loader";

// bankCodeType: z.string().min(1, t("bank_validation.bank_code_type_required")),
// bankCodeLabel: z.string().min(1, t("bank_validation.bank_code_label_required")),
const createBankAccountSchema = (t: any) =>
  z.object({
    bankName: z.string().min(1, t("bank_validation.bank_name_required")),
    accountNumber: z
      .string()
      .min(1, t("bank_validation.account_number_required")),
    accountHolderName: z
      .string()
      .min(1, t("bank_validation.account_holder_name_required")),
    bankCode: z.string().min(1, t("bank_validation.bank_code_required")),
    country: z.string().min(1, t("bank_validation.country_required")),
    isPrimary: z.boolean(),
  });

export default function MyBankAccounts() {
  const dispatch = useAppDispatch();
  const router = useRouter();
  const { user } = useAppSelector((state) => state?.auth);
  const [activeDrawer, setActiveDrawer] = useState<
    null | "addaccount" | "editaccount"
  >(null);
  const [editingAccount, setEditingAccount] = useState<BankAccount | null>(
    null
  );
  const [showDeleteModal, setShowDeleteModal] = useState(false);
  const [accountToDelete, setAccountToDelete] = useState<BankAccount | null>(
    null
  );
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [bankAccounts, setBankAccounts] = useState<BankAccount[]>([]);
  const [isLoading, setIsLoading] = useState(false);

  const t = useTranslations();

  const [page, setPage] = useState<number>(1);
  const [totalPages, setTotalPages] = useState<number>(0);

  const fetchBankAccounts = async () => {
    if (!user?.token) return;

    setIsLoading(true);
    try {
      const result = await indexAccounts(user.token, {
        page: page,
      });

      if (!result.success) throw new Error(result.message);

      if (!Array.isArray(result.data))
        throw new Error(t("bank_validation.fetch_failed"));

      const pagination = result?.pagination;
      setTotalPages(pagination?.totalPages || 1);

      const normalizedAccounts = result.data.map((account: any) => ({
        ...account,
        id: account.id || account._id || "",
      }));

      setBankAccounts(normalizedAccounts);
    } catch (error) {
      if (checkAuthErrorGet(error, dispatch, router)) return;
      toast.error(t("bank_validation.fetch_failed"));
    } finally {
      setIsLoading(false);
    }
  };

  useEffect(() => {
    fetchBankAccounts();
  }, [user?.token, t, page]);

  const DEFAULT_FORM_VALUES: BankAccountFormData = {
    bankName: "",
    accountNumber: "",
    accountHolderName: "",
    // bankCodeType: "",
    // bankCodeLabel: "",
    bankCode: "",
    country: "UAE",
    isPrimary: false,
  };

  const methods = useForm<BankAccountFormData>({
    resolver: zodResolver(createBankAccountSchema(t)),
    mode: "onChange",
    defaultValues: DEFAULT_FORM_VALUES,
  });

  const {
    handleSubmit,
    control,
    reset,
    formState: { errors },
  } = methods;

  // const bankCodeTypeOptions = [
  //   { value: "NATIONAL", label: "National" },
  //   { value: "INTERNATIONAL", label: "International" },
  // ];

  // const bankCodeLabelOptions = [
  //   { value: "IBAN", label: "IBAN" },
  //   { value: "SWIFT", label: "SWIFT" },
  //   { value: "BIC", label: "BIC" },
  //   { value: "ROUTING", label: "Routing Number" },
  // ];

  const countryOptions = [
    { value: "UAE", label: "United Arab Emirates" },
    { value: "SA", label: "Saudi Arabia" },
    { value: "QA", label: "Qatar" },
    { value: "KW", label: "Kuwait" },
    { value: "BH", label: "Bahrain" },
    { value: "OM", label: "Oman" },
  ];

  const closeDrawer = (shouldReset = true) => {
    setActiveDrawer(null);
    setEditingAccount(null);
    if (shouldReset) {
      reset();
    }
  };

  const resetForm = () => {
    methods.reset(DEFAULT_FORM_VALUES);
  };

  const getAccountId = (account: BankAccount): string => {
    return account.id || account._id || "";
  };

  const handleAddAccount = async (data: BankAccountFormData) => {
    setIsSubmitting(true);
    try {
      const result = await createAccount(user.token, data);

      if (!result.success) throw new Error(result.message);

      const newAccount = result.data;

      // Ensure the new account has both id and _id for consistency
      const normalizedAccount = {
        ...newAccount,
        id: newAccount.id || newAccount._id || "", // Use id if exists, otherwise use _id
      };

      let updatedAccounts = [];
      if (data.isPrimary) {
        updatedAccounts = bankAccounts.map((acc) => ({
          ...acc,
          isPrimary: false,
        }));
      } else {
        updatedAccounts = [...bankAccounts];
      }

      updatedAccounts.unshift(normalizedAccount);
      setBankAccounts(updatedAccounts);

      toast.success(t("bank_validation.bank_account_added_successfully"));
      closeDrawer();
    } catch (error: any) {
      if (checkAuthErrorGet(error, dispatch, router)) return;
      toast.error(t("bank_validation.add_failed"));
    } finally {
      setIsSubmitting(false);
    }
  };

  const handleUpdateAccount = async (data: BankAccountFormData) => {
    if (!editingAccount) return;

    const accountId = getAccountId(editingAccount);
    if (!accountId) return;

    setIsSubmitting(true);
    try {
      const result = await updateAccount(user.token, {
        accountId: accountId,
        payload: data,
      });

      if (!result.success) throw new Error(result.message);

      const updatedAccount = result.data;

      // Update local state immediately
      const updatedAccounts = bankAccounts.map((acc) => {
        const accId = getAccountId(acc);
        if (accId === accountId) {
          return { ...acc, ...updatedAccount, id: accId }; // Preserve the id
        }
        // If setting this account as primary, update others
        if (data.isPrimary && accId !== accountId) {
          return { ...acc, isPrimary: false };
        }
        return acc;
      });

      setBankAccounts(updatedAccounts);
      toast.success(t("bank_validation.bank_account_updated_successfully"));
      closeDrawer();
    } catch (error: any) {
      if (checkAuthErrorGet(error, dispatch, router)) return;
      toast.error(t("bank_validation.update_failed"));
    } finally {
      setIsSubmitting(false);
    }
  };

  const handleDeleteAccount = async () => {
    if (!accountToDelete) return;

    const accountId = getAccountId(accountToDelete);
    if (!accountId) return;

    try {
      const result = await deleteAccount(user.token, {
        accountId: accountId,
      });

      if (!result.success) throw new Error(result.message);

      // Update local state immediately
      const updatedAccounts = bankAccounts.filter((acc) => {
        const accId = getAccountId(acc);
        return accId !== accountId;
      });

      setBankAccounts(updatedAccounts);

      toast.success(t("bank_validation.bank_account_deleted_successfully"));
    } catch (error: any) {
      if (checkAuthErrorGet(error, dispatch, router)) return;
      toast.error(t("bank_validation.delete_failed"));
    } finally {
      setShowDeleteModal(false);
      setAccountToDelete(null);
    }
  };

  const handleEditAccount = (account: BankAccount) => {
    setEditingAccount(account);
    setActiveDrawer("editaccount");

    methods.reset({
      bankName: account.bankName,
      accountNumber: account.accountNumber,
      accountHolderName: account.accountHolderName,
      bankCodeType: account.bankCodeType,
      bankCodeLabel: account.bankCodeLabel,
      bankCode: account.bankCode,
      country: account.country,
      isPrimary: account.isPrimary,
    });
  };

  const handleSetPrimaryAccount = async (accountId: string) => {
    try {
      const result = await setPrimaryAccount(user.token, {
        accountId,
      });

      if (!result.success) throw new Error(result.message);

      // Update local state immediately
      const updatedAccounts = bankAccounts.map((acc) => {
        const accId = getAccountId(acc);
        return {
          ...acc,
          isPrimary: accId === accountId,
        };
      });

      setBankAccounts(updatedAccounts);
      toast.success(t("bank_validation.primary_bank_account_updated"));
    } catch (error: any) {
      if (checkAuthErrorGet(error, dispatch, router)) return;
      toast.error(t("bank_validation.set_primary_failed"));
    }
  };

  const onSubmit: SubmitHandler<BankAccountFormData> = async (data) => {
    const isValid = await methods.trigger();
    if (!isValid) return;

    if (activeDrawer === "editaccount" && editingAccount) {
      await handleUpdateAccount(data);
    } else {
      await handleAddAccount(data);
    }
  };

  const { themeKey, isDarkMode, customStyles } = useSelectTheme();

  if (!user?.token) {
    const fakeAuthError = {
      response: {
        data: {
          statusCode: 401,
          statusText: "Unauthorized",
        },
      },
    };
    checkAuthErrorGet(fakeAuthError, dispatch, router);
    return null;
  }

  const handleBack = () => {
    window.history.back();
  };

  if (isLoading) {
    return (
      <div className="min-h-screen flex items-center justify-center">
        <Loader />
      </div>
    );
  }

  return (
    <RouteLoader>
      <MobilePageHeader
        title={t("my_bank_accounts.title")}
        onBack={handleBack}
        rightContent={
          <>
            <button
              onClick={() => {
                setActiveDrawer("addaccount");
                resetForm();
              }}
              disabled={isLoading}
              title="Add Bank Account"
              className="text-neutrals900 dark:text-white"
            >
              <IoMdAddCircleOutline size={24} />
            </button>
          </>
        }
      />

      <main className="flex-1 max-md:px-0">
        <div className="flex items-center justify-between gap-2 pb-6 max-md:hidden">
          <h1 className="text-lg font-bold text-neutrals900 dark:text-white">
            {t("my_bank_accounts.title")}
          </h1>
          <div className="flex items-center gap-1.5">
            <AccountDropdown t={t} />
            <button
              onClick={() => {
                setActiveDrawer("addaccount");
                resetForm();
              }}
              disabled={isLoading}
              title="Add Bank Account"
              className="text-primary500 border border-primary500 p-2 py-1.5 rounded-lg hover:bg-primary500 hover:text-white dark:text-primary400 dark:border-primary400 dark:hover:bg-primary400 dark:hover:text-white"
            >
              <IoMdAddCircleOutline size={20} />
            </button>
          </div>
        </div>
        <div>
          {isLoading && (
            <div className="flex justify-center items-center py-8">
              <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary500"></div>
            </div>
          )}

          <div className="grid flex-col grid-cols-3 gap-4 max-lg:grid-cols-2 max-md:grid-cols-2 max-sm:grid-cols-1">
            {bankAccounts.map((account, index) => (
              <div
                key={account.id || `account-${index}`}
                className="p-4 shadow-lg bg-white rounded-md border border-neutrals100 pb-4 flex items-start justify-between dark:border-darkborder gap-1 dark:bg-darkbg dark:shadow-none hover:shadow-xl transition-shadow hover:border-primary500/30 dark:hover:border-primary400"
              >
                <div className="flex-1">
                  <p className="text-base font-semibold text-neutrals800 mb-2.5 dark:text-neutrals300">
                    {account.isPrimary
                      ? t("my_bank_accounts.primary_account")
                      : `${t("my_bank_accounts.account")} ${index + 1}`}
                  </p>
                  <div className="space-y-1">
                    <p className="font-bold text-neutrals800 text-sm dark:text-neutrals300">
                      {account.bankName}
                    </p>
                    <p className="text-sm text-neutrals500 dark:text-neutrals400">
                      {t("my_bank_accounts.account_number")}:{" "}
                      {account.accountNumber}
                    </p>
                    <p className="text-sm text-neutrals500 dark:text-neutrals400">
                      {t("my_bank_accounts.account_holder")}:{" "}
                      {account.accountHolderName}
                    </p>
                    <p className="text-sm text-neutrals500 dark:text-neutrals400">
                      {account.bankCodeLabel}: {account.bankCode}
                    </p>
                    <p className="text-sm text-neutrals500 dark:text-neutrals400">
                      {t("my_bank_accounts.country")}: {account.country}
                    </p>
                  </div>
                </div>
                <div className="h-full items-end justify-between flex flex-col min-h-24">
                  <div className="relative">
                    <label className="cursor-pointer">
                      <input
                        type="radio"
                        name="bankAccount"
                        value={account.id}
                        checked={account.isPrimary}
                        onChange={() =>
                          account.id && handleSetPrimaryAccount(account.id)
                        }
                        className="peer hidden"
                      />
                      <div className="w-5 h-5 rounded-full border-2 border-neutrals200 peer-checked:border-primary500 peer-checked:bg-primary500 flex items-center justify-center dark:peer-checked:border-primary400 dark:peer-checked:bg-primary400">
                        <div className="w-2.5 h-2.5 rounded-full bg-white max-lg:w-2 max-lg:h-2" />
                      </div>
                    </label>
                  </div>
                  <div className="flex items-center gap-2.5">
                    <MdOutlineEdit
                      size={23}
                      className="text-neutrals500 cursor-pointer hover:text-primary500 dark:text-neutrals400 dark:hover:text-primary400"
                      onClick={() => handleEditAccount(account)}
                    />
                    <MdOutlineDeleteOutline
                      size={24}
                      className="text-red-600 cursor-pointer hover:text-red-700"
                      onClick={() => {
                        setAccountToDelete(account);
                        setShowDeleteModal(true);
                      }}
                    />
                  </div>
                </div>
              </div>
            ))}
          </div>

          {(bankAccounts.length === 0 && !isLoading) && (
            <DataNotFound />
          )}

          {!isLoading && totalPages > 1 && (
            <div className="!mt-10">
              <Pagination
                pageCount={totalPages}
                currentPage={page}
                onPageChange={({ selected }) => setPage(selected + 1)}
              />
            </div>
          )}
        </div>
      </main>

      <SideDrawer
        isOpen={activeDrawer === "addaccount" || activeDrawer === "editaccount"}
        title={
          activeDrawer === "editaccount"
            ? t("my_bank_accounts.edit_account")
            : t("my_bank_accounts.add_account")
        }
        onClose={() => closeDrawer()}
        footer={
          <div className="flex justify-end gap-2">
            <Button
              label={t("my_bank_accounts.button.cancel")}
              onClick={() => closeDrawer()}
              variant="fadoutline"
            />
            <Button
              type="submit"
              label={
                isSubmitting
                  ? t("button.saving")
                  : activeDrawer === "editaccount"
                  ? t("my_bank_accounts.button.update")
                  : t("my_bank_accounts.button.save")
              }
              variant="secondary"
              onClick={handleSubmit(onSubmit)}
              disabled={isLoading || isSubmitting}
            >
              {isSubmitting && (
                <div role="status" className="flex items-center justify-center">
                  <svg
                    className="animate-spin -ml-1 mr-2 h-4 w-4 text-white"
                    xmlns="http://www.w3.org/2000/svg"
                    fill="none"
                    viewBox="0 0 24 24"
                  >
                    <circle
                      className="opacity-25"
                      cx="12"
                      cy="12"
                      r="10"
                      stroke="currentColor"
                      strokeWidth="4"
                    ></circle>
                    <path
                      className="opacity-75"
                      fill="currentColor"
                      d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
                    ></path>
                  </svg>
                  <span className="sr-only">{t("button.loading")}</span>
                </div>
              )}
            </Button>
          </div>
        }
      >
        <FormProvider {...methods}>
          <form onSubmit={handleSubmit(onSubmit)} className="space-y-5">
            <Input
              label={t("my_bank_accounts.bank_name")}
              name="bankName"
              placeholder={t("my_bank_accounts.bank_name_placeholder")}
              required
            />

            <Input
              label={t("my_bank_accounts.account_number")}
              name="accountNumber"
              placeholder={t("my_bank_accounts.account_number_placeholder")}
              required
            />

            <Input
              label={t("my_bank_accounts.account_holder_name")}
              name="accountHolderName"
              placeholder={t(
                "my_bank_accounts.account_holder_name_placeholder"
              )}
              required
            />

            {/* <div>
              <label
                htmlFor="bankCodeType"
                className="block text-sm font-medium text-neutrals800 mb-1 dark:text-neutrals400"
              >
                {t("my_bank_accounts.bank_code_type")}{" "}
                <span className="text-sm text-red-500">*</span>
              </label>
              <Controller
                name="bankCodeType"
                control={control}
                render={({ field }) => (
                  <Select
                    {...field}
                    inputId="bankCodeType"
                    options={bankCodeTypeOptions}
                    placeholder={t("my_bank_accounts.select_bank_code_type")}
                    className="react-select-container"
                    classNamePrefix="react-select"
                    styles={customStyles}
                    key={themeKey}
                    value={bankCodeTypeOptions.find(option => option.value === field.value) || null}
                    onChange={(selected) => field.onChange(selected?.value || "")}
                  />
                )}
              />
              {errors.bankCodeType && (
                <span className="text-red-800 dark:text-red-500 text-sm">
                  {errors.bankCodeType.message}
                </span>
              )}
            </div>

            <div>
              <label
                htmlFor="bankCodeLabel"
                className="block text-sm font-medium text-neutrals800 mb-1 dark:text-neutrals400"
              >
                {t("my_bank_accounts.bank_code_label")}{" "}
                <span className="text-sm text-red-500">*</span>
              </label>
              <Controller
                name="bankCodeLabel"
                control={control}
                render={({ field }) => (
                  <Select
                    {...field}
                    inputId="bankCodeLabel"
                    options={bankCodeLabelOptions}
                    placeholder={t("my_bank_accounts.select_bank_code_label")}
                    className="react-select-container"
                    classNamePrefix="react-select"
                    styles={customStyles}
                    key={themeKey}
                    value={bankCodeLabelOptions.find(option => option.value === field.value) || null}
                    onChange={(selected) => field.onChange(selected?.value || "")}
                  />
                )}
              />
              {errors.bankCodeLabel && (
                <span className="text-red-800 dark:text-red-500 text-sm">
                  {errors.bankCodeLabel.message}
                </span>
              )}
            </div> */}

            <Input
              label={t("my_bank_accounts.bank_code")}
              name="bankCode"
              placeholder={t("my_bank_accounts.bank_code_placeholder")}
              required
            />

            <div>
              <label
                htmlFor="country"
                className="block text-sm font-medium text-neutrals800 mb-1 dark:text-neutrals400"
              >
                {t("my_bank_accounts.country")}{" "}
                <span className="text-sm text-red-500">*</span>
              </label>
              <Controller
                name="country"
                control={control}
                render={({ field }) => (
                  <Select
                    {...field}
                    inputId="country"
                    options={countryOptions}
                    placeholder={t("my_bank_accounts.select_country")}
                    className="react-select-container"
                    classNamePrefix="react-select"
                    styles={customStyles}
                    key={themeKey}
                    value={
                      countryOptions.find(
                        (option) => option.value === field.value
                      ) || null
                    }
                    onChange={(selected) =>
                      field.onChange(selected?.value || "")
                    }
                  />
                )}
              />
              {errors.country && (
                <span className="text-red-800 dark:text-red-500 text-sm">
                  {errors.country.message}
                </span>
              )}
            </div>

            <div className="flex items-center">
              <Controller
                name="isPrimary"
                control={control}
                render={({ field }) => (
                  <input
                    type="checkbox"
                    id="isPrimary"
                    checked={field.value}
                    onChange={field.onChange}
                    className="w-4 h-4 text-primary500 bg-gray-100 border-gray-300 rounded focus:ring-primary500 focus:ring-2"
                  />
                )}
              />
              <label
                htmlFor="isPrimary"
                className="ml-2 text-sm font-medium text-neutrals800 dark:text-neutrals400"
              >
                {t("my_bank_accounts.set_as_primary")}
              </label>
            </div>
          </form>
        </FormProvider>
      </SideDrawer>

      {showDeleteModal && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-40">
          <div className="bg-white rounded-lg shadow-lg p-6 w-full max-w-xs">
            <h2 className="text-lg font-semibold mb-4">
              {t("my_bank_accounts.confirm_deletion")}
            </h2>
            <p className="mb-6">
              {t("my_bank_accounts.confirm_deletion_message")}
            </p>
            <div className="flex justify-end gap-2">
              <button
                className="px-4 py-2 rounded bg-gray-200 hover:bg-gray-300 text-gray-800"
                onClick={() => {
                  setShowDeleteModal(false);
                  setAccountToDelete(null);
                }}
              >
                {t("my_bank_accounts.button.cancel")}
              </button>
              <button
                className="px-4 py-2 rounded bg-red-600 hover:bg-red-700 text-white"
                onClick={handleDeleteAccount}
              >
                {t("my_bank_accounts.button.delete")}
              </button>
            </div>
          </div>
        </div>
      )}
    </RouteLoader>
  );
}
