import {
  type Component,
  createSignal,
  createResource,
  createEffect,
  Show,
  For,
} from 'solid-js';
import { Gauge, Save } from 'lucide-solid';
import { adminRateLimitsApi } from '~/api/admin';
import { useI18n } from '~/i18n';
import { useToast } from '~/components/ui/Toast';
import { isApiError } from '~/types';
import type { AdminRateLimit } from '~/types';
import LoadingSpinner from '~/components/ui/LoadingSpinner';
import Button from '~/components/ui/Button';

/** Local mutable copy of a rate-limit row for editing without modifying the resource. */
interface LocalRateLimit {
  id: string;
  provider_name: string;
  max_requests: number;
  time_window_seconds: number;
}

/**
 * Admin page for viewing and updating per-provider API rate-limit configuration.
 *
 * Fetched rate limits are copied into local signals so form inputs can mutate
 * freely. Saving PUTs the updated values to the backend and refetches.
 */
const RateLimits: Component = () => {
  const { t } = useI18n();
  const { addToast } = useToast();

  const [rateLimits, { refetch }] = createResource(() =>
    adminRateLimitsApi.list(),
  );
  const [localLimits, setLocalLimits] = createSignal<LocalRateLimit[]>([]);
  const [savingId, setSavingId] = createSignal<string | null>(null);

  // Sync fetched data to local state
  createEffect(() => {
    const data = rateLimits();
    if (data) {
      setLocalLimits(
        data.map((rl) => ({
          id: rl.id,
          provider_name: rl.provider_name,
          max_requests: rl.max_requests,
          time_window_seconds: rl.time_window_seconds,
        })),
      );
    }
  });

  const updateLocal = (
    id: string,
    field: 'max_requests' | 'time_window_seconds',
    value: number,
  ) => {
    setLocalLimits((prev) =>
      prev.map((rl) => (rl.id === id ? { ...rl, [field]: value } : rl)),
    );
  };

  const handleSave = async (limit: LocalRateLimit) => {
    setSavingId(limit.id);
    try {
      await adminRateLimitsApi.update(limit.id, {
        max_requests: limit.max_requests,
        time_window_seconds: limit.time_window_seconds,
      });
      addToast({
        type: 'success',
        message: t('admin.rateLimits.saved'),
        duration: 3000,
      });
      refetch();
    } catch (err) {
      const message = isApiError(err)
        ? err.message
        : t('admin.rateLimits.saveError');
      addToast({ type: 'error', message, duration: 5000 });
    } finally {
      setSavingId(null);
    }
  };

  return (
    <div class="max-w-4xl mx-auto">
      <div class="mb-8">
        <div class="flex items-center">
          <Gauge class="h-8 w-8 text-indigo-600 mr-3" />
          <h1 class="text-2xl font-bold text-gray-900">
            {t('admin.rateLimits.title')}
          </h1>
        </div>
        <p class="mt-1 text-sm text-gray-500">
          {t('admin.rateLimits.subtitle')}
        </p>
      </div>

      {/* Loading state */}
      <Show when={rateLimits.loading}>
        <LoadingSpinner />
      </Show>

      {/* Error state */}
      <Show when={rateLimits.error}>
        <div class="bg-red-50 border border-red-200 text-red-800 rounded-md p-4">
          {t('admin.rateLimits.loadError')}
        </div>
      </Show>

      {/* Empty state */}
      <Show
        when={
          !rateLimits.loading &&
          !rateLimits.error &&
          localLimits().length === 0
        }
      >
        <div class="bg-white shadow-sm border border-gray-200 rounded-lg p-8 text-center">
          <Gauge class="h-12 w-12 text-gray-300 mx-auto mb-4" />
          <p class="text-gray-500 font-medium">
            {t('admin.rateLimits.empty')}
          </p>
          <p class="text-sm text-gray-400 mt-1">
            {t('admin.rateLimits.emptyHint')}
          </p>
        </div>
      </Show>

      {/* Rate limit cards */}
      <div class="space-y-4">
        <For each={localLimits()}>
          {(limit) => (
            <div class="bg-white shadow-sm border border-gray-200 rounded-lg">
              <div class="px-6 py-4 border-b border-gray-200">
                <h2 class="text-lg font-semibold text-gray-900">
                  {limit.provider_name}
                </h2>
              </div>
              <div class="px-6 py-4">
                <div class="grid grid-cols-1 sm:grid-cols-2 gap-6">
                  <div>
                    <label class="block text-sm font-medium text-gray-700">
                      {t('admin.rateLimits.maxRequests')}
                    </label>
                    <input
                      type="number"
                      min="1"
                      class="mt-1 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md py-2 px-3 border focus:ring-indigo-500 focus:border-indigo-500"
                      value={limit.max_requests}
                      onInput={(e) =>
                        updateLocal(
                          limit.id,
                          'max_requests',
                          parseInt(e.currentTarget.value) || 1,
                        )
                      }
                    />
                  </div>
                  <div>
                    <label class="block text-sm font-medium text-gray-700">
                      {t('admin.rateLimits.timeWindow')}
                    </label>
                    <input
                      type="number"
                      min="1"
                      class="mt-1 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md py-2 px-3 border focus:ring-indigo-500 focus:border-indigo-500"
                      value={limit.time_window_seconds}
                      onInput={(e) =>
                        updateLocal(
                          limit.id,
                          'time_window_seconds',
                          parseInt(e.currentTarget.value) || 1,
                        )
                      }
                    />
                  </div>
                </div>
                <p class="mt-3 text-sm text-gray-500">
                  {t('admin.rateLimits.effectiveRate', {
                    count: limit.max_requests,
                    seconds: limit.time_window_seconds,
                  })}
                </p>
              </div>
              <div class="px-6 py-3 bg-gray-50 border-t border-gray-200 flex justify-end rounded-b-lg">
                <Button
                  icon={Save}
                  loading={savingId() === limit.id}
                  onClick={() => handleSave(limit)}
                >
                  {t('admin.rateLimits.save')}
                </Button>
              </div>
            </div>
          )}
        </For>
      </div>
    </div>
  );
};

export default RateLimits;
