import MarketLookup from '@/components/admin/market-management/market-lookup';
import OracleConfigSection from '@/components/admin/market-management/oracle-config-section';
import UmaImport, {
  UmaLookup,
} from '@/components/admin/market-management/uma-import';
import FormRenderer from '@/components/common/form-renderer';
import PageHeading from '@/components/common/page-heading';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { Button } from '@/components/ui/button';
import { ColorPicker } from '@/components/ui/color-picker';
import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { getCreateMarketFields } from '@/data/forms/create-market-fields';
import { createRequest } from '@/data/request/create-request';
import { useApiSWR } from '@/hooks/useSWR';
import { MarketSchema, TMarketForm } from '@/schema/market-schema';
import { TMarketCategory } from '@/types/market.types';
import { getImageUrl } from '@/utils/getImageUrl';
import { zodResolver } from '@hookform/resolvers/zod';
import { router } from '@inertiajs/react';
import { MinusIcon, PlusIcon } from '@phosphor-icons/react';
import dayjs from 'dayjs';
import { useEffect } from 'react';
import { useFieldArray, useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { toast } from 'sonner';

const CreateMarket = () => {
  const { t } = useTranslation();
  const { data: categoriesData } = useApiSWR<{ data: TMarketCategory[] }>(
    '/admin/market-categories',
  );
  const categories = categoriesData?.data ?? [];

  const form = useForm<TMarketForm>({
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    resolver: zodResolver(MarketSchema) as any,
    defaultValues: {
      title: '',
      description: '',
      category_id: null,
      type: 'binary',
      engine: 'amm',
      tick_size: 0.01,
      closes_at: '',
      initial_liquidity: 100,
      is_featured: false,
      image: undefined,
      rules: '',
      outcomes: [
        { title: 'Yes', color: '#22c55e' },
        { title: 'No', color: '#ef4444' },
      ],
      oracle_type: 'manual',
      oracle_config: {},
      resolution_criteria: '',
      dispute_window_minutes: 120,
    },
  });

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

  // eslint-disable-next-line react-hooks/incompatible-library
  const type = form.watch('type');
  const formFields = getCreateMarketFields(t);

  useEffect(() => {
    if (type === 'binary') {
      replace([
        { title: 'Yes', color: '#22c55e' },
        { title: 'No', color: '#ef4444' },
      ]);
    }
  }, [type, replace]);

  // Auto-populate the form from a Polymarket/UMA market.
  const handleUmaImport = (data: UmaLookup) => {
    if (data.question) form.setValue('title', data.question);
    if (data.closes_at) {
      form.setValue(
        'closes_at',
        dayjs(data.closes_at).format('YYYY-MM-DD HH:mm:ss'),
      );
    }

    const outcomes = (data.outcomes ?? []).map((title, i) => ({
      title,
      color: i === 0 ? '#22c55e' : i === 1 ? '#ef4444' : '#6366f1',
    }));

    if (outcomes.length >= 2) {
      form.setValue('type', outcomes.length > 2 ? 'multi' : 'binary');
      replace(outcomes);
      // Outcomes are imported in Polymarket's order (index 0 = YES), so the
      // driver maps the resolved side positionally — no manual outcome map.
      form.setValue('oracle_config', { market_id: data.market_id });
    }
  };

  const onSubmit = async (values: TMarketForm) => {
    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('type', values.type);
    fd.append('engine', values.engine ?? 'amm');
    if (values.engine === 'clob' && values.tick_size)
      fd.append('tick_size', String(values.tick_size));
    fd.append('closes_at', values.closes_at);
    fd.append('initial_liquidity', String(values.initial_liquidity ?? 100));
    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);
    values.outcomes.forEach((outcome, i) => {
      fd.append(`outcomes[${i}][title]`, outcome.title);
      if (outcome.color) fd.append(`outcomes[${i}][color]`, outcome.color);
    });

    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);
    if (
      values.oracle_type &&
      values.oracle_type !== 'manual' &&
      values.oracle_config
    ) {
      fd.append('oracle_config', JSON.stringify(values.oracle_config));
    }

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

  return (
    <div className="w-full">
      <PageHeading
        title={t('Create Market')}
        description={t('Set up a new prediction market.')}
        backButton
      />

      <Form {...form}>
        <form
          onSubmit={form.handleSubmit(onSubmit)}
          className="rounded-xl bg-white p-4 shadow-box"
        >
          <div className="grid grid-cols-1 gap-x-8 gap-y-4 lg:grid-cols-2">
            <div className="space-y-4">
              {formFields.info.map((f) => (
                <FormRenderer form={form} key={f.id} item={f} />
              ))}

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

              <div className="grid grid-cols-2 gap-4">
                <FormField
                  control={form.control}
                  name="category_id"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>{t('Category')}</FormLabel>
                      <Select
                        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"></AvatarFallback>
                                </Avatar>
                              )}
                              {cat.name}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                      <FormDescription>
                        {t('Groups the market under a browse category.')}
                      </FormDescription>
                      <FormMessage />
                    </FormItem>
                  )}
                />
                <FormRenderer form={form} item={formFields.marketType} />
              </div>

              <div className="grid grid-cols-2 gap-4">
                <FormField
                  control={form.control}
                  name="engine"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>{t('Trading Engine')}</FormLabel>
                      <Select
                        value={field.value ?? 'amm'}
                        onValueChange={(v) => {
                          field.onChange(v);
                          // The order book supports binary markets only.
                          if (v === 'clob') form.setValue('type', 'binary');
                        }}
                      >
                        <FormControl>
                          <SelectTrigger>
                            <SelectValue />
                          </SelectTrigger>
                        </FormControl>
                        <SelectContent>
                          <SelectItem value="amm">
                            {t('AMM (Pool pricing)')}
                          </SelectItem>
                          <SelectItem value="clob">
                            {t('Order Book (CLOB)')}
                          </SelectItem>
                        </SelectContent>
                      </Select>
                      <FormDescription>
                        {t(
                          'AMM prices from a shared pool. Order book matches limit orders like an exchange (binary markets only). Cannot be changed later.',
                        )}
                      </FormDescription>
                      <FormMessage />
                    </FormItem>
                  )}
                />

                {form.watch('engine') === 'clob' && (
                  <FormField
                    control={form.control}
                    name="tick_size"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>{t('Tick Size')}</FormLabel>
                        <Select
                          value={field.value ? String(field.value) : '0.01'}
                          onValueChange={(v) => field.onChange(Number(v))}
                        >
                          <FormControl>
                            <SelectTrigger>
                              <SelectValue />
                            </SelectTrigger>
                          </FormControl>
                          <SelectContent>
                            <SelectItem value="0.01">0.01</SelectItem>
                            <SelectItem value="0.001">0.001</SelectItem>
                          </SelectContent>
                        </Select>
                        <FormDescription>
                          {t('Smallest allowed price increment for orders.')}
                        </FormDescription>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                )}
              </div>

              <div className="space-y-2">
                <FormLabel>{t('Outcomes')}</FormLabel>
                <FormDescription>
                  {t(
                    'The choices traders can buy. Binary markets are fixed to Yes / No; multi-outcome markets need at least two and each must be mutually exclusive.',
                  )}
                </FormDescription>
                {fields.map((field, index) => (
                  <div key={field.id} className="flex items-center gap-2">
                    <FormField
                      control={form.control}
                      name={`outcomes.${index}.color`}
                      render={({ field }) => (
                        <ColorPicker
                          value={field.value ?? '#22c55e'}
                          onChange={field.onChange}
                        />
                      )}
                    />
                    <FormField
                      control={form.control}
                      name={`outcomes.${index}.title`}
                      render={({ field }) => (
                        <FormItem className="flex-1">
                          <FormControl>
                            <Input
                              placeholder={`${t('Outcome')} ${index + 1}`}
                              {...field}
                            />
                          </FormControl>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                    {type === 'multi' && fields.length > 2 && (
                      <Button
                        type="button"
                        variant="ghost"
                        size="icon"
                        onClick={() => remove(index)}
                      >
                        <MinusIcon weight="bold" className="size-4" />
                      </Button>
                    )}
                  </div>
                ))}
                {type === 'multi' && (
                  <Button
                    type="button"
                    variant="ghost"
                    size="sm"
                    onClick={() => append({ title: '', color: '#22c55e' })}
                  >
                    <PlusIcon weight="bold" className="mr-1.5 size-4" />
                    {t('Add Outcome')}
                  </Button>
                )}
                {form.formState.errors.outcomes?.root && (
                  <p className="text-sm text-destructive">
                    {form.formState.errors.outcomes.root.message}
                  </p>
                )}
              </div>
            </div>

            <div className="space-y-4">
              <div className="grid grid-cols-2 gap-4">
                {formFields.timing.map((f) => (
                  <FormRenderer form={form} key={f.id} item={f} />
                ))}
              </div>

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

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

              <OracleConfigSection
                form={form}
                outcomes={form.watch('outcomes')}
                fieldSlots={{
                  market_id: <MarketLookup onImported={handleUmaImport} />,
                }}
              />

              {form.watch('oracle_type') === 'uma' && (
                <UmaImport form={form} onImported={handleUmaImport} />
              )}
            </div>
          </div>

          <div className="mt-6 flex justify-end gap-3 border-t border-black/5 pt-4 dark:border-white/10">
            <Button
              type="button"
              variant="secondary"
              onClick={() => router.visit('/admin/markets')}
            >
              {t('Cancel')}
            </Button>
            <Button type="submit" loading={form.formState.isSubmitting}>
              {t('Create Market')}
            </Button>
          </div>
        </form>
      </Form>
    </div>
  );
};

CreateMarket.title = 'Create Market';

export default CreateMarket;
