/* eslint-disable @typescript-eslint/no-explicit-any */
import PageHeading from '@/components/common/page-heading';
import LoaderIcon from '@/components/icons/loader-icon';
import { Button } from '@/components/ui/button';
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { Separator } from '@/components/ui/separator';
import { updateRequest } from '@/data/request/update-request';
import { useApiSWR } from '@/hooks/useSWR';
import { SharedData } from '@/types';
import { replaceDashesWithSpaces } from '@/utils/strHelpers';
import { zodResolver } from '@hookform/resolvers/zod';
import { usePage } from '@inertiajs/react';
import { CheckIcon } from '@phosphor-icons/react';
import { useEffect } from 'react';
import { useFieldArray, useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { toast } from 'sonner';
import z from 'zod';

const RankingPointItemSchema = z.object({
  id: z.coerce.number().int().positive(),
  action: z.string().min(1),
  is_active: z.coerce.number().int().min(0).max(1),
  amount_threshold: z.coerce.number().min(0, 'Deposit amount must be >= 0'),
  reward_point: z.coerce.number().min(0, 'Reward point must be >= 0'),
});

const RankingPointsSchema = z.object({
  items: z.array(RankingPointItemSchema).min(1),
});

type FormValues = z.infer<typeof RankingPointsSchema>;

const RankingPoints = () => {
  type TRankingPointItem = {
    id: number;
    action: string;
    reward_point: number;
    amount_threshold: number;
    is_active: number;
  };

  const { data, isLoading, mutate } = useApiSWR<TRankingPointItem[]>(
    'admin/ranking-points',
  );
  const { branding } = usePage<SharedData>().props;
  const { t } = useTranslation();

  const defaultCurrency = branding?.branding?.site_currency ?? 'USD';

  const form = useForm({
    resolver: zodResolver(RankingPointsSchema),
    defaultValues: { items: [] },
    mode: 'onChange',
    reValidateMode: 'onChange',
  });

  const { fields, replace } = useFieldArray({
    control: form.control,
    name: 'items',
  });

  useEffect(() => {
    if (!data) return;

    replace(
      data.map((r: any) => ({
        id: r.id,
        action: r.action,
        reward_point: r.reward_point,
        amount_threshold: r.amount_threshold,
        is_active: r.is_active,
      })),
    );
  }, [data, replace]);

  const onSubmit = (values: FormValues) => {
    const dirtyItems =
      (form.formState.dirtyFields?.items as Array<any> | undefined)
        ?.map((dirty, i) => (dirty ? i : -1))
        .filter((i) => i !== -1) ?? [];

    const itemsToUpdate =
      dirtyItems.length > 0
        ? dirtyItems.map((i) => values.items[i])
        : values.items;

    toast.promise(
      Promise.all(
        itemsToUpdate.map((item) =>
          updateRequest({
            url: `/api/admin/ranking-points/${item.id}`,
            formData: {
              action: item.action,
              reward_point: item.reward_point,
              amount_threshold: item.amount_threshold,
              is_active: item.is_active,
            },
          }),
        ),
      ).then(() => {
        mutate();
        form.reset(values);
      }),
      {
        loading: t('Saving changes...'),
        success: () => t('Saved successfully'),
        error: () => t('Failed to save changes'),
      },
    );
  };

  const getRankingPointDescription = (item: any) => {
    const points = Number(item?.reward_point);
    const threshold = Number(item?.amount_threshold);

    const readableAction = replaceDashesWithSpaces(item?.action);

    if (item?.action === 'market_win') {
      return t(
        'Users will receive {{points}} point(s) for every {{threshold}} {{currency}} market win payout.',
        { points, threshold, currency: defaultCurrency },
      );
    }

    if (item?.action === 'referral') {
      return t(
        'Users will receive {{points}} point(s) for every successful {{threshold}} referral.',
        { points, threshold },
      );
    }

    return t(
      'Users will receive {{points}} point(s) for every successful {{threshold}} {{currency}} {{action}}.',
      { points, threshold, currency: defaultCurrency, action: readableAction },
    );
  };

  return (
    <>
      <Form {...form}>
        <form onSubmit={form.handleSubmit(onSubmit)}>
          <PageHeading
            title={t('Manage Ranking Points')}
            description={t(
              'Configure points awarded for various user actions and activities.',
            )}
            actionButton={
              <Button>
                {t('Save Changes')} <CheckIcon weight="bold" />
              </Button>
            }
          />

          {isLoading ? (
            <div className="flex h-32 w-full items-center justify-center gap-2">
              <LoaderIcon />
              {t('Loading...')}
            </div>
          ) : (
            <div className="grid grid-cols-1 gap-4 md:grid-cols-3">
              {fields.map((row, index) => {
                // eslint-disable-next-line react-hooks/incompatible-library
                const item = form.watch(`items.${index}`);
                return (
                  <div
                    key={row.id}
                    className="rounded-2xl bg-white p-3 shadow-box md:p-6"
                  >
                    <h3 className="text-lg font-medium capitalize md:text-xl">
                      {replaceDashesWithSpaces(row.action)}
                    </h3>
                    <Separator className="my-4" />

                    <div className="space-y-4">
                      <FormField
                        control={form.control}
                        name={`items.${index}.amount_threshold`}
                        render={({ field }) => (
                          <FormItem>
                            <FormLabel>
                              {item?.action === 'referral'
                                ? t('Referral Count')
                                : t('Amount ({{currency}})', {
                                    currency: defaultCurrency,
                                  })}
                            </FormLabel>
                            <FormControl>
                              <Input
                                type="number"
                                inputMode="numeric"
                                placeholder={t('Enter deposit amount')}
                                {...field}
                                value={field.value as string | number}
                              />
                            </FormControl>
                            <FormMessage />
                          </FormItem>
                        )}
                      />

                      <FormField
                        control={form.control}
                        name={`items.${index}.reward_point`}
                        render={({ field }) => (
                          <FormItem>
                            <FormLabel>{t('Reward point')}</FormLabel>
                            <FormControl>
                              <Input
                                type="number"
                                inputMode="numeric"
                                placeholder={t('Enter reward point')}
                                {...field}
                                value={field.value as string | number}
                              />
                            </FormControl>
                            <FormMessage />
                          </FormItem>
                        )}
                      />

                      <div>
                        <h4>{t('Description')}</h4>
                        <div className="rounded-md border border-black/5 bg-black/5 px-4 py-2.5">
                          <p className="text-black/50">
                            {getRankingPointDescription(item)}
                          </p>
                        </div>
                      </div>
                    </div>
                  </div>
                );
              })}
            </div>
          )}
        </form>
      </Form>
    </>
  );
};

RankingPoints.title = 'Ranking Points';

export default RankingPoints;
