import { Space } from "antd";
import { useState } from "react";

import type { Model, Provider, TestModelRequest } from "../../../shared/api";

import {
  useCreateModel,
  useDeleteModel,
  useModelList,
  useTestModelConnection,
  useUpdateModel,
} from "../../shared/hooks/use-models";
import {
  useCreateProvider,
  useDeleteProvider,
  useProviderList,
  useProviderOptions,
  useTestProviderConfig,
  useUpdateProvider,
} from "../../shared/hooks/use-providers";
import { ModelFormModal } from "./components/ModelFormModal";
import { ModelsToolbar } from "./components/ModelsToolbar";
import { ModelTable } from "./components/ModelTable";
import { ProviderFormModal } from "./components/ProviderFormModal";
import { ProviderTable } from "./components/ProviderTable";

export function ModelsPage() {
  const [activeTab, setActiveTab] = useState<string>("models");

  const [providerPage, setProviderPage] = useState(1);
  const [providerPageSize, setProviderPageSize] = useState(20);
  const [providerKeyword, setProviderKeyword] = useState("");
  const [providerDialogOpen, setProviderDialogOpen] = useState(false);
  const [editingProvider, setEditingProvider] = useState<null | Provider>(null);

  const [modelPage, setModelPage] = useState(1);
  const [modelPageSize, setModelPageSize] = useState(20);
  const [modelKeyword, setModelKeyword] = useState("");
  const [modelDialogOpen, setModelDialogOpen] = useState(false);
  const [editingModel, setEditingModel] = useState<Model | null>(null);

  const { data: providerData, isLoading: providerLoading } = useProviderList({
    keyword: providerKeyword || undefined,
    page: providerPage,
    pageSize: providerPageSize,
  });

  const {
    data: providerOptionsData,
    error: providerOptionsError,
    isError: providerOptionsIsError,
    isLoading: providerOptionsLoading,
  } = useProviderOptions();

  const { data: modelData, isLoading: modelLoading } = useModelList({
    keyword: modelKeyword || undefined,
    page: modelPage,
    pageSize: modelPageSize,
  });

  const createProviderMutation = useCreateProvider();
  const updateProviderMutation = useUpdateProvider();
  const deleteProviderMutation = useDeleteProvider();
  const testProviderConfigMutation = useTestProviderConfig();

  const createModelMutation = useCreateModel();
  const updateModelMutation = useUpdateModel();
  const deleteModelMutation = useDeleteModel();
  const testModelMutation = useTestModelConnection();

  const isProviderSubmitting = createProviderMutation.isPending || updateProviderMutation.isPending;
  const isProviderActionPending = deleteProviderMutation.isPending;

  const isModelSubmitting = createModelMutation.isPending || updateModelMutation.isPending;
  const isModelActionPending = deleteModelMutation.isPending;
  const modelProviders = providerOptionsData?.items ?? [];

  const currentKeyword = activeTab === "providers" ? providerKeyword : modelKeyword;

  const handleSearch =
    activeTab === "providers"
      ? (value: string) => {
          setProviderKeyword(value);
          setProviderPage(1);
        }
      : (value: string) => {
          setModelKeyword(value);
          setModelPage(1);
        };

  const handleSearchClear =
    activeTab === "providers"
      ? () => {
          setProviderKeyword("");
          setProviderPage(1);
        }
      : () => {
          setModelKeyword("");
          setModelPage(1);
        };

  const handleOpenCreate =
    activeTab === "providers"
      ? () => {
          setEditingProvider(null);
          setProviderDialogOpen(true);
        }
      : () => {
          setEditingModel(null);
          setModelDialogOpen(true);
        };

  return (
    <Space className="app-page-flex" orientation="vertical" size="large">
      <ModelsToolbar
        activeTab={activeTab}
        key={activeTab}
        keyword={currentKeyword}
        onSearch={handleSearch}
        onSearchClear={handleSearchClear}
        onTabChange={(key) => setActiveTab(key)}
        openCreateDialog={handleOpenCreate}
      />

      {activeTab === "providers" && (
        <>
          <ProviderTable
            data={providerData}
            loading={providerLoading || isProviderActionPending}
            onDelete={(id) => deleteProviderMutation.mutateAsync(id)}
            onEdit={(provider) => {
              setEditingProvider(provider);
              setProviderDialogOpen(true);
            }}
            onPageChange={(p, ps) => {
              setProviderPage(p);
              setProviderPageSize(ps);
            }}
            page={providerPage}
            pageSize={providerPageSize}
          />
          <ProviderFormModal
            editingProvider={editingProvider}
            onCancel={() => setProviderDialogOpen(false)}
            onCreate={(data) => createProviderMutation.mutateAsync(data)}
            onOpenChange={setProviderDialogOpen}
            onTest={(data) => testProviderConfigMutation.mutateAsync(data)}
            onUpdate={(args) => updateProviderMutation.mutateAsync(args)}
            open={providerDialogOpen}
            submitting={isProviderSubmitting}
          />
        </>
      )}

      {activeTab === "models" && (
        <>
          <ModelTable
            data={modelData}
            loading={modelLoading || providerOptionsLoading || isModelActionPending}
            onDelete={(id) => deleteModelMutation.mutateAsync(id)}
            onEdit={(model) => {
              setEditingModel(model);
              setModelDialogOpen(true);
            }}
            onPageChange={(p, ps) => {
              setModelPage(p);
              setModelPageSize(ps);
            }}
            page={modelPage}
            pageSize={modelPageSize}
            providers={modelProviders}
          />
          <ModelFormModal
            editingModel={editingModel}
            onCancel={() => setModelDialogOpen(false)}
            onCreate={(data) => createModelMutation.mutateAsync(data)}
            onOpenChange={setModelDialogOpen}
            onUpdate={(args) => updateModelMutation.mutateAsync(args)}
            open={modelDialogOpen}
            providers={modelProviders}
            providersError={providerOptionsIsError ? providerOptionsError : null}
            providersLoading={providerOptionsLoading}
            submitting={isModelSubmitting}
            testModelConnection={(data: TestModelRequest) => testModelMutation.mutateAsync(data)}
          />
        </>
      )}
    </Space>
  );
}
