import React, { useState, useMemo } from "react";
import { useNavigate } from "react-router-dom";
import { Plus, Database, Box, Search, Filter } from "lucide-react";
import {
  useSchemas,
  useCreateSchema,
  useDeleteSchema,
} from "../infrastructure/api/objectQueries";
import { useObjectDescriptions } from "../infrastructure/api/objectMetadataHooks";
import { ObjectList } from "../features/objects/components/ObjectList";
import {
  CreateObjectModal,
  type ObjectFormData,
} from "../features/objects/components/CreateObjectModal";
import { ConfirmationModal } from "@nexuscrm/salesforce-crm-standard-frontend/platform/components/ui";
import { useErrorToast } from "@nexuscrm/salesforce-crm-standard-frontend/platform/components/ui";
import { EmptyState } from "@nexuscrm/salesforce-crm-standard-frontend/platform/components/ui";
import { Logger } from "../core/services/Logger";
import { formatApiError } from "@nexuscrm/host-sdk";
import type { SObjectDescribe } from "../types";
import { tryBuildSetupCapabilityChildPath } from "../core/navigation/setupPagePaths";
import { useApp } from "@nexuscrm/host-sdk";

export const ObjectManager: React.FC = () => {
  const errorToast = useErrorToast();
  const navigate = useNavigate();
  const { currentFrontendAppId } = useApp();

  // Query Hooks
  const { data: schemas = [], isLoading, error, refetch } = useSchemas();
  // Descriptions come from the authoring API, not from the describe list that
  // backs useSchemas — that payload has no description field at all.
  const { descriptions, status: descriptionStatus } = useObjectDescriptions();
  const createSchemaMutation = useCreateSchema();
  const deleteSchemaMutation = useDeleteSchema();

  // Local UI State
  const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
  const [searchQuery, setSearchQuery] = useState("");
  const [typeFilter, setTypeFilter] = useState<"all" | "standard" | "custom">(
    "all",
  );

  // Delete Modal State
  const [schemaToDelete, setSchemaToDelete] = useState<SObjectDescribe | null>(
    null,
  );

  // Derived State
  const filteredSchemas = useMemo(() => {
    return schemas.filter((schema) => {
      if (schema.name.startsWith("_")) return false;
      const matchesSearch =
        (schema.label || "")
          .toLowerCase()
          .includes(searchQuery.toLowerCase()) ||
        (schema.name || "").toLowerCase().includes(searchQuery.toLowerCase());
      const matchesType =
        typeFilter === "all" ||
        (typeFilter === "standard" && !schema.custom) ||
        (typeFilter === "custom" && schema.custom);
      return matchesSearch && matchesType;
    });
  }, [schemas, searchQuery, typeFilter]);

  const stats = useMemo(() => {
    const total = schemas.filter((s) => !s.name.startsWith("_")).length;
    const standard = schemas.filter(
      (s) => !s.custom && !s.name.startsWith("_"),
    ).length;
    const custom = schemas.filter(
      (s) => s.custom && !s.name.startsWith("_"),
    ).length;
    return { total, standard, custom };
  }, [schemas]);

  // Handlers
  const handleCreate = async (formData: ObjectFormData) => {
    try {
      const { schema } = await createSchemaMutation.mutateAsync({
        name: formData.ApiName,
        label: formData.Label,
        labelPlural: formData.PluralLabel,
        description: formData.Description,
        searchable: formData.Searchable,
      });
      setIsCreateModalOpen(false);
      // Use the returned schema name which might have been normalized/suffixed by backend
      navigate(tryBuildSetupCapabilityChildPath(currentFrontendAppId, "objectManager", schema.name) ?? "/");
    } catch (err: unknown) {
      errorToast(formatApiError(err).message);
    }
  };

  const handleDelete = async () => {
    if (!schemaToDelete) return;
    try {
      await deleteSchemaMutation.mutateAsync(schemaToDelete.name);
      setSchemaToDelete(null);
    } catch (err: unknown) {
      Logger.error("[ObjectManager] Failed to delete object", {}, err);
      errorToast("Failed to delete object. Check console for details.");
    }
  };

  if (isLoading)
    return (
      <div className="flex h-screen items-center justify-center">
        <div className="flex flex-col items-center gap-2">
          <div className="w-8 h-8 border-4 border-blue-600 border-t-transparent rounded-full animate-spin" />
          <p className="text-slate-500 font-medium">
            Loading Object Manager...
          </p>
        </div>
      </div>
    );

  if (error)
    return (
      <EmptyState
        variant="error"
        title="Failed to load objects"
        description="Could not connect to the metadata service."
        action={{ label: "Retry", onClick: () => refetch() }}
      />
    );

  return (
    <div className="max-w-7xl mx-auto p-6 space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold text-slate-900 tracking-tight">
            Object Manager
          </h1>
          <p className="text-slate-500 mt-1">
            Manage standard and custom objects for your organization.
          </p>
        </div>
        <button
          onClick={() => setIsCreateModalOpen(true)}
          className="flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 font-medium shadow-sm transition-colors active:scale-95"
        >
          <Plus size={18} />
          Create Object
        </button>
      </div>

      {/* Stats */}
      <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
        <div className="bg-white p-4 rounded-xl border border-slate-200 shadow-sm flex items-center gap-4">
          <div className="p-3 bg-blue-50 text-blue-600 rounded-lg">
            <Box size={24} />
          </div>
          <div>
            <p className="text-sm font-medium text-slate-500">Total Objects</p>
            <p className="text-2xl font-bold text-slate-900">{stats.total}</p>
          </div>
        </div>
        <div className="bg-white p-4 rounded-xl border border-slate-200 shadow-sm flex items-center gap-4">
          <div className="p-3 bg-slate-100 text-slate-600 rounded-lg">
            <Database size={24} />
          </div>
          <div>
            <p className="text-sm font-medium text-slate-500">
              Standard Objects
            </p>
            <p className="text-2xl font-bold text-slate-900">
              {stats.standard}
            </p>
          </div>
        </div>
        <div className="bg-white p-4 rounded-xl border border-slate-200 shadow-sm flex items-center gap-4">
          <div className="p-3 bg-indigo-50 text-indigo-600 rounded-lg">
            <Box size={24} className="opacity-80" />
          </div>
          <div>
            <p className="text-sm font-medium text-slate-500">Custom Objects</p>
            <p className="text-2xl font-bold text-slate-900">{stats.custom}</p>
          </div>
        </div>
      </div>

      {/* Filter Bar */}
      <div className="flex gap-4">
        <div className="relative flex-1 max-w-md">
          <Search
            className="absolute left-3 top-1/2 -translate-y-1/2 text-slate-400"
            size={18}
          />
          <input
            type="text"
            placeholder="Search objects..."
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            className="w-full pl-10 pr-4 py-2.5 border border-slate-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 shadow-sm"
          />
        </div>
        <div className="relative w-48">
          <Filter
            className="absolute left-3 top-1/2 -translate-y-1/2 text-slate-400"
            size={18}
          />
          <select
            value={typeFilter}
            onChange={(e) =>
              setTypeFilter(e.target.value as "all" | "standard" | "custom")
            }
            className="w-full pl-10 pr-4 py-2.5 border border-slate-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 appearance-none bg-white shadow-sm cursor-pointer"
          >
            <option value="all">All Objects</option>
            <option value="standard">Standard Objects</option>
            <option value="custom">Custom Objects</option>
          </select>
        </div>
      </div>

      {/* List */}
      <ObjectList
        schemas={filteredSchemas}
        descriptions={descriptions}
        descriptionStatus={descriptionStatus}
        onDelete={setSchemaToDelete}
      />

      {/* Create Modal */}
      <CreateObjectModal
        isOpen={isCreateModalOpen}
        onClose={() => setIsCreateModalOpen(false)}
        onSubmit={handleCreate}
        loading={!!createSchemaMutation.isPending}
      />

      {/* Delete Modal */}
      <ConfirmationModal
        isOpen={!!schemaToDelete}
        onClose={() => setSchemaToDelete(null)}
        onConfirm={handleDelete}
        title="Delete Object"
        message={`Are you sure you want to delete the object "${schemaToDelete?.label}"? This action cannot be undone.`}
        confirmLabel="Delete"
        cancelLabel="Cancel"
        variant="danger"
        loading={!!deleteSchemaMutation.isPending}
      />
    </div>
  );
};
