function ContactsPage() {
  const { AppBootstrap } = window.__CRM__;
  const {
    Container, Paper, Typography, TextField, Button, Table, TableHead, TableRow, TableCell, TableBody,
    IconButton, Chip, Stack, Pagination, Dialog, DialogTitle, DialogContent, DialogActions, Grid, MenuItem,
    TableContainer, useMediaQuery, Card, CardContent, Divider, Checkbox, FormControlLabel
  } = MaterialUI;

  const isXs = useMediaQuery('(max-width:600px)');
  const isSm = useMediaQuery('(max-width:900px)');

  const [q, setQ] = React.useState("");
  const [rows, setRows] = React.useState([]);
  const [total, setTotal] = React.useState(0);
  const [page, setPage] = React.useState(1);
  const limit = 25;

  // seleção por página
  const [selected, setSelected] = React.useState(new Set());

  // modal
  const emptyForm = { id: 0, name: "", phone: "", email: "", status: "Active", address_line: "", apt_suite: "", city: "", state: "", zip_code: "", country: "", notes: "" };
  const [open, setOpen] = React.useState(false);
  const [form, setForm] = React.useState(emptyForm);

  async function load(p = 1) {
    const offset = (p - 1) * limit;
    const res = await fetch(`/api/contacts_list.php?q=${encodeURIComponent(q)}&limit=${limit}&offset=${offset}`, { credentials: 'include' });
    const j = await res.json();
    setRows(j.items || []); setTotal(j.total || 0); setPage(p);
    setSelected(new Set()); // limpa seleção ao trocar página
  }
  React.useEffect(() => { load(1); }, []);

  async function upsert(payload) {
    await fetch('/api/contacts_upsert.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload), credentials: 'include' });
  }
  async function onDelete(id) {
    if (!confirm('Delete this contact?')) return;
    await fetch('/api/contacts_delete.php', { method: 'POST', body: new URLSearchParams({ id: String(id) }), credentials: 'include' });
    load(page);
  }
  async function onBlock(id) {
    await fetch('/api/contacts_block.php', { method: 'POST', body: new URLSearchParams({ id: String(id) }), credentials: 'include' });
    load(page);
  }
  async function onDeleteBulk() {
    if (selected.size === 0) return;
    if (!confirm(`Delete ${selected.size} selected contact(s)?`)) return;
    await fetch('/api/contacts_delete_bulk.php', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ ids: Array.from(selected) }),
      credentials: 'include'
    });
    load(page);
  }
  function onExportBulk() {
    if (selected.size === 0) return;
    const ids = Array.from(selected).join(',');
    location.href = `/api/contacts_export.php?ids=${encodeURIComponent(ids)}`;
  }

  async function onImport(e) {
    const f = e.target.files?.[0]; if (!f) return;
    const fd = new FormData(); fd.append('file', f);
    await fetch('/api/contacts_import.php', { method: 'POST', body: fd, credentials: 'include' });
    e.target.value = ''; load(1);
  }

  function openAdd() { setForm(emptyForm); setOpen(true); }
  function openEdit(row) { setForm({ ...row }); setOpen(true); }
  function closeModal() { setOpen(false); }
  async function submitModal() {
    if (!form.name.trim()) { alert('Name is required'); return; }
    await upsert(form); setOpen(false); load(form.id ? page : 1);
  }

  const pages = Math.max(1, Math.ceil(total / limit));

  // seleção helpers
  const allIdsOnPage = React.useMemo(() => rows.map(r => r.id), [rows]);
  const allSelected = allIdsOnPage.length > 0 && allIdsOnPage.every(id => selected.has(id));
  const someSelected = allIdsOnPage.some(id => selected.has(id));

  function toggleOne(id) {
    setSelected(prev => {
      const n = new Set(prev);
      if (n.has(id)) n.delete(id); else n.add(id);
      return n;
    });
  }
  function toggleAllPage() {
    setSelected(prev => {
      const n = new Set(prev);
      if (allSelected) {
        allIdsOnPage.forEach(id => n.delete(id));
      } else {
        allIdsOnPage.forEach(id => n.add(id));
      }
      return n;
    });
  }

  // Card renderer (XS)
  const CardRow = ({ r }) => (
    <Card variant="outlined" sx={{ mb: 1, borderRadius: 2 }}>
      <CardContent sx={{ p: 2 }}>
        <Stack direction="row" justifyContent="space-between" alignItems="center" sx={{ mb: 1 }}>
          <FormControlLabel
            control={<Checkbox size="small" checked={selected.has(r.id)} onChange={()=>toggleOne(r.id)} />}
            label={<Typography variant="subtitle1" sx={{ fontWeight: 700, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{r.name}</Typography>}
          />
          <Chip size="small" label={r.status} color={r.status === 'Blocked' ? 'error' : 'success'} />
        </Stack>
        <Stack spacing={0.5} sx={{ color: 'text.secondary', fontSize: 14 }}>
          {r.phone && <div><b>Phone:</b> {r.phone}</div>}
          {r.email && <div><b>Email:</b> {r.email}</div>}
          {(r.city || r.state) && <div><b>Location:</b> {[r.city, r.state].filter(Boolean).join(' / ')}</div>}
          {r.address_line && <div><b>Address:</b> {r.address_line}</div>}
          {r.notes && <div><b>Notes:</b> {r.notes}</div>}
        </Stack>
        <Divider sx={{ my: 1 }} />
        <Stack direction="row" spacing={1} justifyContent="flex-end">
          <IconButton size="small" onClick={() => openEdit(r)} title="Edit"><span class="material-icons">edit</span></IconButton>
          <IconButton size="small" onClick={() => onBlock(r.id)} title="Block"><span class="material-icons">block</span></IconButton>
          <IconButton size="small" onClick={() => onDelete(r.id)} title="Delete"><span class="material-icons">delete</span></IconButton>
        </Stack>
      </CardContent>
    </Card>
  );

  const bulkCount = selected.size;

  return (
    <AppBootstrap>
      <Container maxWidth="xl" sx={{ py: 3 }}>
        <Stack direction={{ xs: 'column', md: 'row' }} spacing={2} alignItems={{ xs: 'stretch', md: 'center' }} justifyContent="space-between" sx={{ mb: 2 }}>
          <Typography variant="h5" sx={{ fontWeight: 700 }}>Contacts</Typography>
          <Stack direction="row" spacing={1} flexWrap="wrap">
            <TextField size="small" placeholder="Search name, email, phone, city" value={q} onChange={e => setQ(e.target.value)} />
            <Button variant="outlined" onClick={() => load(1)}>Search</Button>
            <Button variant="outlined" component="label">Import CSV<input type="file" accept=".csv,text/csv" hidden onChange={onImport} /></Button>
            <Button variant="outlined" onClick={() => bulkCount ? onExportBulk() : (location.href = '/api/contacts_export.php')}>
              {bulkCount ? `Export Selected (${bulkCount})` : 'Export CSV'}
            </Button>
            <Button variant="contained" onClick={openAdd}>Add Contact</Button>
            <Button variant="contained" color="error" disabled={!bulkCount} onClick={onDeleteBulk}>
              Delete Selected{bulkCount ? ` (${bulkCount})` : ''}
            </Button>
          </Stack>
        </Stack>

        {isXs ? (
          <div>
            {rows.length === 0
              ? <Typography sx={{ p: 2 }} color="text.secondary">No records.</Typography>
              : rows.map(r => <CardRow key={r.id} r={r} />)}
          </div>
        ) : (
          <Paper>
            <TableContainer sx={{ maxHeight: isSm ? 520 : 'none' }}>
              <Table size="small" stickyHeader>
                <TableHead>
                  <TableRow>
                    <TableCell padding="checkbox">
                      <Checkbox
                        indeterminate={someSelected && !allSelected}
                        checked={allSelected}
                        onChange={toggleAllPage}
                      />
                    </TableCell>
                    <TableCell>Name</TableCell>
                    <TableCell>Phone</TableCell>
                    <TableCell>Email</TableCell>
                    <TableCell>Status</TableCell>
                    <TableCell sx={{ display: { xs: 'none', md: 'table-cell' } }}>Address</TableCell>
                    <TableCell sx={{ display: { xs: 'none', md: 'table-cell' } }}>City</TableCell>
                    <TableCell sx={{ display: { xs: 'none', lg: 'table-cell' } }}>State</TableCell>
                    <TableCell sx={{ display: { xs: 'none', lg: 'table-cell' } }}>Zip</TableCell>
                    <TableCell sx={{ display: { xs: 'none', lg: 'table-cell' } }}>Country</TableCell>
                    <TableCell sx={{ display: { xs: 'none', lg: 'table-cell' }, maxWidth: 260, whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }}>Notes</TableCell>
                    <TableCell align="right">Actions</TableCell>
                  </TableRow>
                </TableHead>
                <TableBody>
                  {rows.map(r => {
                    const checked = selected.has(r.id);
                    return (
                      <TableRow key={r.id} hover selected={checked}>
                        <TableCell padding="checkbox">
                          <Checkbox checked={checked} onChange={()=>toggleOne(r.id)} />
                        </TableCell>
                        <TableCell sx={{ maxWidth: 220, whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }}>{r.name}</TableCell>
                        <TableCell>{r.phone || '-'}</TableCell>
                        <TableCell sx={{ maxWidth: 220, whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }}>{r.email || '-'}</TableCell>
                        <TableCell><Chip size="small" label={r.status} color={r.status === 'Blocked' ? 'error' : 'success'} /></TableCell>
                        <TableCell sx={{ display: { xs: 'none', md: 'table-cell' } }}>{r.address_line || '-'}</TableCell>
                        <TableCell sx={{ display: { xs: 'none', md: 'table-cell' } }}>{r.city || '-'}</TableCell>
                        <TableCell sx={{ display: { xs: 'none', lg: 'table-cell' } }}>{r.state || '-'}</TableCell>
                        <TableCell sx={{ display: { xs: 'none', lg: 'table-cell' } }}>{r.zip_code || '-'}</TableCell>
                        <TableCell sx={{ display: { xs: 'none', lg: 'table-cell' } }}>{r.country || '-'}</TableCell>
                        <TableCell sx={{ display: { xs: 'none', lg: 'table-cell' }, maxWidth: 260, whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }}>{r.notes || '-'}</TableCell>
                        <TableCell align="right">
                          <Stack direction="row" spacing={1} justifyContent="flex-end">
                            <IconButton size="small" onClick={() => openEdit(r)} title="Edit"><span class="material-icons">edit</span></IconButton>
                            <IconButton size="small" onClick={() => onBlock(r.id)} title="Block"><span class="material-icons">block</span></IconButton>
                            <IconButton size="small" onClick={() => onDelete(r.id)} title="Delete"><span class="material-icons">delete</span></IconButton>
                          </Stack>
                        </TableCell>
                      </TableRow>
                    );
                  })}
                  {rows.length === 0 && (
                    <TableRow><TableCell colSpan={12}><Typography sx={{ p: 2 }} color="text.secondary">No records.</Typography></TableCell></TableRow>
                  )}
                </TableBody>
              </Table>
            </TableContainer>
          </Paper>
        )}

        <Stack alignItems="center" sx={{ mt: 2 }}>
          <Pagination count={pages} page={page} onChange={(_, p) => load(p)} />
        </Stack>
      </Container>

      {/* Dialog */}
      <Dialog open={open} onClose={closeModal} maxWidth="md" fullWidth>
        <DialogTitle>{form.id ? 'Edit Contact' : 'Add Contact'}</DialogTitle>
        <DialogContent dividers>
          <Grid container spacing={2} sx={{ pt: 1 }}>
            <Grid item xs={12} md={6}><TextField label="Name" value={form.name} onChange={e => setForm({ ...form, name: e.target.value })} fullWidth required /></Grid>
            <Grid item xs={12} md={6}>
              <TextField label="Status" select value={form.status} onChange={e => setForm({ ...form, status: e.target.value })} fullWidth>
                <MenuItem value="Active">Active</MenuItem>
                <MenuItem value="Blocked">Blocked</MenuItem>
              </TextField>
            </Grid>
            <Grid item xs={12} md={6}><TextField label="Phone" value={form.phone} onChange={e => setForm({ ...form, phone: e.target.value })} fullWidth /></Grid>
            <Grid item xs={12} md={6}><TextField label="Email" type="email" value={form.email} onChange={e => setForm({ ...form, email: e.target.value })} fullWidth /></Grid>
            <Grid item xs={12}><TextField label="Address" value={form.address_line} onChange={e => setForm({ ...form, address_line: e.target.value })} fullWidth /></Grid>
            <Grid item xs={12} md={4}><TextField label="Apt/Suite" value={form.apt_suite} onChange={e => setForm({ ...form, apt_suite: e.target.value })} fullWidth /></Grid>
            <Grid item xs={12} md={4}><TextField label="City" value={form.city} onChange={e => setForm({ ...form, city: e.target.value })} fullWidth /></Grid>
            <Grid item xs={12} md={4}><TextField label="State" value={form.state} onChange={e => setForm({ ...form, state: e.target.value })} fullWidth /></Grid>
            <Grid item xs={12} md={4}><TextField label="Zip Code" value={form.zip_code} onChange={e => setForm({ ...form, zip_code: e.target.value })} fullWidth /></Grid>
            <Grid item xs={12} md={4}><TextField label="Country" value={form.country} onChange={e => setForm({ ...form, country: e.target.value })} fullWidth /></Grid>
            <Grid item xs={12}><TextField label="Notes" value={form.notes} onChange={e => setForm({ ...form, notes: e.target.value })} fullWidth multiline minRows={3} /></Grid>
          </Grid>
        </DialogContent>
        <DialogActions>
          <Button onClick={closeModal}>Cancel</Button>
          <Button variant="contained" onClick={submitModal}>{form.id ? 'Save' : 'Add'}</Button>
        </DialogActions>
      </Dialog>
    </AppBootstrap>
  );
}
window.ContactsPage = ContactsPage;
