import OracleConfigSection from '@/components/admin/market-management/oracle-config-section';
import FormRenderer from '@/components/common/form-renderer';
import PageHeading from '@/components/common/page-heading';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@/components/ui/form';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { getUpdateMarketFields } from '@/data/forms/update-market-fields';
import { updateRequest } from '@/data/request/update-request';
import { useApiSWR } from '@/hooks/useSWR';
import { MarketUpdateSchema, TMarketUpdateForm } from '@/schema/market-schema';
import { TMarket, TMarketCategory } from '@/types/market.types';
import { getImageUrl } from '@/utils/getImageUrl';
import { zodResolver } from '@hookform/resolvers/zod';
import { router, usePage } from '@inertiajs/react';
import dayjs from 'dayjs';
import { useEffect } from 'react';
import { useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { toast } from 'sonner';

const UpdateMarket = () => {
  const { t } = useTranslation();
  const marketId = usePage().url.split('?')[0].split('/')[3];

  const { data: market, isLoading } = useApiSWR<TMarket>(
    marketId ? `/admin/markets/${marketId}` : null,
  );
  const { data: categoriesData } = useApiSWR<{ data: TMarketCategory[] }>(
    '/admin/market-categories',
  );
  const categories = categoriesData?.data ?? [];

  const form = useForm<TMarketUpdateForm>({
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    resolver: zodResolver(MarketUpdateSchema) as any,
    defaultValues: {
      title: '',
      description: '',
      category_id: null,
      closes_at: '',
      is_featured: false,
      image: undefined,
      rules: '',
      oracle_type: 'manual',
      oracle_config: {},
      resolution_criteria: '',
      dispute_window_minutes: 120,
    },
  });

  const formFields = getUpdateMarketFields(t);

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

    // Stored outcome_map references outcome ids; the editor is title-based, so
    // convert ids -> titles for display (the server re-resolves on save).
    const outcomesById = new Map(
      (market.outcomes ?? []).map((o) => [o.id, o.title]),
    );
    const oracleConfig: Record<string, unknown> = {
      ...(market.oracle_config ?? {}),
    };
    const outcomeMap = oracleConfig.outcome_map as
      | Record<string, unknown>
      | undefined;
    if (outcomeMap) {
      oracleConfig.outcome_map = Object.fromEntries(
        Object.entries(outcomeMap).map(([k, v]) => [
          k,
          outcomesById.get(Number(v)) ?? v,
        ]),
      );
    }

    form.reset({
      title: market.title,
      description: market.description ?? '',
      category_id: market.category_id ?? null,
      closes_at: dayjs(market.closes_at).format('YYYY-MM-DD HH:mm:ss'),
      is_featured: market.is_featured,
      image: market.image ?? undefined,
      rules: market.rules ?? '',
      oracle_type: market.oracle_type ?? 'manual',
      oracle_config: oracleConfig,
      resolution_criteria: market.resolution_criteria ?? '',
      dispute_window_minutes: market.dispute_window_minutes ?? 120,
    });
  }, [market, form]);

  const onSubmit = async (values: TMarketUpdateForm) => {
    const fd = new FormData();
    fd.append('title', values.title);
    if (values.description) fd.append('description', values.description);
    if (values.category_id != null)
      fd.append('category_id', String(values.category_id));
    fd.append('closes_at', values.closes_at);
    fd.append('is_featured', values.is_featured ? '1' : '0');
    if (values.image instanceof File) fd.append('image', values.image);
    if (values.rules) fd.append('rules', values.rules);

    fd.append('oracle_type', values.oracle_type ?? 'manual');
    fd.append(
      'dispute_window_minutes',
      String(values.dispute_window_minutes ?? 120),
    );
    if (values.resolution_criteria)
      fd.append('resolution_criteria', values.resolution_criteria);
    fd.append(
      'oracle_config',
      values.oracle_type && values.oracle_type !== 'manual'
        ? JSON.stringify(values.oracle_config ?? {})
        : '',
    );

    const result = await updateRequest({
      url: `/api/admin/markets/${marketId}`,
      formData: fd,
    });
    if (result) {
      toast.success(t('Market updated successfully.'));
      router.visit('/admin/markets');
    }
  };

  if (isLoading) {
    return (
      <div className="max-w-2xl space-y-4">
        {Array.from({ length: 5 }).map((_, i) => (
          <div
            key={i}
            className="h-10 animate-pulse rounded-xl bg-black/5 dark:bg-white/5"
          />
        ))}
      </div>
    );
  }

  return (
    <div className="max-w-2xl">
      <PageHeading
        title={t('Edit Market')}
        description={t('Update market details.')}
        backButton
        actionButton={
          <Badge variant="outline">
            {market?.engine === 'clob' ? t('Order Book') : t('AMM')}
          </Badge>
        }
      />

      <Form {...form}>
        <form
          onSubmit={form.handleSubmit(onSubmit)}
          className="space-y-4 rounded-xl bg-white p-4 shadow-box"
        >
          {formFields.info.map((f) => (
            <FormRenderer form={form} key={f.id} item={f} />
          ))}

          <FormRenderer form={form} item={formFields.image(marketId)} />

          <div className="grid grid-cols-2 gap-4">
            <FormField
              control={form.control}
              name="category_id"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>{t('Category')}</FormLabel>
                  <Select
                    key={`${categories.length > 0}-${field.value != null}`}
                    onValueChange={(v) => field.onChange(v ? Number(v) : null)}
                    value={field.value ? String(field.value) : ''}
                  >
                    <FormControl>
                      <SelectTrigger>
                        <SelectValue placeholder={t('Select category')} />
                      </SelectTrigger>
                    </FormControl>
                    <SelectContent>
                      {categories.map((cat) => (
                        <SelectItem key={cat.id} value={String(cat.id)}>
                          {cat.icon && (
                            <Avatar className="size-5 overflow-hidden rounded-full">
                              <AvatarImage
                                src={getImageUrl(cat.icon)}
                                alt={cat.name}
                              />
                              <AvatarFallback className="rounded-lg bg-neutral-200 font-medium text-black dark:bg-neutral-700 dark:text-white" />
                            </Avatar>
                          )}
                          {cat.name}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormRenderer form={form} item={formFields.closesAt} />
          </div>

          <FormRenderer form={form} item={formFields.rules} />

          <FormRenderer form={form} item={formFields.featured} />

          <OracleConfigSection form={form} outcomes={market?.outcomes ?? []} />

          <div className="flex justify-end gap-3 pt-2">
            <Button
              type="button"
              variant="ghost"
              onClick={() => router.visit('/admin/markets')}
            >
              {t('Cancel')}
            </Button>
            <Button type="submit" loading={form.formState.isSubmitting}>
              {t('Save Changes')}
            </Button>
          </div>
        </form>
      </Form>
    </div>
  );
};

UpdateMarket.title = 'Edit Market';

export default UpdateMarket;
