'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 ClientsHeader from './ClientsHeader';
import ClientsFilters from './ClientsFilters';
import DynamicClientRow from './DynamicClientRow';
import ClientRowComponent from './ClientRow';
import ClientsAnalyticsInline from './ClientsAnalyticsInline';
import { useClientsPermissions } from './useClientsPermissions';
import { thStyle } from './design-tokens';

import {
  getClientsPaged,
  getClientScope,
  getClientSignedDocUrl,
} from '@/lib/api/clients.api';
import {
  mapColumnKeyToValue,
  rowKey,
  clientCode,
  hasSignedDoc,
  signedDocName,
} from '@/lib/api/mappers/clients.mappers';
import type {
  ClientRow,
  ClientScope,
  ClientSource,
  ClientTypeFilter,
} from '@/lib/api/types/clients.types';

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 ClientsPage() {
  const router = useRouter();

  // ── Permissions (same dynamic system as previous-nc) ───────────
  const {
    moduleConfig,
    permittedActions,
    visibleColumns,
    headerColumns,
    rowButtons,
    hasActionsColumn,
    useDynamicMode,
    permissionsLoading,
    rawUserId,
    debugLog,
    can,
  } = useClientsPermissions('clients', 'Clients');

  // ── Data state ─────────────────────────────────────────────────
  const [data, setData] = useState<ClientRow[]>([]);
  const [meta, setMeta] = useState<{
    total: number;
    page: number;
    limit: number;
    totalPages: number;
  } | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [scope, setScope] = useState<ClientScope | null>(null);

  const [currentPage, setCurrentPage] = useState(1);
  const [itemsPerPage, setItemsPerPage] = useState(10);

  // ── Filter state ───────────────────────────────────────────────
  const [searchTerm, setSearchTerm] = useState('');
  const [sourceFilter, setSourceFilter] = useState<'all' | ClientSource>('all');
  const [typeFilter, setTypeFilter] = useState<ClientTypeFilter>('All');
  const [statusFilter, setStatusFilter] = useState<'all' | 'active' | 'inactive'>('all');
  const debouncedSearch = useDebounce(searchTerm, 400);

  // ── Analytics ──────────────────────────────────────────────────
  const [showAnalytics, setShowAnalytics] = useState(false);
  const [analyticsData, setAnalyticsData] = useState<ClientRow[]>([]);
  const [analyticsLoaded, setAnalyticsLoaded] = useState(false);
  const [analyticsLoading, setAnalyticsLoading] = useState(false);

  const [exporting, setExporting] = useState(false);
  const [showDebug, setShowDebug] = useState(true);

  // ── Fetching ───────────────────────────────────────────────────
  const fetchPage = useCallback(
    (
      page: number,
      limit: number,
      search: string,
      source: string,
      type: ClientTypeFilter,
    ) => {
      setLoading(true);
      getClientsPaged({
        page,
        limit,
        ...(search && { search }),
        source: source === 'all' ? 'All' : (source as ClientSource),
        type,
      })
        .then((res) => {
          setData(res.rows);
          setMeta({
            total: res.total,
            page: res.page,
            limit: res.limit,
            totalPages: res.totalPages,
          });
        })
        .catch((err) => setError(err.message))
        .finally(() => setLoading(false));
    },
    [],
  );

  const fetchAllForAnalytics = useCallback(() => {
    if (analyticsLoaded) return;
    setAnalyticsLoading(true);
    getClientsPaged({ page: 1, limit: 200 })
      .then((res) => {
        setAnalyticsData(res.rows);
        setAnalyticsLoaded(true);
      })
      .catch(() => toast.error('Analytics fetch failed'))
      .finally(() => setAnalyticsLoading(false));
  }, [analyticsLoaded]);

  const handleAnalyticsToggle = useCallback(() => {
    setShowAnalytics((v) => {
      if (!v) fetchAllForAnalytics();
      return !v;
    });
  }, [fetchAllForAnalytics]);

  // ── Initial load ───────────────────────────────────────────────
  useEffect(() => {
    getClientScope()
      .then(setScope)
      .catch(() => setScope(null));
    fetchPage(1, itemsPerPage, '', 'all', 'All');
    setCurrentPage(1);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // Re-fetch on page / limit change
  useEffect(() => {
    fetchPage(currentPage, itemsPerPage, debouncedSearch, sourceFilter, typeFilter);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [currentPage, itemsPerPage]);

  // Re-fetch on filter change
  useEffect(() => {
    setCurrentPage(1);
    fetchPage(1, itemsPerPage, debouncedSearch, sourceFilter, typeFilter);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [debouncedSearch, sourceFilter, typeFilter]);

  const refresh = () => {
    fetchPage(currentPage, itemsPerPage, debouncedSearch, sourceFilter, typeFilter);
    setAnalyticsLoaded(false);
    if (showAnalytics) {
      setAnalyticsData([]);
      fetchAllForAnalytics();
    }
  };

  const clearAllFilters = () => {
    setSearchTerm('');
    setSourceFilter('all');
    setTypeFilter('All');
    setStatusFilter('all');
  };

  /**
   * Status has no server-side param yet, so it filters the current page
   * client-side. Note this means the count strip still reflects the
   * server total — add a `status` query param to the Nest DTO if you
   * want it to participate in pagination properly.
   */
  const displayRows = useMemo(() => {
    if (statusFilter === 'all') return data;
    const want = statusFilter === 'active' ? 1 : 0;
    return data.filter((r) => Number(r.status ?? -1) === want);
  }, [data, statusFilter]);

  // ── Row actions ────────────────────────────────────────────────
  const handleView = (row: ClientRow) => {
    if (!can('view') && !can('view-all')) {
      toast.error("You don't have permission to view client details");
      return;
    }
    router.push(
      `/modules/clients/view?source=${row.source}&type=${row.client_type}&id=${row.id}`,
    );
  };

  const handleEdit = (row: ClientRow) => {
    if (!can('edit')) {
      toast.error("You don't have permission to edit clients");
      return;
    }
    router.push(
      `/modules/clients/edit?source=${row.source}&type=${row.client_type}&id=${row.id}`,
    );
  };

  const handleDelete = (row: ClientRow) => {
    if (!can('delete')) {
      toast.error("You don't have permission to delete clients");
      return;
    }
    // The legacy QRS/TQS tables are read-only from this app — there is no
    // DELETE endpoint on the Nest side. Wire this up once you add one.
    toast.error('Legacy client records are read-only in this CRM.');
  };

  const handleAuditRequest = (row: ClientRow) => {
    if (!can('audit-request')) {
      toast.error("You don't have permission to raise audit requests");
      return;
    }
    router.push(
      `/modules/audit-requests/new?client_ref_id=${row.id}&client_group=${row.source}&company_source=${row.client_type}`,
    );
  };

  /**
   * Open the signed document — same flow as the audit report:
   * GET /clients/signed-doc/url → { url, filename, docname }, then open it
   * in a new tab. Being able to view the client implies being able to open
   * its signed doc; the dedicated 'signed-doc' action only gates the
   * row-menu button when the module is seeded.
   */
  const handleOpenSignedDoc = async (row: ClientRow) => {
    if (!can('signed-doc') && !can('view') && !can('view-all')) {
      toast.error("You don't have permission to open signed documents");
      return;
    }
    if (!hasSignedDoc(row)) {
      toast.error('No signed document uploaded for this record');
      return;
    }
    // Open the tab inside the click gesture so popup blockers don't eat it
    // after the await, then point it at the resolved URL.
    const win = window.open('', '_blank');
    if (win) win.opener = null;
    try {
      const { url } = await getClientSignedDocUrl(row.id, row.source);
      if (win) {
        win.location.href = url;
      } else {
        window.open(url, '_blank');
      }
    } catch (err: any) {
      win?.close();
      toast.error(err?.message ?? 'Could not open the signed document');
    }
  };

  // ── CSV export ─────────────────────────────────────────────────
  const toCsv = (rows: ClientRow[]): string => {
    const cols = [
      'Code',
      'Source',
      'Type',
      'Company',
      'Contact',
      'Designation',
      'Email',
      'Mobile',
      'Telephone',
      'Address',
      'Sector',
      'Trade license',
      'Signed doc',
      'Status',
      'Created',
    ];
    const esc = (v: any) => {
      const s = v === null || v === undefined ? '' : String(v);
      return /[",\n]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
    };
    const lines = rows.map((r) =>
      [
        clientCode(r),
        r.source,
        r.client_type,
        r.company_name,
        r.contact_primary,
        r.designationpr,
        r.email_id,
        r.mobile_no,
        r.telephone,
        r.Address,
        r.company_sector,
        r.trade_license,
        signedDocName(r) ?? '',
        r.status === 1 ? 'Active' : r.status === 0 ? 'Inactive' : '',
        r.created_at ?? '',
      ]
        .map(esc)
        .join(','),
    );
    return [cols.join(','), ...lines].join('\n');
  };

  const download = (rows: ClientRow[], name: string) => {
    const blob = new Blob([toCsv(rows)], { type: 'text/csv;charset=utf-8;' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = name;
    a.click();
    setTimeout(() => URL.revokeObjectURL(url), 30_000);
  };

  const handleExport = async () => {
    if (!can('export')) {
      toast.error("You don't have permission to export clients");
      return;
    }
    setExporting(true);
    try {
      // Pull a wider slice than the visible page — still owner-scoped server-side.
      const res = await getClientsPaged({
        page: 1,
        limit: 200,
        ...(debouncedSearch && { search: debouncedSearch }),
        source: sourceFilter === 'all' ? 'All' : sourceFilter,
        type: typeFilter,
      });
      download(res.rows, `clients-${new Date().toISOString().slice(0, 10)}.csv`);
      toast.success(`Exported ${res.rows.length} records`);
    } catch (err: any) {
      toast.error(err?.message ?? 'Export failed');
    } finally {
      setExporting(false);
    }
  };

  const handleExportRow = (row: ClientRow) => {
    download([row], `${clientCode(row)}.csv`);
  };

  // ── Render ─────────────────────────────────────────────────────
  if (error)
    return (
      <div className={styles.errorContainer}>
        <div className={styles.errorIcon}>⚠️</div>
        <h3 className={styles.errorTitle}>Error</h3>
        <p className={styles.errorMessage}>{error}</p>
        <button className={styles.errorButton} onClick={refresh}>
          Retry
        </button>
      </div>
    );

  if (permissionsLoading) return <EnterpriseLoader />;

  const colSpan = (useDynamicMode ? headerColumns.length : 10) + (hasActionsColumn ? 1 : 0);
  const noLegacyMatch =
    scope && !scope.can_view_all && scope.qrs_user_id === null && scope.tqs_user_id === null;

  return (
    <div className={styles.container}>
      <ClientsHeader
        totalClients={meta?.total}
        scope={scope}
        onRefresh={refresh}
        isReady={!permissionsLoading}
      />

      {/* DEBUG PANEL (userId=1 only) — same as previous-nc */}
      {Number(rawUserId?.userId) === 1 && (
        <div
          style={{
            margin: '0 0 16px',
            border: `2px solid ${useDynamicMode ? '#14b8a6' : '#f59e0b'}`,
            overflow: 'hidden',
            background: useDynamicMode ? '#f0fdfa' : '#fffbeb',
            fontSize: 13,
            borderRadius: 8,
          }}
        >
          <div
            onClick={() => setShowDebug(!showDebug)}
            style={{
              padding: '10px 16px',
              background: useDynamicMode ? '#0f766e' : '#f59e0b',
              color: '#fff',
              fontWeight: 700,
              cursor: 'pointer',
              display: 'flex',
              justifyContent: 'space-between',
            }}
          >
            <span>
              {useDynamicMode ? '✅ DYNAMIC' : '⚠️ FALLBACK'} — {meta?.total ?? 0} total
            </span>
            <span>{showDebug ? '▼' : '▶'}</span>
          </div>
          {showDebug && (
            <div style={{ padding: 16 }}>
              <div
                style={{
                  display: 'grid',
                  gridTemplateColumns: 'repeat(auto-fit,minmax(180px,1fr))',
                  gap: 10,
                  marginBottom: 12,
                }}
              >
                {[
                  {
                    ok: !!moduleConfig,
                    title: moduleConfig ? `Module #${moduleConfig.id}` : 'No Module',
                    detail: `${moduleConfig?.button_config?.length || 0}b ${moduleConfig?.column_config?.length || 0}c`,
                  },
                  {
                    ok: !!rawUserId?.userId,
                    title: rawUserId?.userId ? `User #${rawUserId.userId}` : 'No User',
                    detail: rawUserId?.source || '',
                  },
                  {
                    ok: permittedActions.size > 0,
                    title: `${permittedActions.size} action(s)`,
                    detail: Array.from(permittedActions).join(', ') || '(none)',
                  },
                  {
                    ok: !!scope && (scope.can_view_all || !noLegacyMatch),
                    title: scope
                      ? scope.can_view_all
                        ? 'View all'
                        : `QRS #${scope.qrs_user_id ?? '—'} / TQS #${scope.tqs_user_id ?? '—'}`
                      : 'No scope',
                    detail: 'legacy id mapping',
                  },
                  {
                    ok: !!meta,
                    title: meta ? `${meta.total} Records` : '—',
                    detail: meta ? `Page ${meta.page}/${meta.totalPages}` : '',
                  },
                ].map((c, i) => (
                  <div
                    key={i}
                    style={{
                      padding: 10,
                      background: c.ok ? '#dcfce7' : '#fef2f2',
                      borderRadius: 8,
                      textAlign: 'center',
                    }}
                  >
                    <div
                      style={{
                        fontWeight: 700,
                        color: c.ok ? '#166534' : '#991b1b',
                        fontSize: 13,
                      }}
                    >
                      {c.ok ? '✅' : '❌'} {c.title}
                    </div>
                    <div style={{ fontSize: 11, color: '#64748b', marginTop: 2 }}>
                      {c.detail}
                    </div>
                  </div>
                ))}
              </div>
              <details>
                <summary style={{ cursor: 'pointer', fontWeight: 600, color: '#0f766e' }}>
                  📋 Debug Log
                </summary>
                <div
                  style={{
                    background: '#0f172a',
                    borderRadius: 6,
                    padding: 10,
                    maxHeight: 150,
                    overflow: 'auto',
                    marginTop: 4,
                  }}
                >
                  {debugLog.map((l, i) => (
                    <div
                      key={i}
                      style={{
                        fontSize: 11,
                        color: l.includes('✅') ? '#4ade80' : l.includes('⚠️') ? '#fbbf24' : '#94a3b8',
                        fontFamily: 'monospace',
                        marginBottom: 2,
                      }}
                    >
                      {l}
                    </div>
                  ))}
                </div>
              </details>
            </div>
          )}
        </div>
      )}

      {/* No legacy account warning — the one failure mode worth surfacing */}
      {noLegacyMatch && (
        <div
          style={{
            padding: '12px 16px',
            background: '#fffbeb',
            border: '1px solid #fde68a',
            borderRadius: 8,
            marginBottom: 12,
            fontSize: 13,
            color: '#92400e',
          }}
        >
          ⚠️ Your account has no matching user in the QRS or TQS databases, so no
          client records can be shown. Ask an administrator to align your email
          address across the systems.
        </div>
      )}

      <ClientsFilters
        searchTerm={searchTerm}
        setSearchTerm={setSearchTerm}
        sourceFilter={sourceFilter}
        setSourceFilter={setSourceFilter}
        typeFilter={typeFilter}
        setTypeFilter={setTypeFilter}
        statusFilter={statusFilter}
        setStatusFilter={setStatusFilter}
        clearFilters={clearAllFilters}
        onRefresh={refresh}
        onAnalyticsToggle={handleAnalyticsToggle}
        showAnalytics={showAnalytics}
        onExport={handleExport}
        canExport={can('export')}
        exporting={exporting}
      />

      {showAnalytics && (
        <ClientsAnalyticsInline rows={analyticsData} loading={analyticsLoading} />
      )}

      {/* Count strip */}
      {meta && (
        <div
          style={{
            padding: '10px 16px',
            background: 'linear-gradient(90deg, #f0fdfa 0%, #f8fafc 100%)',
            border: '1px solid #99f6e4',
            borderRadius: 8,
            marginBottom: 12,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'space-between',
            fontSize: 13,
            color: '#0f766e',
            flexWrap: 'wrap',
            gap: 8,
          }}
        >
          <span>
            🏢 Showing{' '}
            <strong>
              {meta.total === 0 ? 0 : (currentPage - 1) * itemsPerPage + 1}–
              {Math.min(currentPage * itemsPerPage, meta.total)}
            </strong>{' '}
            of <strong>{meta.total.toLocaleString()}</strong> records
          </span>
          {scope && !scope.can_view_all && (
            <span
              style={{
                fontSize: 11,
                fontWeight: 700,
                color: '#0f766e',
                background: '#fff',
                padding: '3px 10px',
                borderRadius: 99,
                border: '1px solid #99f6e4',
              }}
            >
              🔒 Your records only
            </span>
          )}
        </div>
      )}

      {/* Table */}
      <div className={styles.tableWrapper}>
        <table className={styles.table} style={{ width: '100%' }}>
          <thead>
            <tr>
              {useDynamicMode ? (
                <>
                  {headerColumns.map((col) => (
                    <th key={col.key} style={thStyle}>
                      {col.label}
                    </th>
                  ))}
                  {hasActionsColumn && <th style={thStyle}>Actions</th>}
                </>
              ) : (
                <>
                  <th style={thStyle}>Code</th>
                  <th style={thStyle}>Company</th>
                  <th style={thStyle}>Type</th>
                  <th style={thStyle}>Contact</th>
                  <th style={thStyle}>Standards</th>
                  <th style={thStyle}>Email</th>
                  <th style={thStyle}>Location</th>
                  <th style={thStyle}>Signed doc</th>
                  <th style={thStyle}>Status</th>
                  <th style={thStyle}>Created</th>
                  <th style={thStyle}>Actions</th>
                </>
              )}
            </tr>
          </thead>
          <tbody>
            {loading ? (
              <tr>
                <td colSpan={colSpan} style={{ textAlign: 'center', padding: 60 }}>
                  <EnterpriseLoader />
                </td>
              </tr>
            ) : displayRows.length === 0 ? (
              <tr>
                <td colSpan={colSpan} style={{ textAlign: 'center', padding: 60 }}>
                  <div style={{ fontSize: 36 }}>🏢</div>
                  <h3 style={{ margin: '12px 0 4px', color: '#111827' }}>
                    No clients found
                  </h3>
                  <p style={{ color: '#6b7280', margin: 0 }}>
                    {searchTerm ||
                    sourceFilter !== 'all' ||
                    typeFilter !== 'All' ||
                    statusFilter !== 'all'
                      ? 'No records match your filters.'
                      : 'No client records are assigned to you.'}
                  </p>
                </td>
              </tr>
            ) : (
              displayRows.map((row) =>
                useDynamicMode ? (
                  <DynamicClientRow
                    key={rowKey(row)}
                    row={row}
                    visibleColumns={visibleColumns}
                    rowButtons={rowButtons}
                    hasActionsColumn={hasActionsColumn}
                    mapColumnKeyToValue={mapColumnKeyToValue}
                    onView={handleView}
                    onEdit={handleEdit}
                    onDelete={handleDelete}
                    onAuditRequest={handleAuditRequest}
                    onExportRow={handleExportRow}
                    onOpenSignedDoc={handleOpenSignedDoc}
                  />
                ) : (
                  <ClientRowComponent
                    key={rowKey(row)}
                    row={row}
                    permittedActions={permittedActions}
                    onView={handleView}
                    onEdit={handleEdit}
                    onDelete={handleDelete}
                    onAuditRequest={handleAuditRequest}
                    onExportRow={handleExportRow}
                    onOpenSignedDoc={handleOpenSignedDoc}
                  />
                ),
              )
            )}
          </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>
  );
}
