import { useState } from "react";
import { z } from "zod";
import {
  AthenaClientRecord,
  RuntimeAthenaClient,
  createAthenaClient,
  deleteAthenaClient,
  freezeAthenaClient,
  listAthenaClients,
  updateAthenaClient,
} from "@/app/lib/api";
import { RunAction } from "@/app/hooks/useActionFeedback";

type UseAthenaClientsAdminProps = {
  adminApiKey: string;
  runAction: RunAction;
};

const createClientPayloadSchema = z.object({
  client_name: z.string().trim().min(1, "client_name is required"),
  description: z.string().optional(),
  pg_uri: z.string().optional(),
  pg_uri_env_var: z.string().optional(),
  is_active: z.boolean().optional(),
});

function parseJsonPayload(rawJson: string): unknown {
  try {
    return JSON.parse(rawJson);
  } catch {
    throw new Error("Invalid JSON payload");
  }
}

export function useAthenaClientsAdmin({
  adminApiKey,
  runAction,
}: UseAthenaClientsAdminProps) {
  const [adminClients, setAdminClients] = useState<AthenaClientRecord[]>([]);
  const [runtimeClients, setRuntimeClients] = useState<RuntimeAthenaClient[]>([]);
  const [newClientJson, setNewClientJson] = useState(
    JSON.stringify(
      {
        client_name: "new_client",
        description: "Managed from Athena Studio",
        pg_uri_env_var: "NEW_CLIENT_DATABASE_URL",
        is_active: true,
      },
      null,
      2,
    ),
  );
  const [patchClientName, setPatchClientName] = useState("");
  const [patchClientJson, setPatchClientJson] = useState(
    JSON.stringify(
      {
        description: "Updated from Athena Studio",
        is_active: true,
      },
      null,
      2,
    ),
  );
  const [freezeClientName, setFreezeClientName] = useState("");
  const [freezeClientValue, setFreezeClientValue] = useState(true);
  const [deleteClientName, setDeleteClientName] = useState("");

  const reloadAdminClients = async () => {
    if (!adminApiKey.trim()) return;
    const data = await listAthenaClients(adminApiKey.trim());
    setAdminClients(data.clients);
    setRuntimeClients(data.runtime);
  };

  const handleOpen = () => runAction("Loaded Athena clients", reloadAdminClients);
  const handleReload = () => runAction("Reloaded Athena clients", reloadAdminClients);

  const handleCreateClient = () =>
    runAction("Created Athena client", async () => {
      const current = await listAthenaClients(adminApiKey.trim());
      const existingNames = new Set(
        current.clients.map((client) => client.client_name.trim().toLowerCase()),
      );

      const payload = createClientPayloadSchema
        .superRefine((value, ctx) => {
          if (existingNames.has(value.client_name.trim().toLowerCase())) {
            ctx.addIssue({
              code: z.ZodIssueCode.custom,
              path: ["client_name"],
              message: `A client named '${value.client_name}' already exists.`,
            });
          }
        })
        .parse(parseJsonPayload(newClientJson));

      await createAthenaClient(payload, adminApiKey.trim());
      await reloadAdminClients();
    });

  const handleUpdateClient = () =>
    runAction("Updated Athena client", async () => {
      await updateAthenaClient(
        patchClientName.trim(),
        JSON.parse(patchClientJson) as {
          description?: string;
          pg_uri?: string;
          pg_uri_env_var?: string;
          is_active?: boolean;
        },
        adminApiKey.trim(),
      );
      await reloadAdminClients();
    });

  const handleApplyFreeze = () =>
    runAction("Updated freeze state", async () => {
      await freezeAthenaClient(
        freezeClientName.trim(),
        freezeClientValue,
        adminApiKey.trim(),
      );
      await reloadAdminClients();
    });

  const handleDeleteClient = () =>
    runAction("Deleted Athena client", async () => {
      await deleteAthenaClient(deleteClientName.trim(), adminApiKey.trim());
      await reloadAdminClients();
    });

  return {
    adminClients,
    runtimeClients,
    newClientJson,
    setNewClientJson,
    patchClientName,
    setPatchClientName,
    patchClientJson,
    setPatchClientJson,
    freezeClientName,
    setFreezeClientName,
    freezeClientValue,
    setFreezeClientValue,
    deleteClientName,
    setDeleteClientName,
    handleOpen,
    handleReload,
    handleCreateClient,
    handleUpdateClient,
    handleApplyFreeze,
    handleDeleteClient,
  };
}
