/**
 * PropertyInspectorRenderer - Custom JSONForms control for property inspection.
 *
 * Renders when schema has x-custom-type="property-inspector"
 * Displays property selector + table for per-particle and global properties.
 */

import { useMemo, useCallback } from "react";
import { withJsonFormsControlProps } from "@jsonforms/react";
import { rankWith, schemaMatches, and, uiTypeIs, ControlProps } from "@jsonforms/core";
import {
  Box,
  Typography,
  Divider,
  CircularProgress,
  Paper,
  Alert,
} from "@mui/material";
import { useAppStore } from "../../store";
import { useAvailableProperties } from "../../hooks/usePropertyInspector";
import PropertySelector from "./components/PropertySelector";

/**
 * PropertyInspectorRenderer Component
 *
 * ControlProps provided by withJsonFormsControlProps:
 * - data: string[] - Array of selected property keys
 * - handleChange: (path, value) => void - Update form data
 * - path: string - JSON path to this field
 * - label: string - Field label from schema
 * - schema: any - JSON schema for this field
 * - required: boolean - Whether field is required
 * - errors: string - Validation errors
 */
const PropertyInspectorRenderer = ({
  data,
  handleChange,
  path,
  label,
  errors,
}: ControlProps) => {
  const { roomId, particleCount, currentFrame } = useAppStore();

  // Fetch available properties with categorization
  const {
    data: categories,
    isLoading,
    isError,
  } = useAvailableProperties(roomId || undefined, currentFrame, particleCount);

  // data is the array of selected property keys (from enabled_properties field)
  const selectedKeys: string[] = useMemo(() => data || [], [data]);

  // Memoized handler to update JSONForms data
  const handlePropertyToggle = useCallback((key: string) => {
    const keys = new Set(selectedKeys);
    if (keys.has(key)) {
      keys.delete(key);
    } else {
      keys.add(key);
    }
    handleChange(path, Array.from(keys));
  }, [selectedKeys, handleChange, path]);

  const handleClearAll = useCallback(() => {
    handleChange(path, []);
  }, [handleChange, path]);

  if (!roomId) {
    return (
      <Paper variant="outlined" sx={{ mb: 2, p: 2 }}>
        <Alert severity="info">
          Property Inspector requires an active room connection
        </Alert>
      </Paper>
    );
  }

  if (!categories && isLoading) {
    return (
      <Paper variant="outlined" sx={{ mb: 2, p: 2 }}>
        <Box sx={{ display: "flex", justifyContent: "center", alignItems: "center", gap: 2 }}>
          <CircularProgress size={24} />
          <Typography>Loading properties...</Typography>
        </Box>
      </Paper>
    );
  }

  if (isError) {
    return (
      <Paper variant="outlined" sx={{ mb: 2, p: 2 }}>
        <Alert severity="error">Failed to load property metadata</Alert>
      </Paper>
    );
  }

  return (
    <Paper variant="outlined" sx={{ mb: 2, overflow: "hidden" }}>
      {/* Header */}
      <Box sx={{ p: 2, bgcolor: "action.hover" }}>
        <Typography variant="subtitle2" fontWeight="bold">
          {label || "Property Inspector"}
        </Typography>
        <Typography variant="caption" color="text.secondary">
          Select properties to display in InfoBoxes (press 'i' to toggle)
        </Typography>
      </Box>

      <Divider />

      {/* Property Selector - Collapsible multi-select */}
      <Box sx={{ maxHeight: 400, overflow: "auto" }}>
        <PropertySelector
          perParticleProps={categories?.perParticle || []}
          globalProps={categories?.global || []}
          selectedKeys={selectedKeys}
          onToggle={handlePropertyToggle}
          onClearAll={handleClearAll}
        />
      </Box>

      {errors && (
        <Alert severity="error" sx={{ m: 1 }}>
          {errors}
        </Alert>
      )}
    </Paper>
  );
};

/**
 * Tester function - determines when to use this renderer.
 * Priority 10 to override default array renderers.
 */
export const propertyInspectorTester = rankWith(
  10,
  and(
    schemaMatches((schema) => (schema as any)["x-custom-type"] === "property-inspector"),
    uiTypeIs("Control")
  )
);

// Export wrapped with JSONForms HOC
export default withJsonFormsControlProps(PropertyInspectorRenderer);
