import { useState, useMemo, useEffect, useRef } from 'react';
import {
  Search,
  Plus,
  Edit,
  Trash2,
  Mail,
  Phone,
  ShieldAlert,
  Contact,
  Headphones,
  Settings,
  User
} from 'lucide-react';
import { Button } from '@astryxdesign/core/Button';
import { Card } from '@astryxdesign/core/Card';
import { Table, proportional, pixel } from '@astryxdesign/core/Table';
import { AlertDialog } from '@astryxdesign/core/AlertDialog';
import { Badge } from '@astryxdesign/core/Badge';
import { Text } from '@astryxdesign/core/Text';
import { IconButton } from '@astryxdesign/core/IconButton';
import { TextInput } from '@astryxdesign/core/TextInput';
import { Banner } from '@astryxdesign/core/Banner';

import PageHeader from '@/components/PageHeader';
import StatusChip from '@/components/StatusChip';
import EmptyState from '@/components/EmptyState';
import TabLabelCount from '@/components/TabLabelCount';
import { fetchUsers, deleteUser } from '@/utils/apiClient';
import { toUser } from '@/utils/mappers';
import { titleCase } from '@/utils/format';
import UserFormDialog from './UserFormDialog';

// Per-role accent colour + icon, used for the avatar badge and role chip.
const ROLE_META = {
  admin: { color: 'primary', icon: ShieldAlert },
  manager: { color: 'success', icon: Settings },
  rep: { color: 'info', icon: Contact },
  support: { color: 'warning', icon: Headphones }
};
const roleMeta = (role) => ROLE_META[String(role || '').toLowerCase()] || { color: 'secondary', icon: User };

// Name + handle only — no avatar (role is already shown in its own column).
function UserIdentity({ name, email }) {
  const handle = email ? email.split('@')[0] : '';

  return (
    <div style={{ minWidth: 0 }}>
      <div style={{ fontWeight: 600, color: '#1e293b', fontSize: '0.8rem', lineHeight: 1.2 }}>{name}</div>
      {handle && <div style={{ fontSize: '0.68rem', color: '#64748b' }}>@{handle}</div>}
    </div>
  );
}

const ROLE_BADGE_VARIANT = {
  primary: 'red',
  success: 'success',
  info: 'info',
  warning: 'warning',
  secondary: 'neutral'
};

function RoleCell({ role }) {
  const { color } = roleMeta(role);
  return <Badge variant={ROLE_BADGE_VARIANT[color] || 'neutral'} label={titleCase(role)} />;
}

export default function TeamUsers() {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  const [tab, setTab] = useState(0);
  const [search, setSearch] = useState('');
  const [page, setPage] = useState(0);
  const [rpp, setRpp] = useState(10);

  const [dialog, setDialog] = useState({ open: false, mode: 'add', initial: null });
  const [toDelete, setToDelete] = useState(null);
  const [deleting, setDeleting] = useState(false);

  // Guards against out-of-order responses (e.g. React StrictMode's double-invoked
  // effect, or a quick double-click on Refresh) so a stale request can never
  // clobber a newer one's result.
  const loadRequestId = useRef(0);

  const load = () => {
    const requestId = ++loadRequestId.current;
    setLoading(true);
    setError(null);
    fetchUsers()
      .then((points) => {
        if (loadRequestId.current === requestId) setUsers(points.map(toUser));
      })
      .catch((e) => {
        if (loadRequestId.current === requestId) setError(e.message || 'Failed to load team users');
      })
      .finally(() => {
        if (loadRequestId.current === requestId) setLoading(false);
      });
  };

  useEffect(() => { load(); }, []);

  const tabs = useMemo(() => {
    const seen = [];
    users.forEach((u) => { if (!seen.includes(u.role)) seen.push(u.role); });
    return [{ key: 'all', label: 'All' }, ...seen.map((r) => ({ key: r, label: titleCase(r) }))];
  }, [users]);

  const tabKey = tabs[Math.min(tab, tabs.length - 1)]?.key || 'all';

  const counts = useMemo(() => {
    const c = { all: users.length };
    users.forEach((u) => { c[u.role] = (c[u.role] || 0) + 1; });
    return c;
  }, [users]);

  const filtered = useMemo(
    () =>
      users.filter((u) => {
        const matchTab = tabKey === 'all' || u.role === tabKey;
        const matchSearch =
          !search || [u.name, u.email, u.phone, u.role].join(' ').toLowerCase().includes(search.toLowerCase());
        return matchTab && matchSearch;
      }),
    [users, tabKey, search]
  );

  const paged = filtered.slice(page * rpp, page * rpp + rpp);
  const displayRows = useMemo(
    () => paged.map((row, i) => ({ ...row, _rowNumber: page * rpp + i + 1 })),
    [paged, page, rpp]
  );

  const columns = useMemo(() => [
    {
      key: '_rowNumber',
      header: <div style={{ paddingLeft: '24px', paddingTop: '12px' }}>S.No</div>,
      width: pixel(72),
      renderCell: (r) => (
        <div style={{ paddingLeft: '24px' }}>
          <Text type="supporting" color="secondary">{r._rowNumber}</Text>
        </div>
      )
    },
    {
      key: 'name',
      header: <div style={{ padding: '12px 16px 0' }}>User</div>,
      width: proportional(2),
      renderCell: (r) => (
        <div style={{ padding: '10px 16px' }}>
          <UserIdentity name={r.name} email={r.email} />
        </div>
      )
    },
    {
      key: 'email',
      header: <div style={{ padding: '12px 16px 0' }}>Email</div>,
      width: proportional(2),
      renderCell: (r) => (
        <div style={{ padding: '10px 16px' }}>
          {r.email ? (
            <a href={`mailto:${r.email}`} style={{ display: 'inline-flex', alignItems: 'center', gap: '6px', textDecoration: 'none' }} className="link-hover">
              <Mail size={14} style={{ color: '#94a3b8' }} />
              <Text type="body" size="sm">{r.email}</Text>
            </a>
          ) : <Text type="supporting" color="disabled">—</Text>}
        </div>
      )
    },
    {
      key: 'phone',
      header: <div style={{ padding: '12px 16px 0' }}>Phone</div>,
      width: proportional(1),
      renderCell: (r) => (
        <div style={{ padding: '10px 16px' }}>
          {r.phone ? (
            <a href={`tel:${r.phone}`} style={{ display: 'inline-flex', alignItems: 'center', gap: '6px', textDecoration: 'none' }} className="link-hover">
              <Phone size={14} style={{ color: '#94a3b8' }} />
              <Text type="body" size="sm">{r.phone}</Text>
            </a>
          ) : <Text type="supporting" color="disabled">—</Text>}
        </div>
      )
    },
    {
      key: 'role',
      header: <div style={{ padding: '12px 16px 0' }}>Role</div>,
      width: pixel(140),
      renderCell: (r) => (
        <div style={{ padding: '10px 16px' }}>
          <RoleCell role={r.role} />
        </div>
      )
    },
    {
      key: 'actions',
      header: <div style={{ paddingRight: '24px', paddingTop: '12px' }}>Actions</div>,
      width: pixel(120),
      align: 'end',
      renderCell: (r) => (
        <div style={{ display: 'inline-flex', gap: '8px', paddingRight: '24px' }}>
          <IconButton
            label={`Edit ${r.name}`}
            tooltip="Edit user"
            variant="ghost"
            size="sm"
            icon={<Edit size={16} />}
            onClick={() => setDialog({ open: true, mode: 'edit', initial: r })}
          />
          <IconButton
            label={`Delete ${r.name}`}
            tooltip="Delete user"
            variant="ghost"
            size="sm"
            icon={<Trash2 size={16} style={{ color: '#dc2626' }} />}
            onClick={() => setToDelete(r)}
          />
        </div>
      )
    }
  ], []);

  const handleSaved = () => { setDialog({ open: false, mode: 'add', initial: null }); load(); };

  const confirmDelete = async () => {
    setDeleting(true);
    try {
      await deleteUser(toDelete.id);
      setToDelete(null);
      load();
    } catch (e) {
      setError(e.message || 'Failed to delete user');
    } finally {
      setDeleting(false);
    }
  };

  return (
    <div style={{ fontFamily: 'system-ui, sans-serif' }}>
      <PageHeader
        title="Team Users"
        action={
          <div style={{ display: 'flex', alignItems: 'center', gap: '12px', flexWrap: 'nowrap' }}>
            <div style={{ flex: '0 1 320px', minWidth: '200px' }}>
              <TextInput
                label="Search team users"
                isLabelHidden
                placeholder="Search team users…"
                startIcon={<Search size={16} />}
                hasClear
                value={search}
                onChange={(v) => { setSearch(v); setPage(0); }}
                htmlName="team-users-search"
                autoComplete="off"
              />
            </div>
            <Button
              variant="primary"
              icon={<Plus size={14} />}
              onClick={() => setDialog({ open: true, mode: 'add', initial: null })}
              label="Add User"
              style={{ flexShrink: 0 }}
            />
          </div>
        }
      />

      <Card style={{ padding: '0', borderRadius: '16px', border: '1px solid rgba(5, 54, 89, 0.08)', backgroundColor: '#ffffff', overflow: 'hidden', boxShadow: '0 10px 30px -5px rgba(0,0,0,0.02), 0 4px 12px -3px rgba(0,0,0,0.02)' }}>
        {/* Tabs */}
        <div style={{ display: 'flex', padding: '0 24px', borderBottom: '1px solid rgba(5, 54, 89, 0.06)', overflowX: 'auto', gap: '24px' }}>
          {tabs.map((t, i) => (
            <div
              key={t.key}
              onClick={() => { setTab(i); setPage(0); }}
              style={{
                padding: '16px 0',
                cursor: 'pointer',
                borderBottom: tab === i ? '2px solid #C01227' : '2px solid transparent',
                color: tab === i ? '#C01227' : '#64748b',
                fontWeight: tab === i ? 600 : 500,
                fontSize: '0.875rem',
                transition: 'all 0.2s'
              }}
            >
              <TabLabelCount label={t.label} count={counts[t.key] || 0} active={tab === i} />
            </div>
          ))}
        </div>

        {error && (
          <div style={{ padding: '20px 24px 0' }}>
            <Banner
              status="error"
              title={error}
              endContent={<Button label="Retry" variant="ghost" size="sm" onClick={load} />}
            />
          </div>
        )}

        {loading ? (
          <div style={{ display: 'flex', justifyContent: 'center', padding: '48px 0' }}>
            <div className="spinner" style={{ width: '32px', height: '32px', border: '3px solid #f1f5f9', borderTop: '3px solid #C01227', borderRadius: '50%', animation: 'spin 1s linear infinite' }} />
          </div>
        ) : paged.length === 0 ? (
          <EmptyState title="No team users found" caption="Try a different role or search term, or add a user." />
        ) : (
          <div style={{ paddingTop: '8px', paddingBottom: '8px' }}>
            <Table
              data={displayRows}
              columns={columns}
              idKey="id"
              density="compact"
              dividers="rows"
              hasHover
              isStriped
              textOverflow="truncate"
            />
          </div>
        )}

        {/* Pagination bar */}
        <div style={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', padding: '12px 24px', borderTop: '1px solid #e2e8f0', gap: '20px', flexWrap: 'wrap' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: '8px', fontSize: '0.875rem', color: '#475569' }}>
            <span>Rows per page:</span>
            <select
              value={rpp}
              onChange={(e) => { setRpp(Number(e.target.value)); setPage(0); }}
              className="rpp-select"
            >
              {[5, 10, 25].map((opt) => <option key={opt} value={opt}>{opt}</option>)}
            </select>
          </div>
          <span style={{ fontSize: '0.875rem', color: '#475569' }}>
            {filtered.length === 0 ? '0-0' : `${page * rpp + 1}-${Math.min((page + 1) * rpp, filtered.length)}`} of {filtered.length}
          </span>
          <div style={{ display: 'flex', gap: '8px' }}>
            <Button
              label="Prev"
              variant="secondary"
              size="sm"
              onClick={() => setPage((p) => Math.max(0, p - 1))}
              isDisabled={page === 0}
            />
            <Button
              label="Next"
              variant="secondary"
              size="sm"
              onClick={() => setPage((p) => Math.min(Math.ceil(filtered.length / rpp) - 1, p + 1))}
              isDisabled={page >= Math.ceil(filtered.length / rpp) - 1}
            />
          </div>
        </div>
      </Card>

      <UserFormDialog
        open={dialog.open}
        mode={dialog.mode}
        initial={dialog.initial}
        onClose={() => setDialog({ open: false, mode: 'add', initial: null })}
        onSaved={handleSaved}
      />

      <AlertDialog
        isOpen={!!toDelete}
        onOpenChange={(o) => { if (!o) setToDelete(null); }}
        title="Delete user?"
        description={toDelete ? `This will permanently remove ${toDelete.name} from the PostgreSQL database. This cannot be undone.` : ''}
        actionLabel="Delete"
        onAction={confirmDelete}
        isActionLoading={deleting}
      />

      <style>{`
        .link-hover:hover {
          text-decoration: underline;
        }
        @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
      `}</style>
    </div>
  );
}
