import { useState, useMemo } from "react";
import { krowSDK } from "@/api/krowSDK";
import { Button } from "@/components/ui/button";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import ApiResponse from "@/components/ApiResponse";
import { Textarea } from "@/components/ui/textarea";
import { Label } from "@/components/ui/label";

const entityNames = Object.keys(krowSDK.entities).sort();

const getPrettifiedJSON = (entity, method) => {
  // Basic placeholder payloads. A more advanced SDK could provide detailed examples.
  const payloads = {
    get: { id: "some-id" },
    create: { data: { property: "value" } },
    update: { id: "some-id", data: { property: "new-value" } },
    delete: { id: "some-id" },
    filter: { where: { property: { _eq: "value" } } },
    list: {}
  };
  return JSON.stringify(payloads[method] || {}, null, 2);
};

const EntityTester = () => {
  const [selectedEntity, setSelectedEntity] = useState(null);
  const [selectedMethod, setSelectedMethod] = useState(null);
  const [response, setResponse] = useState(null);
  const [error, setError] = useState(null);
  const [loading, setLoading] = useState(false);
  const [jsonInput, setJsonInput] = useState("");
  const [jsonError, setJsonError] = useState(null);

  const availableMethods = useMemo(() => {
    if (!selectedEntity) return [];
    return Object.keys(krowSDK.entities[selectedEntity]);
  }, [selectedEntity]);

  const handleEntityChange = (entity) => {
    setSelectedEntity(entity);
    setSelectedMethod(null);
    setJsonInput("");
    setJsonError(null);
    setResponse(null);
    setError(null);
  };

  const handleMethodSelect = (method) => {
    setSelectedMethod(method);
    setJsonInput(getPrettifiedJSON(selectedEntity, method));
    setJsonError(null);
    setResponse(null);
    setError(null);
  };

  const handleJsonInputChange = (e) => {
    setJsonInput(e.target.value);
    try {
      JSON.parse(e.target.value);
      setJsonError(null);
    } catch (err) {
      setJsonError("Invalid JSON format");
    }
  };

  const executeApi = async () => {
    if (!selectedEntity || !selectedMethod || jsonError) return;

    setLoading(true);
    setResponse(null);
    setError(null);

    try {
      const params = JSON.parse(jsonInput);
      const sdkMethod = krowSDK.entities[selectedEntity][selectedMethod];
      const res = await sdkMethod(params);
      setResponse(res);
    } catch (err) {
      setError(err.response?.data || err.message);
    } finally {
      setLoading(false);
    }
  };

  const renderMethodForm = () => {
    if (!selectedMethod) {
      return (
        <div className="mt-4 p-4 text-center text-slate-500 bg-slate-50 rounded-lg">
          <p>Select a method to begin.</p>
        </div>
      );
    }

    return (
      <div className="space-y-4 mt-6">
        <h3 className="text-lg font-semibold text-slate-800">
          Parameters for <code className="bg-slate-100 p-1 rounded text-sm">/{selectedEntity}/{selectedMethod}</code>
        </h3>
        
        {/* 
          This is a textarea for JSON input. A more advanced implementation could
          dynamically generate a form based on the expected parameters of each
          SDK method, but that requires metadata about each method's signature
          which is not currently available in the mock client.
        */}
        <div className="space-y-2">
          <Label htmlFor="params">JSON Payload</Label>
          <Textarea
            id="params"
            name="params"
            value={jsonInput}
            onChange={handleJsonInputChange}
            rows={8}
            className={`font-mono text-sm ${jsonError ? 'border-red-500 focus-visible:ring-red-500' : ''}`}
          />
          {jsonError && <p className="text-xs text-red-600">{jsonError}</p>}
        </div>

        <Button onClick={executeApi} disabled={loading || !!jsonError}>
          {loading ? "Executing..." : "Execute"}
        </Button>
      </div>
    );
  };

  return (
    <div>
      <header className="mb-8">
        <h1 className="text-3xl font-bold text-slate-900">Entity API Tester</h1>
        <p className="text-slate-600 mt-1">
          Select an entity and method, provide the required parameters in JSON format, and execute the API call.
        </p>
      </header>

      <Card className="shadow-sm">
        <CardHeader>
          <CardTitle>API Configuration</CardTitle>
          <CardDescription>Choose a Base44 entity and method to interact with.</CardDescription>
        </CardHeader>
        <CardContent>
          <div className="grid grid-cols-1 md:grid-cols-3 gap-4 items-start">
            <div className="col-span-1">
              <Label>Entity</Label>
              <Select onValueChange={handleEntityChange} value={selectedEntity || ""}>
                <SelectTrigger>
                  <SelectValue placeholder="Select an entity" />
                </SelectTrigger>
                <SelectContent>
                  {entityNames.map(entity => (
                    <SelectItem key={entity} value={entity}>{entity}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            
            {selectedEntity && (
              <div className="col-span-2">
                <Label>Method</Label>
                <div className="flex flex-wrap items-center gap-2 pt-2">
                  {availableMethods.map(method => (
                    <Button 
                      key={method}
                      variant={selectedMethod === method ? "default" : "outline"}
                      size="sm"
                      onClick={() => handleMethodSelect(method)}
                    >
                      {method}
                    </Button>
                  ))}
                </div>
              </div>
            )}
          </div>

          {renderMethodForm()}
        </CardContent>
      </Card>

      <ApiResponse response={response} error={error} loading={loading} />
    </div>
  );
};

export default EntityTester;
