import { Icon } from "@iconify/react";
import { Alert, Box, Button, Chip, IconButton, Paper, Stack, Tooltip, Typography } from "@mui/material";
import { useEffect, useMemo, useRef, useState } from "react";
import { toast } from "sonner";
import {
  actualizarFormatoBancario,
  crearFormatoBancario,
  eliminarFormatoBancario,
  getBancosRrhh,
  getFormatosBancarios,
} from "../../api/rrhh.service";
import { useConfirmDialog } from "../../hooks/useConfirmDialog";
import {
  Badge,
  Container,
  EmptyState,
  Field,
  FieldsGrid,
  Footer,
  FooterActionButton,
  FormHead,
  FormPanel,
  GhostButton,
  ListBody,
  ListPanel,
  RowActions,
  SectionTitle,
  TableWrap,
} from "../ui/FormShell";
import { SearchableSelect } from "../ui/SearchableSelect";
import { RRHHGuia } from "./_shared/RRHHGuia";
import { RRHHEmptyState } from "./_shared/RRHHEmptyState";
import { useRRHHContext } from "./_shared/RRHHContext";
import {
  construirPreview,
  EJEMPLO_FORMATO,
  FILTROS_AYUDA,
  VARIABLES_CABECERA_PIE,
  VARIABLES_DETALLE,
} from "./_shared/acreditacionTemplate";

const CAMPO_LABEL = {
  template_cabecera: "Cabecera",
  template_detalle: "Detalle",
  template_pie: "Pie",
};

const TIPO_OPTIONS = [
  { id: "DELIMITADO", label: "Delimitado (separador entre campos)" },
  { id: "POSICIONAL", label: "Posicional (campos de ancho fijo)" },
];
const ENCODING_OPTIONS = [
  { id: "UTF-8", label: "UTF-8" },
  { id: "ISO-8859-1", label: "ISO-8859-1 (Latin-1)" },
  { id: "ASCII", label: "ASCII" },
];

const EMPTY = {
  banco_id: "",
  nombre: "",
  encoding: "UTF-8",
  separador_lineas: "\\n",
  separador_campos: "",
  tipo_archivo: "DELIMITADO",
  tiene_cabecera: false,
  tiene_pie: false,
  template_cabecera: "",
  template_detalle: "{{cedula}};{{nombre_completo|upper|trunc:40}};{{cuenta_bancaria}};{{monto|num:0}}",
  template_pie: "",
  extension_archivo: "txt",
  descripcion: "",
  activo: true,
};

export function FormatosBancariosTab() {
  const { reloadPrereqs } = useRRHHContext();
  const { confirm, dialogs } = useConfirmDialog();
  const [data, setData] = useState([]);
  const [bancos, setBancos] = useState([]);
  const [loading, setLoading] = useState(false);
  const [editingId, setEditingId] = useState(null);
  const [form, setForm] = useState(EMPTY);
  // Para insertar variables en el textarea que esté enfocado.
  const textareaRefs = useRef({});
  const [activeField, setActiveField] = useState("template_detalle");

  const preview = useMemo(() => construirPreview(form), [form]);

  const load = async () => {
    try {
      setLoading(true);
      const [list, bancosResp] = await Promise.all([getFormatosBancarios(), getBancosRrhh()]);
      setData(list || []);
      setBancos(bancosResp || []);
    } catch {
      toast.error("Error al cargar formatos");
    } finally {
      setLoading(false);
    }
  };

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

  const handleEditar = (f) => {
    setEditingId(f.id);
    setForm({
      banco_id: f.banco_id,
      nombre: f.nombre,
      encoding: f.encoding || "UTF-8",
      separador_lineas: f.separador_lineas || "\\n",
      separador_campos: f.separador_campos || "",
      tipo_archivo: f.tipo_archivo || "DELIMITADO",
      tiene_cabecera: !!f.tiene_cabecera,
      tiene_pie: !!f.tiene_pie,
      template_cabecera: f.template_cabecera || "",
      template_detalle: f.template_detalle || "",
      template_pie: f.template_pie || "",
      extension_archivo: f.extension_archivo || "txt",
      descripcion: f.descripcion || "",
      activo: f.activo ?? true,
    });
  };

  const handleGuardar = async () => {
    if (!form.banco_id) return toast.error("Elegí el banco");
    if (!form.nombre.trim()) return toast.error("Indicá un nombre");
    if (!form.template_detalle.trim()) return toast.error("El template del detalle es obligatorio");
    try {
      const payload = {
        ...form,
        separador_campos: form.separador_campos || undefined,
        template_cabecera: form.tiene_cabecera ? form.template_cabecera : undefined,
        template_pie: form.tiene_pie ? form.template_pie : undefined,
        descripcion: form.descripcion || undefined,
      };
      if (editingId) {
        await actualizarFormatoBancario(editingId, payload);
        toast.success("Formato actualizado");
      } else {
        await crearFormatoBancario(payload);
        toast.success("Formato creado");
      }
      setForm(EMPTY);
      setEditingId(null);
      load();
      reloadPrereqs();
    } catch (error) {
      toast.error(error?.response?.data?.message || "Error al guardar");
    }
  };

  const handleEliminar = async (f) => {
    const ok = await confirm({
      title: "Eliminar formato",
      message: `¿Eliminar formato "${f.nombre}" del banco ${f.banco?.descripcion}?`,
      confirmText: "Eliminar",
      confirmColor: "error",
    });
    if (!ok) return;
    try {
      await eliminarFormatoBancario(f.id);
      toast.success("Formato eliminado");
      load();
      reloadPrereqs();
    } catch (error) {
      toast.error(error?.response?.data?.message || "No se pudo eliminar");
    }
  };

  const updateField = (k, v) => setForm((p) => ({ ...p, [k]: v }));

  // Inserta {{key}} en la posición del cursor del template activo (o al final).
  const insertarVariable = (key) => {
    let field = activeField;
    if (field === "template_cabecera" && !form.tiene_cabecera) field = "template_detalle";
    if (field === "template_pie" && !form.tiene_pie) field = "template_detalle";
    const snippet = `{{${key}}}`;
    const el = textareaRefs.current[field];
    const current = form[field] || "";
    if (el && typeof el.selectionStart === "number") {
      const start = el.selectionStart;
      const end = el.selectionEnd;
      const next = current.slice(0, start) + snippet + current.slice(end);
      updateField(field, next);
      requestAnimationFrame(() => {
        el.focus();
        const pos = start + snippet.length;
        el.setSelectionRange(pos, pos);
      });
    } else {
      updateField(field, current + snippet);
    }
  };

  const cargarEjemplo = () => {
    setForm((p) => ({ ...p, ...EJEMPLO_FORMATO }));
    toast.success("Plantilla de ejemplo cargada. Ajustala a tu banco y mirá la vista previa.");
  };

  const campoActivoLabel =
    CAMPO_LABEL[
      (activeField === "template_cabecera" && !form.tiene_cabecera) ||
      (activeField === "template_pie" && !form.tiene_pie)
        ? "template_detalle"
        : activeField
    ];

  const bancoOptions = bancos.map((b) => ({
    id: b.id,
    label: `${b.codigo ? b.codigo + " — " : ""}${b.descripcion}`,
  }));

  return (
    <Container>
      <RRHHGuia seccion="formatosBancarios" />
      <FormPanel>
        <FormHead>
          <SectionTitle>
            <Icon icon={editingId ? "lucide:edit-3" : "lucide:plus-circle"} />
            {editingId ? "Editar formato bancario" : "Nuevo formato bancario"}
          </SectionTitle>
          {editingId && (
            <GhostButton onClick={() => { setForm(EMPTY); setEditingId(null); }}>
              <Icon icon="lucide:x" /> Cancelar edición
            </GhostButton>
          )}
        </FormHead>

        <Alert
          severity="info"
          sx={{ mb: 2 }}
          action={
            <Button color="inherit" size="small" startIcon={<Icon icon="lucide:wand-2" width={15} />} onClick={cargarEjemplo}>
              Cargar ejemplo
            </Button>
          }
        >
          Cada banco usa su propio formato. Hacé clic en una variable para insertarla en el template, y mirá el resultado en la <strong>Vista previa</strong> de abajo. Si no sabés por dónde empezar, usá «Cargar ejemplo».
        </Alert>

        <FieldsGrid $cols={4}>
          <Field $span={2}>
            <label>Banco *</label>
            <SearchableSelect options={bancoOptions} value={form.banco_id}
              onChange={(id) => updateField("banco_id", id || "")} placeholder="Elegí un banco…" />
          </Field>
          <Field $span={2}>
            <label>Nombre del formato *</label>
            <input value={form.nombre} onChange={(e) => updateField("nombre", e.target.value)}
              placeholder="Ej: Continental — Acreditación nómina v2" />
          </Field>

          <Field>
            <label>Tipo de archivo *</label>
            <SearchableSelect options={TIPO_OPTIONS} value={form.tipo_archivo}
              onChange={(id) => updateField("tipo_archivo", id || "DELIMITADO")} clearable={false} />
          </Field>
          <Field>
            <label>Encoding</label>
            <SearchableSelect options={ENCODING_OPTIONS} value={form.encoding}
              onChange={(id) => updateField("encoding", id || "UTF-8")} clearable={false} />
          </Field>
          <Field>
            <label>Separador de líneas</label>
            <input value={form.separador_lineas}
              onChange={(e) => updateField("separador_lineas", e.target.value)}
              placeholder="\n o \r\n" />
          </Field>
          <Field>
            <label>Extensión de archivo</label>
            <input value={form.extension_archivo}
              onChange={(e) => updateField("extension_archivo", e.target.value)}
              placeholder="txt, csv, dat..." />
          </Field>

          <Field>
            <label>¿Incluye cabecera?</label>
            <SearchableSelect
              options={[{ id: "false", label: "No" }, { id: "true", label: "Sí" }]}
              value={form.tiene_cabecera ? "true" : "false"}
              onChange={(id) => updateField("tiene_cabecera", id === "true")} clearable={false} />
          </Field>
          <Field>
            <label>¿Incluye pie?</label>
            <SearchableSelect
              options={[{ id: "false", label: "No" }, { id: "true", label: "Sí" }]}
              value={form.tiene_pie ? "true" : "false"}
              onChange={(id) => updateField("tiene_pie", id === "true")} clearable={false} />
          </Field>
          <Field>
            <label>Activo</label>
            <SearchableSelect
              options={[{ id: "true", label: "Activo" }, { id: "false", label: "Inactivo" }]}
              value={form.activo ? "true" : "false"}
              onChange={(id) => updateField("activo", id === "true")} clearable={false} />
          </Field>
          <Field>
            <label>Separador de campos (delimitado)</label>
            <input value={form.separador_campos}
              onChange={(e) => updateField("separador_campos", e.target.value)}
              placeholder="; o , o \t" />
          </Field>

          <Field $span={4}>
            <Paper variant="outlined" sx={{ p: 1.5, bgcolor: "action.hover" }}>
              <Typography variant="caption" color="text.secondary">
                Insertá variables en: <strong>{campoActivoLabel}</strong> (hacé clic en el template donde querés escribir, luego en la variable)
              </Typography>
              <Typography variant="caption" display="block" sx={{ mt: 1, mb: 0.5, fontWeight: 600 }}>
                Datos de cada empleado (detalle)
              </Typography>
              <Stack direction="row" flexWrap="wrap" gap={0.5}>
                {VARIABLES_DETALLE.map((v) => (
                  <Tooltip key={v.key} title={`{{${v.key}}} · ej: ${v.ejemplo}`} enterDelay={300}>
                    <Chip size="small" label={v.label} onClick={() => insertarVariable(v.key)} sx={{ cursor: "pointer" }} />
                  </Tooltip>
                ))}
              </Stack>
              <Typography variant="caption" display="block" sx={{ mt: 1, mb: 0.5, fontWeight: 600 }}>
                Totales y empresa (cabecera / pie)
              </Typography>
              <Stack direction="row" flexWrap="wrap" gap={0.5}>
                {VARIABLES_CABECERA_PIE.map((v) => (
                  <Tooltip key={v.key} title={`{{${v.key}}} · ej: ${v.ejemplo}`} enterDelay={300}>
                    <Chip size="small" variant="outlined" label={v.label} onClick={() => insertarVariable(v.key)} sx={{ cursor: "pointer" }} />
                  </Tooltip>
                ))}
              </Stack>
              <Typography variant="caption" display="block" color="text.disabled" sx={{ mt: 1 }}>
                Filtros (agregá tras un <code>|</code>): {FILTROS_AYUDA.map((f) => `${f.key} (${f.desc})`).join(" · ")}
              </Typography>
            </Paper>
          </Field>

          {form.tiene_cabecera && (
            <Field $span={4}>
              <label>Template de la cabecera</label>
              <textarea value={form.template_cabecera}
                ref={(el) => { textareaRefs.current.template_cabecera = el; }}
                onFocus={() => setActiveField("template_cabecera")}
                onChange={(e) => updateField("template_cabecera", e.target.value)}
                placeholder="{{empresa_ruc}};NOMINA;{{periodo_anio}}-{{periodo_mes}};{{total_registros}}"
                rows={2} style={{ fontFamily: "monospace", fontSize: "0.85rem" }} />
            </Field>
          )}
          <Field $span={4}>
            <label>Template del detalle *</label>
            <textarea value={form.template_detalle}
              ref={(el) => { textareaRefs.current.template_detalle = el; }}
              onFocus={() => setActiveField("template_detalle")}
              onChange={(e) => updateField("template_detalle", e.target.value)}
              placeholder="{{cedula}};{{nombre_completo|upper|trunc:40}};{{cuenta_bancaria}};{{monto|num:0}}"
              rows={2} style={{ fontFamily: "monospace", fontSize: "0.85rem" }} />
          </Field>
          {form.tiene_pie && (
            <Field $span={4}>
              <label>Template del pie</label>
              <textarea value={form.template_pie}
                ref={(el) => { textareaRefs.current.template_pie = el; }}
                onFocus={() => setActiveField("template_pie")}
                onChange={(e) => updateField("template_pie", e.target.value)}
                placeholder="TOTAL;{{total_registros|pad0:6}};{{monto_total_centavos|pad0:15}}"
                rows={2} style={{ fontFamily: "monospace", fontSize: "0.85rem" }} />
            </Field>
          )}

          <Field $span={4}>
            <label>Vista previa (con datos de ejemplo)</label>
            <Box
              component="pre"
              sx={{
                m: 0,
                p: 1.5,
                minHeight: 64,
                maxHeight: 220,
                overflow: "auto",
                fontFamily: "monospace",
                fontSize: "0.82rem",
                lineHeight: 1.5,
                border: "1px solid",
                borderColor: "divider",
                borderRadius: 1,
                background: "rgba(0,0,0,0.06)",
                whiteSpace: "pre-wrap",
                wordBreak: "break-all",
              }}
            >
              {preview || "(Completá el template del detalle para ver la vista previa)"}
            </Box>
            <Typography variant="caption" color="text.disabled">
              Así se vería el archivo con 2 empleados de ejemplo. Verificá que coincida con la especificación de tu banco antes de generar.
            </Typography>
          </Field>
          <Field $span={4}>
            <label>Descripción</label>
            <input value={form.descripcion}
              onChange={(e) => updateField("descripcion", e.target.value)} />
          </Field>
        </FieldsGrid>

        <Footer>
          <FooterActionButton type="button" $variant="primary" onClick={handleGuardar}>
            <Icon icon={editingId ? "lucide:check-circle" : "lucide:plus"} />
            {editingId ? "Actualizar formato" : "Crear formato"}
          </FooterActionButton>
        </Footer>
      </FormPanel>

      <ListPanel>
        <ListBody>
          <SectionTitle><Icon icon="lucide:list" /> Formatos configurados</SectionTitle>
          {loading ? (
            <EmptyState>Cargando…</EmptyState>
          ) : data.length === 0 ? (
            <RRHHEmptyState
              icon="lucide:landmark"
              titulo="Sin formatos bancarios configurados"
              descripcion="Los formatos bancarios definen la estructura del archivo de acreditaciones que se envía al banco. Son obligatorios para generar acreditaciones automáticas."
              guiaSeccion="formatosBancarios"
            />
          ) : (
            <TableWrap>
              <table>
                <thead>
                  <tr>
                    <th>Banco</th>
                    <th>Nombre</th>
                    <th>Tipo</th>
                    <th>Encoding</th>
                    <th>Extensión</th>
                    <th>Estado</th>
                    <th style={{ textAlign: "center" }}>Acciones</th>
                  </tr>
                </thead>
                <tbody>
                  {data.map((f) => (
                    <tr key={f.id}>
                      <td>{f.banco?.descripcion || "—"}</td>
                      <td>{f.nombre}</td>
                      <td>{f.tipo_archivo}</td>
                      <td>{f.encoding}</td>
                      <td>{f.extension_archivo}</td>
                      <td>
                        <Badge $state={f.activo ? "ACTIVO" : "INACTIVO"}>
                          {f.activo ? "Activo" : "Inactivo"}
                        </Badge>
                      </td>
                      <td style={{ textAlign: "center" }}>
                        <RowActions>
                          <Tooltip title="Editar">
                            <IconButton size="small" onClick={() => handleEditar(f)}>
                              <Icon icon="lucide:pencil" width={16} />
                            </IconButton>
                          </Tooltip>
                          <Tooltip title="Eliminar">
                            <IconButton size="small" color="error" onClick={() => handleEliminar(f)}>
                              <Icon icon="lucide:trash-2" width={16} />
                            </IconButton>
                          </Tooltip>
                        </RowActions>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </TableWrap>
          )}
        </ListBody>
      </ListPanel>
      {dialogs}
    </Container>
  );
}
