import { Component, createMemo, createResource, createSignal, For, Show } from "solid-js";
import { logsApi } from "../api/client";
import type { RequestLog as RequestLogType } from "../types";
import { Button } from "./ui/Button";
import { Card } from "./ui/Card";
import { Input } from "./ui/Input";
import { Select } from "./ui/Select";
import RequestDetails from "./RequestDetails";

const RequestLogs: Component = () => {
  const [search, setSearch] = createSignal("");
  const [inputValue, setInputValue] = createSignal("");
  const [method, setMethod] = createSignal("");
  const [selectedLog, setSelectedLog] = createSignal<RequestLogType | null>(null);

  let debounceTimer: number;
  const handleInput = (e: { currentTarget: { value: string } }) => {
    const value = e.currentTarget.value;
    setInputValue(value);
    clearTimeout(debounceTimer);
    debounceTimer = window.setTimeout(() => setSearch(value), 300);
  };

  const [logs, { refetch: refetchLogs }] = createResource(
    () => ({ search: search(), method: method() }),
    async (filters) => {
      return logsApi.list(filters);
    },
  );
  const [allLogs, { refetch: refetchAllLogs }] = createResource(async () => {
    return await logsApi.list();
  });
  const methods = createMemo(() => {
    return allLogs.loading ? [] : [...new Set(allLogs()!.map((log) => log.method))];
  });
  const refetch = () => {
    refetchLogs();
    refetchAllLogs();
  };

  const handleLogClick = (log: RequestLogType) => {
    setSelectedLog(log);
  };

  const handleCloseDetails = () => {
    setSelectedLog(null);
  };

  const formatDate = (dateStr: string) => {
    return new Date(dateStr).toLocaleString();
  };

  return (
    <>
      <div class="space-y-4">
        <div class="flex items-center justify-between">
          <h2 class="text-2xl font-semibold">
            Request Logs
            <Show when={logs() && !logs.loading && !allLogs.loading}>
              <span class="text-gray-500 text-base ml-2">
                ({logs()?.length} of {allLogs()?.length} logs)
              </span>
            </Show>
          </h2>
          <Button onClick={() => refetch()} variant="secondary">
            Refresh
          </Button>
        </div>

        <Card>
          <div class="p-4 flex flex-col sm:flex-row items-center space-y-4 sm:space-x-4 sm:space-y-0 bg-gray-50 border-b">
            <div class="flex-1 w-full">
              <Input
                type="text"
                placeholder="Search in request/response..."
                value={inputValue()}
                onInput={handleInput}
              />
            </div>
            <div class="w-full sm:w-1/4">
              <Select value={method()} onChange={(e) => setMethod(e.currentTarget.value)} class="w-full">
                <option value="">All Methods</option>
                <For each={methods()}>{(m) => <option value={m}>{m}</option>}</For>
              </Select>
            </div>
          </div>

          <div class="overflow-x-auto">
            <table class="min-w-full divide-y divide-gray-200">
              <thead class="bg-gray-50">
                <tr>
                  <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Method</th>
                  <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Time</th>
                  <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">
                    Request Body
                  </th>
                </tr>
              </thead>
              <tbody class="bg-white divide-y divide-gray-200">
                <Show
                  when={!logs.loading}
                  fallback={
                    <tr>
                      <td colspan="3" class="text-center py-4">
                        Loading...
                      </td>
                    </tr>
                  }
                >
                  <For
                    each={logs()}
                    fallback={
                      <tr>
                        <td colspan="3" class="text-center py-8 text-gray-500">
                          No logs found.
                        </td>
                      </tr>
                    }
                  >
                    {(log) => (
                      <tr class="hover:bg-gray-50 cursor-pointer" onClick={() => handleLogClick(log)}>
                        <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
                          {log.method}
                        </td>
                        <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
                          {formatDate(log.created_at)}
                        </td>
                        <td class="px-6 py-4 text-sm text-gray-500 font-mono truncate max-w-lg">
                          {JSON.stringify(log.request_body)}
                        </td>
                      </tr>
                    )}
                  </For>
                </Show>
              </tbody>
            </table>
          </div>
        </Card>
      </div>
      <Show when={selectedLog()}>{(log) => <RequestDetails log={log()} onClose={handleCloseDetails} />}</Show>
    </>
  );
};

export default RequestLogs;
