"use client";

import { useEffect, useState } from "react";
import { CheckSquare, ChevronDown, ChevronRight, Save, Square } from "lucide-react";
import { useToastMessage } from "@/src/hooks/admin/useToastMessage";
import { useStateContext } from "@/src/context/admin/StateContext";
import Button from "@/src/components/admin/ui/button/Button";
import instance from "@/src/utils/axios-instance";
import { AxiosResponse } from "axios";
import { ApiResponse } from "@/src/types/admin/types";

export const getModulesWithSections = (): Promise<AxiosResponse<ApiResponse<any>>> => 
  instance.get("/user-permissions/modules-sections");

export const getUserPermissions = (id: number): Promise<AxiosResponse<ApiResponse<any>>> => 
  instance.get(`/user-permissions/get/${id}`);

export const updateUserPermissions = (id: number, data: any): Promise<AxiosResponse<ApiResponse<any>>> => 
  instance.put(`/user-permissions/update/${id}`, data);

type Section = {
  id: number;
  name: string;
  slug: string;
  path: string;
};

type ModuleWithSections = {
  id: number;
  name: string;
  slug: string;
  icon?: string;
  sections: Section[];
};

type UserPermissionAssignmentProps = {
  userId: number;
  userName: string;
};

export default function UserPermissionAssignmentDrawer({ userId, userName }: UserPermissionAssignmentProps) {
  const { message, setMessage } = useToastMessage();
  const { setIsDrawerOpen, refresh, setRefresh } = useStateContext();

  const [modules, setModules] = useState<ModuleWithSections[]>([]);
  const [selectedPages, setSelectedPages] = useState<Set<string>>(new Set());
  const [expandedModules, setExpandedModules] = useState<Set<number>>(new Set());
  const [isLoading, setIsLoading] = useState(true);
  const [isSubmitting, setIsSubmitting] = useState(false);

  // Format: "m_{moduleId}" or "m_{moduleId}_s_{sectionId}"
  const pageKey = (moduleId: number, sectionId?: number) =>
    sectionId ? `m_${moduleId}_s_${sectionId}` : `m_${moduleId}`;

  useEffect(() => {
    const loadData = async () => {
      try {
        setIsLoading(true);

        const modulesRes = await getModulesWithSections();
        setModules(modulesRes.data.data.modules || []);

        const permRes = await getUserPermissions(userId);
        const currentPerms = permRes.data.data.userPermissions || [];

        const selectedSet = new Set<string>();
        currentPerms.forEach((p: any) => {
          const key = pageKey(p.module_id, p.section_id);
          selectedSet.add(key);
        });
        setSelectedPages(selectedSet);

        const expanded = new Set<number>();
        currentPerms.forEach((p: any) => {
          if (p.module_id) expanded.add(p.module_id);
        });
        setExpandedModules(expanded);
      } catch (err) {
        console.error("Failed to load permissions data:", err);
        setMessage({ type: "error", text: "Failed to load permission data" });
      } finally {
        setIsLoading(false);
      }
    };

    loadData();
  }, [userId, setMessage]);

  const togglePage = (moduleId: number, sectionId?: number) => {
    const key = pageKey(moduleId, sectionId);
    setSelectedPages((prev) => {
      const newSet = new Set(prev);
      if (newSet.has(key)) {
        newSet.delete(key);
      } else {
        newSet.add(key);
      }
      return newSet;
    });
  };

  const isSelected = (moduleId: number, sectionId?: number) => {
    return selectedPages.has(pageKey(moduleId, sectionId));
  };

  const selectAll = (moduleId?: number) => {
    setSelectedPages((prev) => {
      const newSet = new Set(prev);

      if (moduleId) {
        // Select module and all its sections
        newSet.add(pageKey(moduleId));
        modules
          .find((m) => m.id === moduleId)
          ?.sections.forEach((section) => {
            newSet.add(pageKey(moduleId, section.id));
          });
      } else {
        // Global select all
        modules.forEach((module) => {
          newSet.add(pageKey(module.id));
          module.sections.forEach((section) => {
            newSet.add(pageKey(module.id, section.id));
          });
        });
      }

      return newSet;
    });
  };

  const deselectAll = (moduleId?: number) => {
    setSelectedPages((prev) => {
      const newSet = new Set(prev);

      if (moduleId) {
        newSet.delete(pageKey(moduleId));
        modules
          .find((m) => m.id === moduleId)
          ?.sections.forEach((section) => {
            newSet.delete(pageKey(moduleId, section.id));
          });
      } else {
        newSet.clear();
      }

      return newSet;
    });
  };

  const toggleModuleExpand = (moduleId: number) => {
    setExpandedModules((prev) => {
      const newSet = new Set(prev);
      if (newSet.has(moduleId)) {
        newSet.delete(moduleId);
      } else {
        newSet.add(moduleId);
      }
      return newSet;
    });
  };

  const handleSubmit = async () => {
    setIsSubmitting(true);
    setMessage(null);

    try {
      const permissions = Array.from(selectedPages)
        .map((key) => {
          const [, mPart, , sPart] = key.split("_");
          return {
            module_id: Number(mPart),
            section_id: sPart ? Number(sPart) : null,
          };
        })
        .filter((p) => p.module_id);

      const payload = { permissions };

      const response = await updateUserPermissions(userId, payload);

      if (!response.data?.success) {
        throw new Error(response.data?.message || "Failed to save permissions");
      }

      setMessage({
        type: "success",
        text: "User permissions updated successfully!",
      });

      setRefresh(!refresh);
      setIsDrawerOpen(false);
    } catch (err: any) {
      setMessage({ type: "error", text: err.message || "Failed to save permissions" });
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <div className="flex flex-col h-full">
      {/* Header */}
      <div className="px-0 py-3 -my-6 mb-6">
        
        <p className="text-sm text-gray-600 mb-4">
          Select the modules and pages this user can access
        </p>
        
        {/* Global Controls */}
        <div className="flex justify-end gap-4 text-sm">
          <button
            onClick={() => selectAll()}
            className="flex items-center gap-1.5 text-blue-600 hover:text-blue-800"
          >
            <CheckSquare size={16} /> Select All
          </button>
          <button
            onClick={() => deselectAll()}
            className="flex items-center gap-1.5 text-red-600 hover:text-red-800"
          >
            <Square size={16} /> Deselect All
          </button>
        </div>
      </div>

      {/* Content */}
      <div className="flex-1 overflow-y-auto">
        {isLoading ? (
          <div className="flex justify-center items-center h-64">
            <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div>
          </div>
        ) : (
          <div className="space-y-4">
            {modules.map((module) => (
              <div
                key={module.id}
                className="border rounded-lg overflow-hidden bg-white dark:bg-gray-800"
              >
                {/* Module Header */}
                <div className="flex items-center justify-between px-5 py-4 bg-gray-50 dark:bg-gray-900">
                  <button
                    onClick={() => toggleModuleExpand(module.id)}
                    className="flex items-center gap-3 flex-1"
                  >
                    <h3 className="font-medium text-sm">{module.name}</h3>
                  </button>

                  <div className="flex items-center gap-4 text-sm">
                    <label className="flex items-center gap-2 cursor-pointer">
                      <input
                        type="checkbox"
                        checked={isSelected(module.id)}
                        onChange={() => togglePage(module.id)}
                        className="w-4 h-4 text-blue-600 rounded focus:ring-blue-500"
                      />
                      <span>Module Access</span>
                    </label>
                    <button
                      onClick={() => selectAll(module.id)}
                      className="text-blue-600 hover:text-blue-800"
                    >
                      Select All
                    </button>
                    <button
                      onClick={() => deselectAll(module.id)}
                      className="text-red-600 hover:text-red-800"
                    >
                      Clear
                    </button>
                    {expandedModules.has(module.id) ? (
                      <ChevronDown size={18} />
                    ) : (
                      <ChevronRight size={18} />
                    )}
                  </div>
                </div>

                {/* Sections */}
                {expandedModules.has(module.id) && module.sections.length > 0 && (
                  <div className="p-5">
                    <p className="text-sm font-medium text-gray-600 mb-3">Pages</p>
                    <div className="grid grid-cols-1 sm:grid-cols-1 md:grid-cols-1 gap-3">
                      {module.sections.map((section) => (
                        <label
                          key={section.id}
                          className="flex items-center text-sm gap-2 cursor-pointer p-3 hover:bg-gray-50 dark:hover:bg-gray-700 rounded border"
                        >
                          <input
                            type="checkbox"
                            checked={isSelected(module.id, section.id)}
                            onChange={() => togglePage(module.id, section.id)}
                            className="w-4 h-4 shrink-0 text-blue-600 rounded focus:ring-blue-500"
                          />
                          <span className="text-gray-700">{section.name}</span>
                        </label>
                      ))}
                    </div>
                  </div>
                )}
              </div>
            ))}
          </div>
        )}
      </div>

      {/* Footer */}
      <div className="fixed bottom-0 right-0 w-full border-t p-4 bg-gray-50 dark:bg-gray-800 flex justify-start gap-4">
        <Button onClick={handleSubmit} disabled={isSubmitting || isLoading}>
          <Save size={18} />
          {isSubmitting ? "Saving..." : "Save Privileges"}
        </Button>
      </div>
    </div>
  );
}