"use client";

import { ColumnDef } from "ikoncomponents";
import { useEffect, useRef, useState, useMemo } from "react";
import {
  Button,
  ComboboxInput,
  ComboboxItemProps,
  DataTableLayout,
  Input,
} from "ikoncomponents";
import { Plus } from "lucide-react";

import { createProjectApi, getProjectsApi } from "@/app/utils/api/projectApi";
import ProjectCard from "./projectCard/projectCard";

import { Project } from "./types/project";
import { mapProjectToCard } from "./types/project-mapper";
import CreateProjectModal from "./projectModal/projectModal";
import { ProjectFormData } from "./projectModal/zodProject";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useAppCache } from "@/app/utils/context/AppCacheContext";
import {
  createUserMaps,
  findUsersInRole,
} from "@/app/utils/api/user-dashboard-platform/mappingFunction";
// import FileUploader from "./uploadFile";

export default function ProjectsPage() {
  const [projects, setProjects] = useState<Project[]>([]);
  const [statusesDropdown, setStatusesDropdown] = useState<ComboboxItemProps[]>(
    [],
  );

  const [managerDropdown, setManagerDropdown] = useState<ComboboxItemProps[]>(
    [],
  );
  const [open, setOpen] = useState(false);
  const [loading, setLoading] = useState(true);
  const [search, setSearch] = useState("");
  const [filterQuery, setFilterQuery] = useState<
    Partial<Record<keyof Project, string>>
  >({});

  // let statusesDropdown: ComboboxItemProps[] = [];

  const router = useRouter();

  // Project Manager options + the userId -> userName map come from the shared
  // app-wide cache. The map resolves a project's manager UUID to a display name.
  const { projectManagerOptions, userNameMap } = useAppCache();

  // DataTableLayout has no prop to set the initial view, so once the table is
  // rendered we click its built-in "Grid View" toggle once to default to cards.
  const tableContainerRef = useRef<HTMLDivElement>(null);
  const defaultedToGrid = useRef(false);

  const setDropdownFilters = async (statusDropdown: ComboboxItemProps[]) => {
    setStatusesDropdown(statusDropdown);
  };

  // =====================
  // DataTable Columns
  // =====================
  const columns: ColumnDef<Project>[] = [
    {
      accessorKey: "projectName",
      header: () => <div className="text-center">Project Name</div>,
      cell: (row) => {
        console.log("row", row.projectIdentifier);
        return (
          <Link
            className="hover:underline"
            href={`/main/planning/projects/${row.projectIdentifier}`}
          >
            {row.projectName}
          </Link>
        );
      },
    },
    {
      accessorKey: "projectIdentifier",
      header: () => <div className="text-center">Code</div>,
      // cell: ({ row }) => <span>{row.original.projectIdentifier}</span>,
    },
    {
      accessorKey: "contractedStartDate",
      header: () => <div className="text-center">Start Date</div>,
      // cell: ({ row }) => <span>{row.original.contractedStartDate}</span>,
    },
    {
      accessorKey: "contractedEndDate",
      header: () => <div className="text-center">End Date</div>,
      // cell: ({ row }) => <span>{row.original.contractedEndDate}</span>,
    },
    {
      accessorKey: "projectStatus",
      header: () => <div className="text-center">Status</div>,
      // cell: ({ row }) => <span>{row.original.projectStatus}</span>,
    },
  ];

  // =====================
  // Load projects
  // =====================
  useEffect(() => {
    const loadProjects = async () => {
      try {
        const data = await getProjectsApi();
        if (Array.isArray(data)) {
          setProjects(data);
        } else {
          console.error("Failed to fetch projects, received:", data);
          setProjects([]);
        }
      } finally {
        setLoading(false);
      }
    };

    const loadManagerData = async () => {
      const projectManagerMemberIds = await findUsersInRole("Project manager");
      const { nameMap } = await createUserMaps();

      const dropdown: ComboboxItemProps[] = [
        { label: "All Managers", value: "All Managers" },
      ];
      projectManagerMemberIds?.map((id) => {
        const userName = nameMap.get(`${id}`);
        dropdown.push({ label: userName, value: id });
      });

      setManagerDropdown(dropdown);
    };

    loadManagerData();
    loadProjects();
  }, []);

  // Switch the table into grid (card) view as soon as it mounts, once.
  useEffect(() => {
    if (loading || defaultedToGrid.current) return;
    const gridButton =
      tableContainerRef.current?.querySelector<HTMLButtonElement>(
        'button[title="Grid View"]',
      );
    if (gridButton) {
      gridButton.click();
      defaultedToGrid.current = true;
    }
  }, [loading]);

  // Build the manager filter dropdown from the cached Project Manager options.
  useEffect(() => {
    const dropdown: ComboboxItemProps[] = [
      { label: "All Managers", value: "All Managers" },
    ];
    projectManagerOptions.forEach((opt) => {
      dropdown.push({ label: opt.label, value: opt.value });
    });
    setManagerDropdown(dropdown);
  }, [projectManagerOptions]);

  useEffect(() => {
    const statuses: string[] = ["Active", "Ongoing", "Completed"];
    const statusDropdown: ComboboxItemProps[] = [
      { label: "All Statuses", value: "All Statuses" },
    ];
    // projects.map((project) => {
    //   if (!statuses.includes(project.projectStatus)) {
    //     statuses.push(project.projectStatus);
    //   }
    // });

    statuses.map((status) =>
      statusDropdown.push({ label: status, value: status }),
    );

    setDropdownFilters(statusDropdown);
  }, [projects]);

  // =====================
  // Create project
  // =====================
  const handleCreateProject = async (data: ProjectFormData) => {
    try {
      console.log("Project data------", data);
      const response = await createProjectApi(data);
      console.log("Project payload-----", response);
      setOpen(false);

      const refreshed = await getProjectsApi();
      if (Array.isArray(refreshed)) {
        setProjects(refreshed);
      }
    } catch (error) {
      console.error("Failed to create project", error);
    }
  };

  // =====================
  // Search filter
  // =====================
  const filteredProjects = useMemo(() => {
    if (!search.trim() && Object.keys(filterQuery).length === 0)
      return projects;

    return projects.filter((project: Project) => {
      const searchMatch = project.projectName
        ?.toLowerCase()
        .includes(search.toLowerCase());

      const filterMatch = Object.entries(filterQuery).every(([key, value]) => {
        // Check if the project matches the filter query
        return value ? project[key] === value : true;
      });

      return searchMatch && filterMatch;
    });
  }, [projects, search, filterQuery]);

  const onFilterChange = (key: string, value: string) => {
    setFilterQuery((prev) => {
      // "All …" entries are show-everything sentinels, not real filter values —
      // map them to "" so they don't get matched against real fields (e.g. a UUID
      // projectManager). Covers "All Statuses", "All Managers", etc.
      const isSentinel = value.startsWith("All ");
      return {
        ...prev,
        [key]: isSentinel || value === "All Managers" ? "" : value,
      };
    });
  };

  return (
    <div className="p-6 space-y-6">
      {/* ================= HEADER ================= */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-3xl font-semibold">Projects</h1>
          <p className="text-muted-foreground mt-1">
            {filteredProjects.length} of {projects.length} projects
          </p>
        </div>

        <Button onClick={() => setOpen(true)} className="flex gap-2">
          <Plus size={18} />
          New Project
        </Button>
      </div>

      {/* ================= CONTENT ================= */}
      {loading ? (
        <div className="text-sm text-muted-foreground">Loading projects...</div>
      ) : (
        <>
          {/* LIST VIEW */}

          <div ref={tableContainerRef}>
            <DataTableLayout
              data={filteredProjects}
              columns={columns}
              extraTools={{
                keyExtractor: (row: Project) => {
                  console.log("row", row);
                  return row.projectIdentifier;
                },
                onRowClick: (row) => {
                  router.push(
                    `/main/planning/projects/${row.projectIdentifier}`,
                  );
                },
                totalPages: 0,
                currentPage: 0,
                actionNode: (
                  <div className="flex flex-wrap items-center gap-3">
                    {/* Search */}
                    <div className="flex-1 min-w-[260px]">
                      <Input
                        placeholder="Search projects..."
                        value={search}
                        onChange={(e) => setSearch(e.target.value)}
                      />
                    </div>

                    {/* Status Filter */}
                    {/* <Button variant="outline" className="flex gap-2">
          All Statuses <ChevronDown size={16} />
        </Button> */}
                    <div className="grid grid-cols-2 gap-2">
                      <ComboboxInput
                        items={statusesDropdown}
                        placeholder="Select Status"
                        defaultValue="All Statuses"
                        onSelect={(value) => {
                          if (Array.isArray(value)) {
                            onFilterChange("projectStatus", value[0]);
                          } else {
                            onFilterChange("projectStatus", value);
                          }
                        }}
                      />
                      {/* Manager Filter */}
                      {/* <Button variant="outline" className="">
                  All Managers <ChevronDown size={16} />
                </Button> */}
                      <ComboboxInput
                        items={managerDropdown}
                        placeholder="Select Manager"
                        defaultValue="All Managers"
                        onSelect={(value) => {
                          if (Array.isArray(value)) {
                            onFilterChange("projectManager", value[0]);
                          } else {
                            onFilterChange("projectManager", value);
                          }
                        }}
                      />
                    </div>

                    {/* Source Filter */}
                    {/* <Button variant="outline" className="">
                  All Sources <ChevronDown size={16} />
                </Button> */}

                    {/* View Toggle */}
                    {/* <div className="flex border rounded-lg overflow-hidden">
                <button
                  onClick={() => setView("grid")}
                  className={`p-2 ${view === "grid" ? "bg-muted" : ""}`}
                >
                  <Grid size={18} />
                </button> 
                <button
                  onClick={() => setView("list")}
                  className={`p-2 ${view === "list" ? "bg-muted" : ""}`}
                >
                  <List size={18} />
                </button> 
              </div> */}
                  </div>
                ),

                gridComponent: (data: Project[]) => (
                  <div className="grid gap-3 grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
                    {data &&
                      data.length > 0 &&
                      data.map((project, index) => {
                        const cardProps = mapProjectToCard(project);
                        const resolved = userNameMap.get(
                          project.projectManager,
                        );
                        // TEMP diagnostic: shows whether the manager UUID resolves to a name.
                        console.log("[manager check]", {
                          project: project.projectName,
                          managerId: project.projectManager,
                          mapHasId: userNameMap.has(project.projectManager),
                          resolvedName: resolved,
                          mapSize: userNameMap.size,
                        });
                        const managerName =
                          resolved ?? cardProps.projectManager;

                        return (
                          <ProjectCard
                            key={index}
                            {...cardProps}
                            projectManager={managerName}
                          />
                        );
                      })}
                  </div>
                ),
              }}
            />
          </div>
        </>
      )}

      {/* ================= MODAL ================= */}
      <CreateProjectModal
        open={open}
        onClose={setOpen}
        onSubmit={handleCreateProject}
        projectManagerDropdownOptions={managerDropdown}
      />
    </div>
  );
}
