"use client";
import React, { useEffect, useState, useMemo, useCallback } from "react";
import dynamic from "next/dynamic";
import styles from "../../modules/commonstyle/dattabale.module.css";
import { Pagination } from "./Pagination";
import { EnterpriseLoader } from "./../../../../components/loader/loader";
import { getStandards, deleteStandard } from "@/lib/api/standard.api";
import { fetchApi } from "@/lib/api/http";
import { deleteWithConfirm } from "./../../../../components/ConfirmDialog/ConfirmDialog";
import StandardForm from "./Form/StandardForm";
import { mapStandardsApiResponse, mapColumnKeyToValue } from "@/lib/api/mappers/standard.mappers";
import type { StandardRow } from "@/lib/api/types/standard.types";
import { StandardFilters } from "./Filters/StandardFilters";


const StandardRowFallback = dynamic(() => import("./StandardRow").then((m) => m.StandardRow), { ssr: false });

interface ColumnConfig { key: string; type: string; label: string; order: number; sortable: boolean; default_visible: boolean; }
interface ButtonConfig  { key: string; icon: string; color: string; label: string; order: number; position: "row" | "toolbar"; }
interface ModuleConfig  { id: number; name: string; slug: string; button_config: ButtonConfig[]; column_config: ColumnConfig[]; }

const FALLBACK_COLUMNS: ColumnConfig[] = [
  { key: "name",       type: "text",    label: "Standard Name", order: 1,  sortable: true,  default_visible: true },
  { key: "title",      type: "text",    label: "Title",         order: 2,  sortable: true,  default_visible: true },
  { key: "created_at", type: "date",    label: "Created",       order: 3,  sortable: true,  default_visible: true },
  { key: "actions",    type: "actions", label: "Actions",       order: 99, sortable: false, default_visible: true },
];

const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL || "http://localhost:3007/api";

export default function StandardTable({ refreshFlag }: { refreshFlag?: boolean }) {
  const [data, setData]           = useState<StandardRow[]>([]);
  const [loading, setLoading]     = useState(true);
  const [error, setError]         = useState<string | null>(null);
  const [selectedRows, setSelectedRows] = useState<number[]>([]);
  const [expandedRows, setExpandedRows] = useState<number[]>([]);
  const [searchTerm, setSearchTerm]     = useState("");
  const [currentPage, setCurrentPage]   = useState(1);
  const [itemsPerPage, setItemsPerPage] = useState(10);
  const [isEditModalOpen, setIsEditModalOpen] = useState(false);
  const [editingId, setEditingId]             = useState<number | null>(null);
  const [startDate, setStartDate]             = useState("");
  const [endDate, setEndDate]                 = useState("");

  const [moduleConfig, setModuleConfig]     = useState<ModuleConfig | null>(null);
  const [userPermissions, setUserPermissions] = useState<any[]>([]);
  const [permissionsLoading, setPermissionsLoading] = useState(true);
  const [permissionSystemReady, setPermissionSystemReady] = useState(false);
  const [rawUserId, setRawUserId] = useState<any>(null);

  const fetchModuleConfig = useCallback(async () => {
    try {
      const res = await fetchApi<any>(`${API_BASE_URL}/modules`);
      const list = Array.isArray(res) ? res : res?.data ? (Array.isArray(res.data) ? res.data : [res.data]) : [res];
      const mod = list.find((m: any) => m.slug === "standards" || m.name === "standards");
      if (mod) { setModuleConfig(mod); return true; }
      return false;
    } catch { return false; }
  }, []);

  const fetchUserPermissions = useCallback(async () => {
    try {
      let userId: any = null;
      if (typeof window !== "undefined") {
        try { const s = localStorage.getItem("user"); if (s) { const p = JSON.parse(s); userId = p?.id || p?.userId || p?.user_id; } } catch {}
        if (!userId) { try { const t = localStorage.getItem("token") || localStorage.getItem("accessToken"); if (t) { const p = JSON.parse(atob(t.split(".")[1])); userId = p?.id || p?.userId || p?.sub; } } catch {} }
      }
      setRawUserId({ userId });
      if (!userId) { setUserPermissions([]); return false; }
      const res = await fetchApi<any>(`${API_BASE_URL}/user-permissions/user/${userId}`);
      const list = Array.isArray(res) ? res : res?.data ? (Array.isArray(res.data) ? res.data : [res.data]) : res?.permissions ?? [];
      setUserPermissions(list); return true;
    } catch { setUserPermissions([]); return false; }
  }, []);

  const permittedActions = useMemo((): Set<string> => {
    if (!moduleConfig) return new Set(["view","edit","delete","create","export","print","view_all"]);
    const a = new Set<string>();
    for (const up of userPermissions) {
      if (!up.permission?.action) continue;
      const mid = up.permission.module?.id ?? up.permission.module_id;
      if (mid === moduleConfig.id) a.add(up.permission.action);
    }
    return a;
  }, [moduleConfig, userPermissions]);

  const refreshData = useCallback(() => {
    setLoading(true);
    getStandards()
      .then((s) => setData(mapStandardsApiResponse(s)))
      .catch((err) => setError(err.message))
      .finally(() => setLoading(false));
  }, []);

  useEffect(() => {
    const init = async () => {
      setPermissionsLoading(true);
      const [m, p] = await Promise.all([fetchModuleConfig(), fetchUserPermissions()]);
      setPermissionSystemReady(m && p);
      setPermissionsLoading(false);
    };
    init(); refreshData();
  }, [refreshFlag, fetchModuleConfig, fetchUserPermissions, refreshData]);

  useEffect(() => setCurrentPage(1), [searchTerm]);

  const filteredData = useMemo(() => data.filter((row) => {
    const q = searchTerm.toLowerCase();
    if (q && !(row.name.toLowerCase().includes(q) || row.title?.toLowerCase().includes(q))) return false;
    if (startDate || endDate) {
      const d = row.created_at ? new Date(row.created_at) : null;
      if (d) {
        if (startDate && d < new Date(startDate)) return false;
        if (endDate   && d > new Date(endDate + "T23:59:59")) return false;
      }
    }
    return true;
  }), [data, searchTerm, startDate, endDate]);

  const paginatedData = useMemo(() => filteredData.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage), [filteredData, currentPage, itemsPerPage]);

  const handleDelete = async (row: StandardRow) => {
    const { confirmed, error: e } = await deleteWithConfirm(row.name, () => deleteStandard(row.id), { successMessage: "Standard deleted.", errorMessage: "Failed to delete." });
    if (confirmed && !e) { setSelectedRows((p) => p.filter((s) => s !== row.sno)); refreshData(); }
  };
  const handleEdit = (row: StandardRow) => { setEditingId(row.id); setIsEditModalOpen(true); };
  const handleView = (row: StandardRow) => setExpandedRows((p) => p.includes(row.sno) ? p : [...p, row.sno]);

  if (error) return <div className={styles.errorContainer}><p className={styles.errorMessage}>{error}</p><button className={styles.errorButton} onClick={refreshData}>Retry</button></div>;
  if (loading || permissionsLoading) return <EnterpriseLoader />;

  return (
    <div className={styles.container}>
      {/* Filters */}
      <StandardFilters
        searchTerm={searchTerm}
        setSearchTerm={setSearchTerm}
        startDate={startDate}
        setStartDate={setStartDate}
        endDate={endDate}
        setEndDate={setEndDate}
        clearFilters={() => { setSearchTerm(""); setStartDate(""); setEndDate(""); }}
        onRefresh={refreshData}
      />

      {filteredData.length !== data.length && (
        <div style={{ padding: "10px 16px", backgroundColor: "#f0fdfa", border: "1px solid #99f6e4", borderRadius: 8, marginBottom: 12, fontSize: 13, color: "#0f766e" }}>
          Showing {filteredData.length} of {data.length} standards
        </div>
      )}

      <div className={styles.tableWrapper}>
        <table className={styles.table}>
          <thead>
            <tr>
              <th className={styles.expandCol}></th>
              <th className={styles.checkboxCol}>
                <input type="checkbox" className={styles.checkbox}
                  checked={filteredData.length > 0 && filteredData.every((r) => selectedRows.includes(r.sno))}
                  onChange={(e) => setSelectedRows(e.target.checked ? filteredData.map((r) => r.sno) : [])} />
              </th>
              <th className={styles.th}>Standard Name</th>
              <th className={styles.th}>Title</th>
              <th className={styles.th}>Created</th>
              <th className={styles.actionsCol}>Actions</th>
            </tr>
          </thead>
          <tbody>
            {paginatedData.length > 0 ? paginatedData.map((row) => (
              <StandardRowFallback key={row.sno} row={row}
                isExpanded={expandedRows.includes(row.sno)}
                toggleRowExpand={(id) => setExpandedRows((p) => p.includes(id) ? p.filter((r) => r !== id) : [...p, id])}
                isSelected={selectedRows.includes(row.sno)}
                handleRowSelect={(id, checked) => setSelectedRows((p) => checked ? [...p, id] : p.filter((r) => r !== id))}
                onEdit={handleEdit} onDelete={handleDelete} onView={handleView} />
            )) : (
              <tr><td colSpan={6} style={{ textAlign: "center", padding: "60px" }}>
                <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }}>
                  <div style={{ fontSize: 36 }}>📋</div>
                  <h3 style={{ margin: 0, color: "#111827" }}>No Standards Found</h3>
                  <p style={{ color: "#6b7280", margin: 0 }}>{searchTerm ? "No standards match your search." : "Get started by adding a new standard."}</p>
                </div>
              </td></tr>
            )}
          </tbody>
        </table>
      </div>

      <Pagination currentPage={currentPage} setCurrentPage={setCurrentPage}
        totalPages={Math.ceil(filteredData.length / itemsPerPage)}
        startIndex={(currentPage - 1) * itemsPerPage + 1}
        endIndex={Math.min(currentPage * itemsPerPage, filteredData.length)}
        sortedDataLength={filteredData.length} itemsPerPage={itemsPerPage}
        setItemsPerPage={(v) => { setCurrentPage(1); setItemsPerPage(v); }} />

      <StandardForm isOpen={isEditModalOpen} onClose={() => { setIsEditModalOpen(false); setEditingId(null); }} refreshData={refreshData} editId={editingId} />
    </div>
  );
}
