'use client';

import React, { useEffect, useState, useMemo, useCallback } from 'react';
import { useRouter } from 'next/navigation';
import toast from 'react-hot-toast';
import styles from '../commonstyle/dattabale.module.css';
import { EnterpriseLoader } from '../../../../components/loader/loader';
import { Pagination } from '../companies/Pagination';
import { fetchApi } from '@/lib/api/http';

import LeadsHeader from './LeadsHeader';
import LeadsFilters from './LeadsFilters';
import LeadsAnalyticsInline from './LeadsAnalyticsInline';
import LeadRow from './LeadRow';

import {
  getLeads,
  getLeadAnalytics,
  deleteLead,
  bulkUpdateLeads,
  bulkDeleteLeads,
  getAssignableUsers,
} from '@/lib/api/leads.api';
import { CLIENT_GROUP_OPTIONS, formatUserName } from '@/lib/api/mappers/leads.mappers';
import {
  useLeadRealtime,
  useCurrentUserId,
} from '@/lib/api/hooks/useLeadRealtime';
import type {
  Lead,
  LeadAnalytics,
  LeadListMeta,
  LeadPriority,
  LeadStatus,
  SelectableClientGroup,
} from '@/lib/api/types/leads.types';

const API_BASE_URL =
  process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3007/api';

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: any[];
}

/** Actions assumed available when the permission system can't be reached. */
const FALLBACK_ACTIONS = ['view', 'create', 'update', 'assign'];

function useDebounce<T>(value: T, delay: number): T {
  const [d, setD] = useState(value);
  useEffect(() => {
    const t = setTimeout(() => setD(value), delay);
    return () => clearTimeout(t);
  }, [value, delay]);
  return d;
}

export default function LeadsPage() {
  const router = useRouter();
  const currentUserId = useCurrentUserId();

  // ── Data ──────────────────────────────────────────────────────────────
  const [data, setData] = useState<Lead[]>([]);
  const [meta, setMeta] = useState<LeadListMeta | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const [analytics, setAnalytics] = useState<LeadAnalytics | null>(null);
  const [analyticsLoading, setAnalyticsLoading] = useState(false);
  const [showAnalytics, setShowAnalytics] = useState(false);

  const [users, setUsers] = useState<{ id: number; label: string }[]>([]);

  // ── Paging + filters ──────────────────────────────────────────────────
  const [currentPage, setCurrentPage] = useState(1);
  const [itemsPerPage, setItemsPerPage] = useState(10);

  const [searchTerm, setSearchTerm] = useState('');
  const [statusFilter, setStatusFilter] = useState<LeadStatus | 'all'>('all');
  const [clientGroupFilter, setClientGroupFilter] = useState<
    SelectableClientGroup | 'all'
  >('all');
  const [priorityFilter, setPriorityFilter] = useState<LeadPriority | 'all'>('all');
  const [assigneeFilter, setAssigneeFilter] = useState<number | 'all'>('all');
  const [dateFrom, setDateFrom] = useState('');
  const [dateTo, setDateTo] = useState('');
  const debouncedSearch = useDebounce(searchTerm, 400);

  // ── Selection + modals ────────────────────────────────────────────────
  const [selectedIds, setSelectedIds] = useState<Set<number>>(new Set());
  const [highlightedIds, setHighlightedIds] = useState<Set<number>>(new Set());

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

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

  const fetchUserPermissions = useCallback(async (): Promise<boolean> => {
    try {
      let userId: any = currentUserId;
      if (!userId && typeof window !== 'undefined') {
        const s = localStorage.getItem('user');
        if (s) {
          const p = JSON.parse(s);
          userId = p?.id || p?.userId || p?.user_id;
        }
      }
      if (!userId) return false;

      const res = await fetchApi<any>(
        `${API_BASE_URL}/users/${userId}/permissions`,
      );
      const perms = Array.isArray(res) ? res : (res?.data ?? []);
      setUserPermissions(perms);
      return true;
    } catch {
      return false;
    }
  }, [currentUserId]);

  const permittedActions = useMemo(() => {
    const set = new Set<string>();
    if (!permissionSystemReady || !moduleConfig) {
      FALLBACK_ACTIONS.forEach((a) => set.add(a));
      return set;
    }
    for (const p of userPermissions) {
      const slug = p?.module?.slug ?? p?.module_slug;
      if (slug === 'leads' && p?.action) set.add(p.action);
    }
    return set;
  }, [permissionSystemReady, moduleConfig, userPermissions]);

  // ── Fetching ──────────────────────────────────────────────────────────
  const fetchPage = useCallback(
    (page: number, limit: number) => {
      setLoading(true);
      getLeads({
        page,
        limit,
        ...(debouncedSearch && { search: debouncedSearch }),
        ...(statusFilter !== 'all' && { status: statusFilter }),
        ...(clientGroupFilter !== 'all' && { client_group: clientGroupFilter }),
        ...(assigneeFilter !== 'all' && { assigned_to: assigneeFilter }),
        ...(dateFrom && { date_from: dateFrom }),
        ...(dateTo && { date_to: dateTo }),
      })
        .then((res) => {
          setData(res.data);
          setMeta(res.meta);
          setError(null);
        })
        .catch((err) => setError(err.message))
        .finally(() => setLoading(false));
    },
    [
      debouncedSearch,
      statusFilter,
      clientGroupFilter,
      assigneeFilter,
      dateFrom,
      dateTo,
    ],
  );

  const fetchAnalytics = useCallback(() => {
    setAnalyticsLoading(true);
    getLeadAnalytics()
      .then(setAnalytics)
      .catch(() => setAnalytics(null))
      .finally(() => setAnalyticsLoading(false));
  }, []);

  const refresh = useCallback(() => {
    fetchPage(currentPage, itemsPerPage);
    if (showAnalytics) fetchAnalytics();
  }, [fetchPage, currentPage, itemsPerPage, showAnalytics, fetchAnalytics]);

  // ── Live notifications ────────────────────────────────────────────────
  // A handover that lands while the page is open refreshes the list and
  // flashes the affected row, so the user sees the lead appear rather than
  // just a toast about a lead they then have to hunt for.
  const handleLeadEvent = useCallback(
    (n: any) => {
      const leadId = n?.metadata?.lead_id;

      if (n.type === 'LEAD_ASSIGNED') {
        toast.success(n.title, { icon: '📥', duration: 6000 });
      } else if (n.type === 'LEAD_UNASSIGNED') {
        toast(n.title, { icon: '📤' });
      } else if (n.type === 'LEAD_BULK_ASSIGNED') {
        toast.success(n.title, { icon: '📥', duration: 6000 });
      } else if (n.type === 'LEAD_HANDOVER_REQUESTED') {
        toast(n.title, { icon: '🙋' });
      }

      if (leadId) {
        setHighlightedIds((prev) => new Set(prev).add(Number(leadId)));
        setTimeout(() => {
          setHighlightedIds((prev) => {
            const next = new Set(prev);
            next.delete(Number(leadId));
            return next;
          });
        }, 6000);
      }

      refresh();
    },
    [refresh],
  );

  const realtime = useLeadRealtime({
    userId: currentUserId,
    onLeadEvent: handleLeadEvent,
  });

  // ── Init ──────────────────────────────────────────────────────────────
  useEffect(() => {
    const init = async () => {
      setPermissionsLoading(true);
      const [moduleOk, permsOk] = await Promise.all([
        fetchModuleConfig(),
        fetchUserPermissions(),
      ]);
      setPermissionSystemReady(moduleOk && permsOk);
      setPermissionsLoading(false);
    };
    init();

    getAssignableUsers()
      .then((res: any) => {
        const list = Array.isArray(res) ? res : (res?.data ?? []);
        setUsers(
          list.map((u: any) => ({ id: u.id, label: formatUserName(u) })),
        );
      })
      .catch(() => setUsers([]));
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    fetchPage(currentPage, itemsPerPage);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [currentPage, itemsPerPage]);

  useEffect(() => {
    setCurrentPage(1);
    fetchPage(1, itemsPerPage);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [
    debouncedSearch,
    statusFilter,
    clientGroupFilter,
    assigneeFilter,
    dateFrom,
    dateTo,
  ]);

  // Priority isn't a server-side filter, so it narrows the page in memory.
  const visibleData = useMemo(
    () =>
      priorityFilter === 'all'
        ? data
        : data.filter((l) => l.priority === priorityFilter),
    [data, priorityFilter],
  );

  // ── Handlers ──────────────────────────────────────────────────────────
  const handleAnalyticsToggle = () => {
    setShowAnalytics((v) => {
      if (!v && !analytics) fetchAnalytics();
      return !v;
    });
  };

  const clearAllFilters = () => {
    setSearchTerm('');
    setStatusFilter('all');
    setClientGroupFilter('all');
    setPriorityFilter('all');
    setAssigneeFilter('all');
    setDateFrom('');
    setDateTo('');
  };

  const handleOpen = (row: Lead) => {
    if (!permittedActions.has('view')) {
      toast.error("You don't have permission to open leads");
      return;
    }
    router.push(`/modules/leads/${row.id}`);
  };

  const handleEdit = (row: Lead) => {
    router.push(`/modules/leads/${row.id}/edit`);
  };

  const handleNew = () => {
    router.push('/modules/leads/new');
  };

  // Handover lives in the form's Ownership card, so "assign" from a row
  // opens the same page and jumps to it. One place changes ownership, one
  // place fires the notification.
  const handleAssign = (row: Lead) => {
    router.push(`/modules/leads/${row.id}/edit#ownership`);
  };

  const handleDelete = async (row: Lead) => {
    if (!window.confirm(`Delete ${row.lead_code} — ${row.company}?`)) return;
    try {
      await deleteLead(row.id);
      toast.success(`${row.lead_code} deleted`);
      refresh();
    } catch (err: any) {
      toast.error(err?.message || 'Could not delete the lead');
    }
  };

  const toggleSelect = (row: Lead) => {
    setSelectedIds((prev) => {
      const next = new Set(prev);
      next.has(row.id) ? next.delete(row.id) : next.add(row.id);
      return next;
    });
  };

  const toggleSelectAll = () => {
    setSelectedIds((prev) =>
      prev.size === visibleData.length
        ? new Set()
        : new Set(visibleData.map((l) => l.id)),
    );
  };

  const bulkSetClientGroup = async (group: SelectableClientGroup) => {
    try {
      const res = await bulkUpdateLeads({
        ids: [...selectedIds],
        action: 'client_group',
        client_group: group,
      });
      toast.success(`${res.count} lead${res.count === 1 ? '' : 's'} set to ${group}`);
      setSelectedIds(new Set());
      refresh();
    } catch (err: any) {
      toast.error(err?.message || 'Bulk update failed');
    }
  };

  const bulkDelete = async () => {
    if (!window.confirm(`Delete ${selectedIds.size} leads?`)) return;
    try {
      const res = await bulkDeleteLeads([...selectedIds]);
      toast.success(`${res.count} deleted`);
      setSelectedIds(new Set());
      refresh();
    } catch (err: any) {
      toast.error(err?.message || 'Bulk delete failed');
    }
  };

  // ── Render ────────────────────────────────────────────────────────────
  if (error)
    return (
      <div className={styles.errorContainer}>
        <div className={styles.errorIcon}>⚠️</div>
        <h3 className={styles.errorTitle}>Leads didn't load</h3>
        <p className={styles.errorMessage}>{error}</p>
        <button className={styles.errorButton} onClick={refresh}>
          Try again
        </button>
      </div>
    );

  if (permissionsLoading) return <EnterpriseLoader />;

  const thStyle: React.CSSProperties = {
    padding: '10px',
    textAlign: 'left',
    fontSize: 10,
    fontWeight: 700,
    color: '#6b7280',
    textTransform: 'uppercase',
    letterSpacing: '0.05em',
  };

  const canBulk = permittedActions.has('update') || permittedActions.has('delete');
  const colCount = canBulk ? 10 : 9;

  return (
    <div className={styles.container}>
      <LeadsHeader
        totalLeads={meta?.total}
        onRefresh={refresh}
        onNewLead={handleNew}
        canCreate={permittedActions.has('create')}
        realtime={realtime}
      />

      <LeadsFilters
        searchTerm={searchTerm}
        setSearchTerm={setSearchTerm}
        statusFilter={statusFilter}
        setStatusFilter={setStatusFilter}
        clientGroupFilter={clientGroupFilter}
        setClientGroupFilter={setClientGroupFilter}
        priorityFilter={priorityFilter}
        setPriorityFilter={setPriorityFilter}
        assigneeFilter={assigneeFilter}
        setAssigneeFilter={setAssigneeFilter}
        assignableUsers={users}
        dateFrom={dateFrom}
        setDateFrom={setDateFrom}
        dateTo={dateTo}
        setDateTo={setDateTo}
        clearFilters={clearAllFilters}
        onRefresh={refresh}
        onAnalyticsToggle={handleAnalyticsToggle}
        showAnalytics={showAnalytics}
      />

      {showAnalytics && (
        <LeadsAnalyticsInline analytics={analytics} loading={analyticsLoading} />
      )}

      {/* Bulk action bar — only while something is selected */}
      {selectedIds.size > 0 && canBulk && (
        <div
          style={{
            display: 'flex',
            alignItems: 'center',
            gap: 10,
            flexWrap: 'wrap',
            padding: '10px 14px',
            marginBottom: 12,
            background: '#eef2ff',
            border: '1px solid #c7d2fe',
            borderRadius: 10,
          }}
        >
          <strong style={{ fontSize: 13, color: '#4338ca' }}>
            {selectedIds.size} selected
          </strong>

          {permittedActions.has('update') && (
            <>
              <span style={{ fontSize: 12, color: '#64748b' }}>
                Set client group:
              </span>
              {CLIENT_GROUP_OPTIONS.map((g) => (
                <button
                  key={g.value}
                  onClick={() => bulkSetClientGroup(g.value)}
                  style={{
                    padding: '5px 12px',
                    borderRadius: 7,
                    border: '1px solid #c7d2fe',
                    background: '#fff',
                    color: '#4338ca',
                    fontSize: 12,
                    fontWeight: 700,
                    cursor: 'pointer',
                  }}
                >
                  {g.label}
                </button>
              ))}
            </>
          )}

          {permittedActions.has('delete') && (
            <button
              onClick={bulkDelete}
              style={{
                marginLeft: 'auto',
                padding: '5px 12px',
                borderRadius: 7,
                border: '1px solid #fca5a5',
                background: '#fef2f2',
                color: '#dc2626',
                fontSize: 12,
                fontWeight: 700,
                cursor: 'pointer',
              }}
            >
              Delete selected
            </button>
          )}

          <button
            onClick={() => setSelectedIds(new Set())}
            style={{
              padding: '5px 12px',
              borderRadius: 7,
              border: '1px solid #cbd5e1',
              background: '#fff',
              color: '#475569',
              fontSize: 12,
              fontWeight: 600,
              cursor: 'pointer',
            }}
          >
            Clear
          </button>
        </div>
      )}

      {meta && (
        <div
          style={{
            padding: '10px 16px',
            backgroundColor: '#f0fdfa',
            border: '1px solid #99f6e4',
            borderRadius: 8,
            marginBottom: 12,
            fontSize: 13,
            color: '#0f766e',
          }}
        >
          📋 Showing{' '}
          <strong>
            {(currentPage - 1) * itemsPerPage + 1}–
            {Math.min(currentPage * itemsPerPage, meta.total)}
          </strong>{' '}
          of <strong>{meta.total.toLocaleString()}</strong> leads
        </div>
      )}

      <div className={styles.tableWrapper}>
        <table
          className={styles.table}
          style={{ tableLayout: 'fixed', width: '100%' }}
        >
          <colgroup>
            {canBulk && <col style={{ width: 40 }} />}
            <col style={{ width: 150 }} />
            <col style={{ width: 200 }} />
            <col style={{ width: 110 }} />
            <col style={{ width: 190 }} />
            <col style={{ width: 160 }} />
            <col style={{ width: 100 }} />
            <col style={{ width: 120 }} />
            <col style={{ width: 110 }} />
            <col style={{ width: 130 }} />
          </colgroup>
          <thead>
            <tr style={{ background: '#f8fafc' }}>
              {canBulk && (
                <th style={thStyle}>
                  <input
                    type="checkbox"
                    aria-label="Select all rows"
                    checked={
                      visibleData.length > 0 &&
                      selectedIds.size === visibleData.length
                    }
                    onChange={toggleSelectAll}
                    style={{ cursor: 'pointer' }}
                  />
                </th>
              )}
              <th style={thStyle}>Lead Code</th>
              <th style={thStyle}>Company</th>
              <th style={thStyle}>Client Group</th>
              <th style={thStyle}>Contact Details</th>
              <th style={thStyle}>Owner</th>
              <th style={thStyle}>Priority</th>
              <th style={thStyle}>Status</th>
              <th style={thStyle}>Created</th>
              <th style={thStyle}>Actions</th>
            </tr>
          </thead>
          <tbody>
            {loading ? (
              <tr>
                <td colSpan={colCount} style={{ textAlign: 'center', padding: 60 }}>
                  <EnterpriseLoader />
                </td>
              </tr>
            ) : visibleData.length === 0 ? (
              <tr>
                <td colSpan={colCount} style={{ textAlign: 'center', padding: 60 }}>
                  <div style={{ fontSize: 36 }}>🎯</div>
                  <h3 style={{ margin: '12px 0 4px', color: '#111827' }}>
                    No leads here
                  </h3>
                  <p style={{ color: '#6b7280', margin: 0 }}>
                    {searchTerm ||
                    statusFilter !== 'all' ||
                    clientGroupFilter !== 'all' ||
                    priorityFilter !== 'all' ||
                    assigneeFilter !== 'all' ||
                    dateFrom ||
                    dateTo
                      ? 'Nothing matches these filters. Clear one and try again.'
                      : 'Add your first lead to start building the pipeline.'}
                  </p>
                </td>
              </tr>
            ) : (
              visibleData.map((row) => (
                <LeadRow
                  key={row.id}
                  row={row}
                  onOpen={handleOpen}
                  onEdit={handleEdit}
                  onAssign={handleAssign}
                  onDelete={handleDelete}
                  isSelected={selectedIds.has(row.id)}
                  onToggleSelect={canBulk ? toggleSelect : undefined}
                  permittedActions={permittedActions}
                  isHighlighted={highlightedIds.has(row.id)}
                />
              ))
            )}
          </tbody>
        </table>
      </div>

      {meta && (
        <Pagination
          currentPage={currentPage}
          setCurrentPage={setCurrentPage}
          totalPages={meta.totalPages}
          startIndex={(currentPage - 1) * itemsPerPage + 1}
          endIndex={Math.min(currentPage * itemsPerPage, meta.total)}
          sortedDataLength={meta.total}
          itemsPerPage={itemsPerPage}
          setItemsPerPage={(v: number) => {
            setCurrentPage(1);
            setItemsPerPage(v);
          }}
        />
      )}

    </div>
  );
}
