import { Add, Delete, Edit, LinkOutlined } from "@mui/icons-material";
import {
  Autocomplete,
  Button,
  Chip,
  CircularProgress,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  FormControl,
  IconButton,
  InputLabel,
  MenuItem,
  Select,
  TextField,
  Tooltip,
  Typography,
} from "@mui/material";
import { useState } from "react";
import styled from "styled-components";
import {
  TIPOS_CATEGORIA_TESORERIA,
  TIPOS_CATEGORIA_TESORERIA_LIST,
  getTipoCategoriaChip,
} from "../../_standards";
import { esCuentaLegacy, usePlanCuentasQuery } from "../../../tanstack/ContabilidadStack";
import {
  useCreateTesCategoriaMutation,
  useDeleteTesCategoriaMutation,
  useTesCategoriaQuery,
  useUpdateTesCategoriaMutation,
  useUpsertTesCategoriaCuentaContableMutation,
} from "../../../tanstack/TesoreriaStack";

export const TesCategoriaConfigSection = () => {
  const { data: categorias = [], isLoading } = useTesCategoriaQuery();
  const { data: planCuentasRaw = [] } = usePlanCuentasQuery();
  const planCuentas = planCuentasRaw.filter(c => c.acepta_movimientos && !esCuentaLegacy(c));
  const createCat = useCreateTesCategoriaMutation();
  const updateCat = useUpdateTesCategoriaMutation();
  const deleteCat = useDeleteTesCategoriaMutation();

  const upsertMapeo = useUpsertTesCategoriaCuentaContableMutation();

  const EMPTY_FORM = {
    nombre: "",
    tipo: TIPOS_CATEGORIA_TESORERIA.INGRESO.value,
    descripcion: "",
    cuenta_contable_id: "",
  };

  const [modal, setModal] = useState(null);
  const [form, setForm] = useState(EMPTY_FORM);
  const [confirmDelete, setConfirmDelete] = useState(null);
  const [modalMapeo, setModalMapeo] = useState(null); // { id, nombre, cuenta_contable_id }
  const [mapeoValue, setMapeoValue] = useState(null);

  const openCreate = () => {
    setForm(EMPTY_FORM);
    setModal({ mode: "create" });
  };

  const openEdit = (cat) => {
    setForm({
      nombre: cat.nombre,
      tipo: cat.tipo || TIPOS_CATEGORIA_TESORERIA.INGRESO.value,
      descripcion: cat.descripcion || "",
      cuenta_contable_id: cat.cuenta_contable_id || "",
    });
    setModal({ mode: "edit", id: cat.id });
  };

  const handleSave = async () => {
    if (!form.nombre.trim()) return;
    if (modal.mode === "create") {
      await createCat.mutateAsync(form);
    } else {
      await updateCat.mutateAsync({ id: modal.id, data: form });
    }
    setModal(null);
  };

  const handleDelete = async () => {
    await deleteCat.mutateAsync(confirmDelete.id);
    setConfirmDelete(null);
  };

  const openModalMapeo = (cat) => {
    const cuentaActual = planCuentas.find(c => c.id === cat.cuenta_contable_id) || null;
    setMapeoValue(cuentaActual);
    setModalMapeo({ id: cat.id, nombre: cat.nombre });
  };

  const handleGuardarMapeo = async () => {
    await upsertMapeo.mutateAsync({
      id: modalMapeo.id,
      data: { cuenta_contable_id: mapeoValue?.id ?? null },
    });
    setModalMapeo(null);
  };

  const isPending = createCat.isPending || updateCat.isPending;

  return (
    <Container>
      <PageHeader>
        <div>
          <Typography variant="h6" fontWeight={600}>Categorías de Movimiento</Typography>
          <Typography variant="body2" sx={{ opacity: 0.6, mt: 0.5 }}>
            Las categorías del sistema no se pueden modificar. Podés agregar categorías propias.
          </Typography>
        </div>
        <Button variant="contained" startIcon={<Add />} onClick={openCreate}>
          Nueva categoría
        </Button>
      </PageHeader>

      <TableWrap>
        <ScrollX>
        <StyledTable>
          <thead>
            <tr>
              <Th>Nombre</Th>
              <Th>Tipo</Th>
              <Th>Cuenta contable</Th>
              <Th>Sistema</Th>
              <Th>Acciones</Th>
            </tr>
          </thead>
          <tbody>
            {isLoading ? (
              <tr><Td colSpan={5} style={{ textAlign: "center", padding: 32 }}><CircularProgress size={20} /></Td></tr>
            ) : categorias.length === 0 ? (
              <tr><Td colSpan={5} style={{ textAlign: "center", opacity: 0.5 }}>Sin categorías</Td></tr>
            ) : categorias.map((cat) => (
              <Tr key={cat.id}>
                <Td style={{ fontWeight: 500 }}>{cat.nombre}</Td>
                <Td>
                  <Chip
                    label={getTipoCategoriaChip(cat.tipo).label}
                    size="small"
                    color={getTipoCategoriaChip(cat.tipo).color}
                  />
                </Td>
                <Td style={{ opacity: 0.65, fontSize: 12 }}>
                  {cat.cuenta_contable_id
                    ? (() => { const c = planCuentas.find(p => p.id === cat.cuenta_contable_id); return c ? `${c.codigo} ${c.descripcion}` : "—"; })()
                    : <span style={{ opacity: 0.4 }}>Sin mapear</span>}
                </Td>
                <Td>
                  {cat.is_sistema && <Chip label="Sistema" size="small" variant="outlined" />}
                </Td>
                <Td>
                  {cat.is_sistema ? (
                    <Tooltip title="Asignar cuenta contable para esta empresa">
                      <IconButton size="small" color="primary" onClick={() => openModalMapeo(cat)}>
                        <LinkOutlined fontSize="small" />
                      </IconButton>
                    </Tooltip>
                  ) : (
                    <div style={{ display: "flex", gap: 4 }}>
                      <Tooltip title="Editar">
                        <IconButton size="small" onClick={() => openEdit(cat)}>
                          <Edit fontSize="small" />
                        </IconButton>
                      </Tooltip>
                      <Tooltip title="Eliminar">
                        <IconButton size="small" color="error" onClick={() => setConfirmDelete(cat)}>
                          <Delete fontSize="small" />
                        </IconButton>
                      </Tooltip>
                    </div>
                  )}
                </Td>
              </Tr>
            ))}
          </tbody>
        </StyledTable>
        </ScrollX>
      </TableWrap>

      <Dialog open={!!modal} onClose={() => setModal(null)} maxWidth="sm" fullWidth>
        <DialogTitle>{modal?.mode === "create" ? "Nueva categoría" : "Editar categoría"}</DialogTitle>
        <DialogContent>
          <Fields>
            <TextField
              label="Nombre"
              required
              fullWidth
              value={form.nombre}
              onChange={(e) => setForm((f) => ({ ...f, nombre: e.target.value }))}
            />
            <FormControl fullWidth>
              <InputLabel>Tipo</InputLabel>
              <Select value={form.tipo} label="Tipo" onChange={(e) => setForm((f) => ({ ...f, tipo: e.target.value }))}>
                {TIPOS_CATEGORIA_TESORERIA_LIST.map((t) => (
                  <MenuItem key={t.value} value={t.value}>{t.label}</MenuItem>
                ))}
              </Select>
              <Typography variant="caption" sx={{ mt: 0.5, opacity: 0.75 }}>
                La categoría aparece solo al registrar movimientos de su mismo tipo. Usá
                {" "}<strong>Ingreso y egreso</strong> para conceptos que van en los dos sentidos
                (ej: un anticipo que se paga y después se devuelve) y así no tener que cargarla dos veces.
              </Typography>
            </FormControl>
            <TextField
              label="Descripción"
              fullWidth
              multiline
              rows={2}
              value={form.descripcion}
              onChange={(e) => setForm((f) => ({ ...f, descripcion: e.target.value }))}
            />
            {planCuentas.length > 0 && (
              <Autocomplete
                fullWidth
                options={planCuentas}
                getOptionLabel={(c) => c.codigo ? `${c.codigo} — ${c.descripcion}` : (c.descripcion || "")}
                value={planCuentas.find((c) => c.id === form.cuenta_contable_id) || null}
                onChange={(_, val) => setForm((f) => ({ ...f, cuenta_contable_id: val?.id || "" }))}
                renderInput={(params) => (
                  <TextField
                    {...params}
                    label="Cuenta contable"
                    size="small"
                    helperText="Contracuenta usada en asientos automáticos de esta categoría"
                  />
                )}
                isOptionEqualToValue={(opt, val) => opt.id === val?.id}
                noOptionsText="Sin cuentas configuradas"
                clearText="Limpiar"
              />
            )}
          </Fields>
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setModal(null)}>Cancelar</Button>
          <Button variant="contained" onClick={handleSave} disabled={isPending || !form.nombre.trim()}>
            {isPending ? <CircularProgress size={18} /> : "Guardar"}
          </Button>
        </DialogActions>
      </Dialog>

      <Dialog open={!!modalMapeo} onClose={() => setModalMapeo(null)} maxWidth="xs" fullWidth>
        <DialogTitle>Cuenta contable — {modalMapeo?.nombre}</DialogTitle>
        <DialogContent>
          <Typography variant="body2" sx={{ mb: 2, opacity: 0.7 }}>
            Asigná la cuenta del plan contable que corresponde a esta categoría del sistema para tu empresa.
            Se usa en la generación automática de asientos al confirmar un movimiento.
          </Typography>
          <Autocomplete
            fullWidth
            options={planCuentas}
            getOptionLabel={(c) => c.codigo ? `${c.codigo} — ${c.descripcion}` : (c.descripcion || "")}
            value={mapeoValue}
            onChange={(_, val) => setMapeoValue(val)}
            renderInput={(params) => <TextField {...params} label="Cuenta contable" size="small" autoFocus />}
            isOptionEqualToValue={(opt, val) => opt.id === val?.id}
            noOptionsText="Sin cuentas configuradas"
            clearText="Quitar mapeo"
          />
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setModalMapeo(null)}>Cancelar</Button>
          <Button
            variant="contained"
            onClick={handleGuardarMapeo}
            disabled={upsertMapeo.isPending}
          >
            {upsertMapeo.isPending ? <CircularProgress size={18} /> : "Guardar"}
          </Button>
        </DialogActions>
      </Dialog>

      <Dialog open={!!confirmDelete} onClose={() => setConfirmDelete(null)} maxWidth="xs" fullWidth>
        <DialogTitle>Confirmar eliminación</DialogTitle>
        <DialogContent>
          <Typography>
            ¿Eliminar la categoría <strong>{confirmDelete?.nombre}</strong>? Esta acción no se puede deshacer.
          </Typography>
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setConfirmDelete(null)}>Cancelar</Button>
          <Button variant="contained" color="error" onClick={handleDelete} disabled={deleteCat.isPending}>
            {deleteCat.isPending ? <CircularProgress size={18} /> : "Eliminar"}
          </Button>
        </DialogActions>
      </Dialog>
    </Container>
  );
};

const Container = styled.div`padding: 24px; height: 100%; overflow-y: auto;`;
const PageHeader = styled.div`display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 20px;`;
const TableWrap = styled.div`background: ${({ theme }) => theme.bg2}; border: 1px solid ${({ theme }) => theme.color2}; border-radius: 10px; overflow: hidden;`;
const ScrollX = styled.div`overflow-x: auto;`;
const StyledTable = styled.table`width: 100%; border-collapse: collapse; min-width: 560px;`;
const Th = styled.th`background: ${({ theme }) => theme.bg3}; color: ${({ theme }) => theme.text2}; padding: 10px 14px; text-align: left; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.4px; border-bottom: 1px solid ${({ theme }) => theme.color2}; white-space: nowrap;`;
const Td = styled.td`padding: 10px 14px; border-bottom: 1px solid ${({ theme }) => theme.color2}; font-size: 13px;`;
const Tr = styled.tr`&:last-child td { border-bottom: none; } &:hover { background: ${({ theme }) => theme.bg3}; }`;
const Fields = styled.div`display: flex; flex-direction: column; gap: 16px; margin-top: 8px;`;
