import {
  FormControl,
  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 { Separator } from '@/components/ui/separator';
import { Textarea } from '@/components/ui/textarea';
import { useOracleDrivers } from '@/hooks/useOracleDrivers';
import { TOracleField } from '@/types/market.types';
import { ReactNode } from 'react';
import { useWatch } from 'react-hook-form';
import { useTranslation } from 'react-i18next';

type OutcomeLike = { title?: string };

/**
 * Driver-agnostic oracle config editor. It reads the selected driver's
 * self-describing field list and renders inputs dynamically, so new providers
 * (UMA, sports, …) need no changes here — they just declare their fields
 * server-side.
 *
 * All values are written under the `oracle_config` form key. Outcome mappings
 * are stored by outcome *title*; the server resolves them to ids on save.
 */
export default function OracleConfigSection({
  form,
  outcomes,
  fieldSlots,
}: {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  form: any;
  outcomes: OutcomeLike[];
  // Optional add-on rendered beside a driver field, keyed by field key (e.g. a
  // "Market Lookup" button next to the uma `market_id` input).
  fieldSlots?: Partial<Record<string, ReactNode>>;
}) {
  const { t } = useTranslation();
  const { drivers, isLoading } = useOracleDrivers();

  // Subscribe directly to the field store. `form.watch()` only schedules
  // re-renders on the component that called `useForm` (the parent), so relying
  // on it here can leave this child stale when `oracle_type` changes or the
  // async driver list settles — hiding the config fields until a forced render.
  const oracleType: string =
    useWatch({ control: form.control, name: 'oracle_type' }) ?? 'manual';
  const driver = drivers.find((d) => d.key === oracleType);
  const outcomeTitles = outcomes
    .map((o) => o.title?.trim())
    .filter((titleValue): titleValue is string => !!titleValue);

  return (
    <div className="space-y-4 rounded-xl border border-black/5 p-4">
      <div>
        <h4 className="text-lg font-medium">{t('Resolution')}</h4>
        <p className="text-sm text-black/50 dark:text-white/50">
          {t('Choose how this market is resolved when it closes.')}
        </p>
      </div>
      <Separator />

      <FormField
        control={form.control}
        name="oracle_type"
        render={({ field }) => (
          <FormItem>
            <FormLabel>{t('Resolution Source')}</FormLabel>
            <Select
              value={field.value ?? 'manual'}
              onValueChange={field.onChange}
              disabled={isLoading}
            >
              <FormControl>
                <SelectTrigger>
                  <SelectValue placeholder={t('Select a source')} />
                </SelectTrigger>
              </FormControl>
              <SelectContent>
                {drivers.map((d) => (
                  <SelectItem key={d.key} value={d.key}>
                    {d.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <FormMessage />
          </FormItem>
        )}
      />

      {oracleType !== 'manual' && driver && (
        <div className="space-y-4">
          {driver.fields.map((fieldDef) =>
            renderDriverField(
              fieldDef,
              form,
              outcomeTitles,
              t,
              fieldSlots?.[fieldDef.key],
            ),
          )}

          <FormField
            control={form.control}
            name="dispute_window_minutes"
            render={({ field }) => (
              <FormItem>
                <FormLabel>{t('Dispute Window (minutes)')}</FormLabel>
                <FormControl>
                  <Input
                    type="number"
                    min={0}
                    placeholder="120"
                    {...field}
                    value={field.value ?? ''}
                  />
                </FormControl>
                <p className="text-xs text-black/50 dark:text-white/50">
                  {t(
                    'Time to allow an admin override before the proposed outcome is finalised. 0 resolves immediately.',
                  )}
                </p>
                <FormMessage />
              </FormItem>
            )}
          />
        </div>
      )}

      <FormField
        control={form.control}
        name="resolution_criteria"
        render={({ field }) => (
          <FormItem>
            <FormLabel>{t('Resolution Criteria')}</FormLabel>
            <FormControl>
              <Textarea
                placeholder={t(
                  'Plain-language rules and sources used to decide the outcome.',
                )}
                {...field}
                value={field.value ?? ''}
              />
            </FormControl>
            <FormMessage />
          </FormItem>
        )}
      />
    </div>
  );
}

function renderDriverField(
  fieldDef: TOracleField,
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  form: any,
  outcomeTitles: string[],
  t: (key: string) => string,
  slot?: ReactNode,
) {
  const name = `oracle_config.${fieldDef.key}`;

  if (fieldDef.type === 'outcome_map') {
    return (
      <div key={fieldDef.key} className="space-y-2">
        <FormLabel>{t(fieldDef.label)}</FormLabel>
        <div className="space-y-2">
          {(fieldDef.cases ?? []).map((c) => (
            <FormField
              key={c.key}
              control={form.control}
              name={`oracle_config.${fieldDef.key}.${c.key}`}
              render={({ field }) => (
                <FormItem className="flex items-center justify-between gap-3">
                  <FormLabel className="text-sm font-normal text-black/60 dark:text-white/60">
                    {t(c.label)}
                  </FormLabel>
                  <Select
                    value={field.value ? String(field.value) : ''}
                    onValueChange={field.onChange}
                  >
                    <FormControl>
                      <SelectTrigger className="w-48">
                        <SelectValue placeholder={t('Select outcome')} />
                      </SelectTrigger>
                    </FormControl>
                    <SelectContent>
                      {outcomeTitles.map((title) => (
                        <SelectItem key={title} value={title}>
                          {title}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </FormItem>
              )}
            />
          ))}
        </div>
      </div>
    );
  }

  if (fieldDef.type === 'select') {
    return (
      <FormField
        key={fieldDef.key}
        control={form.control}
        name={name}
        render={({ field }) => (
          <FormItem>
            <FormLabel>{t(fieldDef.label)}</FormLabel>
            <Select
              value={field.value ? String(field.value) : ''}
              onValueChange={field.onChange}
            >
              <FormControl>
                <SelectTrigger>
                  <SelectValue placeholder={fieldDef.placeholder ?? ''} />
                </SelectTrigger>
              </FormControl>
              <SelectContent>
                {(fieldDef.options ?? []).map((opt) => (
                  <SelectItem key={opt.value} value={opt.value}>
                    {opt.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <FormMessage />
          </FormItem>
        )}
      />
    );
  }

  return (
    <FormField
      key={fieldDef.key}
      control={form.control}
      name={name}
      render={({ field }) => (
        <FormItem>
          <FormLabel>{t(fieldDef.label)}</FormLabel>
          <div className="flex items-center gap-2">
            <div className="min-w-0 flex-1">
              <FormControl>
                <Input
                  type={fieldDef.type === 'number' ? 'number' : 'text'}
                  placeholder={fieldDef.placeholder ?? ''}
                  {...field}
                  value={field.value ?? ''}
                />
              </FormControl>
            </div>
            {slot}
          </div>
          <FormMessage />
        </FormItem>
      )}
    />
  );
}
