import { Icon } from "@iconify/react";
import { Autocomplete, Avatar, Box, Button, CircularProgress, Dialog, DialogActions, DialogContent, DialogTitle, IconButton, TextField, Tooltip, Typography } from "@mui/material";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useEffect, useMemo, useRef, useState } from "react";
import { Controller, useForm } from "react-hook-form";
import { toast } from "sonner";
import styled, { keyframes } from "styled-components";
import { getReferenciales } from "../../../api/referenciales.service";
import { removeSucursalLogo, uploadSucursalLogo } from "../../../api/sucursales.service";
import { useEmpresa } from "../../../context/EmpresaContext";
import { useCreateSucursalMutation, useUpdateSucursalMutation } from "../../../tanstack/SucursalesStack";
import { FieldHint, InlineValidationBanner } from "../../_standards";

const spin = keyframes`to { transform: rotate(360deg); }`;
const Spinner = styled(Icon)`
  animation: ${spin} 1s linear infinite;
`;

const HeaderIcon = styled.div`
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 10px;
  background: ${(p) => p.theme.bg6 || "rgba(127,127,127,0.12)"};
  display: flex;
  align-items: center;
  justify-content: center;
  color: ${(p) => p.theme.primary || "#3b82f6"};
  flex-shrink: 0;
`;

const SectionTitle = styled(Typography)`
  && {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: ${(p) => p.theme.textSecondary || "#94a3b8"};
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.4rem;
  }
`;

export const SucursalFormDialog = ({ open, onClose, sucursal }) => {
  const { empresaId } = useEmpresa();
  const createMutation = useCreateSucursalMutation();
  const updateMutation = useUpdateSucursalMutation();
  const isEditing = !!sucursal;

  const { data: referenciales } = useQuery({
    queryKey: ["referenciales"],
    queryFn: getReferenciales,
    staleTime: 60 * 60 * 1000,
  });

  const paises = referenciales?.geografica?.paises || [];
  const departamentos = referenciales?.geografica?.departamentos || [];
  const ciudades = referenciales?.geografica?.ciudades || [];
  const distritos = referenciales?.geografica?.distritos || [];

  const {
    control,
    handleSubmit,
    reset,
    watch,
    formState: { errors },
  } = useForm({
    defaultValues: {
      punto_establecimiento: "",
      descripcion: "",
      nombre_fantasia: "",
      direccion: "",
      numero_casa: "0",
      pais_id: null,
      departamento_id: null,
      ciudad_id: null,
      distrito_id: null,
      telefono: "",
      email: "",
    },
  });

  // ── Logo propio de la sucursal ──────────────────────────────────
  // Sólo al editar: la subida necesita el id, que recién existe una vez creada.
  const queryClient = useQueryClient();
  const fileInputRef = useRef(null);
  const [logoPreview, setLogoPreview] = useState(null);
  const [logoSubiendo, setLogoSubiendo] = useState(false);

  const refrescarSucursales = () => {
    queryClient.invalidateQueries({ queryKey: ["sucursales"] });
    queryClient.invalidateQueries({ queryKey: ["empresa"] });
  };

  const handleLogoChange = async (e) => {
    const file = e.target.files?.[0];
    e.target.value = ""; // permite volver a elegir el mismo archivo
    if (!file || !sucursal?.id) return;

    if (!file.type.startsWith("image/")) {
      toast.error("Solo se permiten archivos de imagen");
      return;
    }
    if (file.size > 5 * 1024 * 1024) {
      toast.error("El logo no puede superar los 5MB");
      return;
    }

    const anterior = logoPreview;
    const reader = new FileReader();
    reader.onload = (ev) => setLogoPreview(ev.target.result);
    reader.readAsDataURL(file);

    setLogoSubiendo(true);
    try {
      const resp = await uploadSucursalLogo(sucursal.id, file);
      setLogoPreview(resp?.data?.logo || null);
      toast.success("Logo de la sucursal actualizado");
      refrescarSucursales();
    } catch (error) {
      setLogoPreview(anterior);
      toast.error(error.response?.data?.message || "Error al subir el logo");
    } finally {
      setLogoSubiendo(false);
    }
  };

  const handleLogoRemove = async () => {
    if (!sucursal?.id) return;
    const anterior = logoPreview;
    setLogoSubiendo(true);
    try {
      await removeSucursalLogo(sucursal.id);
      setLogoPreview(null);
      toast.success("La sucursal vuelve a usar el logo de la empresa");
      refrescarSucursales();
    } catch (error) {
      setLogoPreview(anterior);
      toast.error(error.response?.data?.message || "Error al quitar el logo");
    } finally {
      setLogoSubiendo(false);
    }
  };

  const selectedPais = watch("pais_id");
  const selectedDepartamento = watch("departamento_id");
  const selectedDistrito = watch("distrito_id");

  const filteredDepartamentos = useMemo(() => {
    if (!selectedPais) return departamentos;
    return departamentos.filter((d) => d.pais_id === selectedPais?.id);
  }, [departamentos, selectedPais]);

  const filteredDistritos = useMemo(() => {
    if (!selectedDepartamento) return [];
    return distritos.filter((d) => d.departamento_id === selectedDepartamento?.id);
  }, [distritos, selectedDepartamento]);

  const filteredCiudades = useMemo(() => {
    if (!selectedDistrito) return [];
    return ciudades.filter((c) => c.distrito_id === selectedDistrito?.id);
  }, [ciudades, selectedDistrito]);

  useEffect(() => {
    if (open) setLogoPreview(sucursal?.logo || null);
  }, [open, sucursal]);

  useEffect(() => {
    if (open) {
      if (sucursal) {
        const paisObj = paises.find((p) => p.id === sucursal.pais_id) || null;
        const deptoObj = departamentos.find((d) => d.id === sucursal.departamento_id) || null;
        const ciudadObj = ciudades.find((c) => c.id === sucursal.ciudad_id) || null;
        const distritoObj = distritos.find((d) => d.id === sucursal.distrito_id) || null;

        reset({
          punto_establecimiento: sucursal.punto_establecimiento || "",
          descripcion: sucursal.descripcion || "",
          nombre_fantasia: sucursal.nombre_fantasia || "",
          direccion: sucursal.direccion || "",
          numero_casa: sucursal.numero_casa || "0",
          pais_id: paisObj,
          departamento_id: deptoObj,
          ciudad_id: ciudadObj,
          distrito_id: distritoObj,
          telefono: sucursal.telefono || "",
          email: sucursal.email || "",
        });
      } else {
        const paraguayDefault = paises.find((p) => p.descripcion?.toLowerCase() === "paraguay");
        reset({
          punto_establecimiento: "",
          descripcion: "",
          nombre_fantasia: "",
          direccion: "",
          numero_casa: "0",
          pais_id: paraguayDefault || null,
          departamento_id: null,
          ciudad_id: null,
          distrito_id: null,
          telefono: "",
          email: "",
        });
      }
    }
  }, [open, sucursal, reset, paises, departamentos, ciudades, distritos]);

  const onSubmit = (data) => {
    const payload = {
      empresa_id: empresaId,
      punto_establecimiento: data.punto_establecimiento,
      descripcion: data.descripcion,
      // Vacío = null y no "": el KUDE cae al nombre de fantasía de la empresa
      // cuando la sucursal no tiene uno propio.
      nombre_fantasia: data.nombre_fantasia?.trim() || null,
      direccion: data.direccion,
      numero_casa: data.numero_casa || "0",
      pais_id: data.pais_id?.id,
      departamento_id: data.departamento_id?.id,
      ciudad_id: data.ciudad_id?.id,
      distrito_id: data.distrito_id?.id,
      telefono: data.telefono || undefined,
      email: data.email || undefined,
    };

    if (isEditing) {
      updateMutation.mutate({ id: sucursal.id, data: payload }, { onSuccess: onClose });
    } else {
      createMutation.mutate(payload, { onSuccess: onClose });
    }
  };

  const isPending = createMutation.isPending || updateMutation.isPending;

  const errorMessages = Object.values(errors)
    .map((e) => e?.message)
    .filter(Boolean);

  return (
    <Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth PaperProps={{ sx: { borderRadius: 2 } }}>
      <DialogTitle
        sx={{
          display: "flex",
          alignItems: "center",
          gap: 1.25,
          py: 1.75,
        }}
      >
        <HeaderIcon>
          <Icon icon={isEditing ? "lucide:edit-3" : "lucide:building-2"} width={20} />
        </HeaderIcon>
        <Box sx={{ flex: 1, minWidth: 0 }}>
          <Typography variant="subtitle1" fontWeight={700} lineHeight={1.2}>
            {isEditing ? "Editar Sucursal" : "Nueva Sucursal"}
          </Typography>
          <Typography variant="caption" color="text.secondary">
            {isEditing ? "Actualiza los datos del establecimiento" : "Registra un nuevo establecimiento habilitado en SET"}
          </Typography>
        </Box>
        <IconButton onClick={onClose} size="small">
          <Icon icon="lucide:x" width={18} />
        </IconButton>
      </DialogTitle>

      <form onSubmit={handleSubmit(onSubmit)}>
        <DialogContent dividers sx={{ display: "flex", flexDirection: "column", gap: 2 }}>
          {errorMessages.length > 0 && <InlineValidationBanner errors={errorMessages} />}

          <Box>
            <SectionTitle>
              <Icon icon="lucide:hash" width={14} /> Identificación
            </SectionTitle>
            <Box sx={{ display: "flex", gap: 2 }}>
              <Controller
                name="punto_establecimiento"
                control={control}
                rules={{
                  required: "Punto establecimiento es requerido",
                  pattern: {
                    value: /^\d{3}$/,
                    message: "Debe ser exactamente 3 dígitos",
                  },
                }}
                render={({ field }) => (
                  <FieldHint
                    {...field}
                    label="Punto Establecimiento"
                    sx={{ width: 180 }}
                    placeholder="001"
                    hint="3 dígitos. Ej: 001. Debe coincidir con SET."
                    error={!!errors.punto_establecimiento}
                    disabled={isEditing}
                  />
                )}
              />
              <Controller
                name="descripcion"
                control={control}
                rules={{ required: "Descripción es requerida" }}
                render={({ field }) => <TextField {...field} label="Descripción / Nombre" size="small" fullWidth placeholder="Casa Matriz" error={!!errors.descripcion} />}
              />
            </Box>
            {/* Nombre comercial: campo aparte de la descripción porque la
                descripción es el nombre interno (el que se elige en los
                combos) y no siempre es la marca con la que el cliente
                reconoce al local. Encabeza el ticket y los KUDE A4. Mismo
                criterio que el logo: vacío = se usa el de la empresa. */}
            <Controller
              name="nombre_fantasia"
              control={control}
              render={({ field }) => (
                <FieldHint
                  {...field}
                  label="Nombre de fantasía"
                  fullWidth
                  sx={{ mt: 1.5 }}
                  placeholder="Agogo Regalos"
                  hint="Nombre comercial que encabeza los comprobantes de esta sucursal. Vacío: se usa el de la empresa."
                />
              )}
            />
          </Box>

          <Box>
            <SectionTitle>
              <Icon icon="lucide:map-pin" width={14} /> Ubicación
            </SectionTitle>
            <Box sx={{ display: "flex", flexDirection: "column", gap: 1.5 }}>
              <Box sx={{ display: "flex", gap: 2 }}>
                <Controller
                  name="direccion"
                  control={control}
                  rules={{ required: "Dirección es requerida" }}
                  render={({ field }) => <TextField {...field} label="Dirección" size="small" fullWidth error={!!errors.direccion} />}
                />
                <Controller
                  name="numero_casa"
                  control={control}
                  rules={{ required: "Número es requerido" }}
                  render={({ field }) => <TextField {...field} label="Nro. Casa" size="small" sx={{ width: 120 }} error={!!errors.numero_casa} />}
                />
              </Box>

              <Controller
                name="pais_id"
                control={control}
                rules={{ required: "País es requerido" }}
                render={({ field: { onChange, value } }) => (
                  <Autocomplete
                    options={paises}
                    getOptionLabel={(opt) => opt?.descripcion || ""}
                    value={value}
                    onChange={(_, v) => onChange(v)}
                    size="small"
                    renderInput={(params) => <TextField {...params} label="País" error={!!errors.pais_id} />}
                  />
                )}
              />

              <Controller
                name="departamento_id"
                control={control}
                rules={{ required: "Departamento es requerido" }}
                render={({ field: { onChange, value } }) => (
                  <Autocomplete
                    options={filteredDepartamentos}
                    getOptionLabel={(opt) => opt?.descripcion || ""}
                    value={value}
                    onChange={(_, v) => onChange(v)}
                    size="small"
                    renderInput={(params) => <TextField {...params} label="Departamento" error={!!errors.departamento_id} />}
                  />
                )}
              />

              <Controller
                name="distrito_id"
                control={control}
                rules={{ required: "Distrito es requerido" }}
                render={({ field: { onChange, value } }) => (
                  <Autocomplete
                    options={filteredDistritos}
                    getOptionLabel={(opt) => opt?.descripcion || ""}
                    value={value}
                    onChange={(_, v) => onChange(v)}
                    size="small"
                    disabled={!selectedDepartamento}
                    renderInput={(params) => <TextField {...params} label="Distrito" error={!!errors.distrito_id} />}
                  />
                )}
              />

              <Controller
                name="ciudad_id"
                control={control}
                rules={{ required: "Ciudad es requerida" }}
                render={({ field: { onChange, value } }) => (
                  <Autocomplete
                    options={filteredCiudades}
                    getOptionLabel={(opt) => opt?.descripcion || ""}
                    value={value}
                    onChange={(_, v) => onChange(v)}
                    size="small"
                    disabled={!selectedDistrito}
                    renderInput={(params) => <TextField {...params} label="Ciudad" error={!!errors.ciudad_id} />}
                  />
                )}
              />
            </Box>
          </Box>

          <Box>
            <SectionTitle>
              <Icon icon="lucide:phone" width={14} /> Contacto
            </SectionTitle>
            <Box sx={{ display: "flex", gap: 2 }}>
              <Controller name="telefono" control={control} render={({ field }) => <TextField {...field} label="Teléfono" size="small" fullWidth placeholder="0210000000" />} />
              <Controller
                name="email"
                control={control}
                rules={{
                  pattern: {
                    value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
                    message: "Email inválido",
                  },
                }}
                render={({ field }) => <TextField {...field} label="Email" size="small" fullWidth placeholder="sucursal@empresa.com" error={!!errors.email} />}
              />
            </Box>
          </Box>

          {/* Logo propio: para empresas cuyos locales tienen identidad visual
              distinta. Sin uno, el KUDE sale con el logo de la empresa. */}
          <Box>
            <SectionTitle>
              <Icon icon="lucide:image" width={14} /> Logo de la sucursal
            </SectionTitle>

            {!isEditing ? (
              <Typography variant="caption" color="text.secondary">
                Vas a poder cargarlo al editar la sucursal, una vez creada.
              </Typography>
            ) : (
              <Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
                <Box sx={{ position: "relative", flexShrink: 0 }}>
                  <Avatar
                    src={logoPreview || undefined}
                    variant="rounded"
                    sx={{
                      width: 64,
                      height: 64,
                      bgcolor: "action.hover",
                      color: "text.secondary",
                      opacity: logoSubiendo ? 0.5 : 1,
                    }}
                  >
                    <Icon icon="lucide:store" width={26} />
                  </Avatar>
                  {logoSubiendo && (
                    <CircularProgress
                      size={26}
                      sx={{
                        position: "absolute",
                        top: "50%",
                        left: "50%",
                        mt: "-13px",
                        ml: "-13px",
                      }}
                    />
                  )}
                </Box>

                <Box sx={{ display: "flex", flexDirection: "column", gap: 0.75, minWidth: 0 }}>
                  <Typography variant="caption" color="text.secondary">
                    {logoPreview ? "Este logo se usa en las facturas emitidas desde esta sucursal." : "Sin logo propio: se usa el de la empresa."}
                  </Typography>
                  <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap" }}>
                    <Button size="small" variant="outlined" disabled={logoSubiendo} onClick={() => fileInputRef.current?.click()} startIcon={<Icon icon="lucide:upload" width={15} />}>
                      {logoPreview ? "Cambiar" : "Subir logo"}
                    </Button>
                    {logoPreview && (
                      <Tooltip title="Vuelve a usar el logo de la empresa">
                        <span>
                          <Button size="small" color="inherit" disabled={logoSubiendo} onClick={handleLogoRemove} startIcon={<Icon icon="lucide:trash-2" width={15} />}>
                            Quitar
                          </Button>
                        </span>
                      </Tooltip>
                    )}
                  </Box>
                  <Typography variant="caption" color="text.disabled">
                    PNG, JPG o WEBP · hasta 5MB
                  </Typography>
                </Box>

                <input type="file" ref={fileInputRef} onChange={handleLogoChange} accept="image/png,image/jpeg,image/jpg,image/webp" style={{ display: "none" }} />
              </Box>
            )}
          </Box>
        </DialogContent>

        <DialogActions sx={{ px: 3, py: 2 }}>
          <Button onClick={onClose} disabled={isPending} startIcon={<Icon icon="lucide:x" width={16} />}>
            Cancelar
          </Button>
          <Button
            type="submit"
            variant="contained"
            disabled={isPending}
            startIcon={isPending ? <Spinner icon="lucide:loader-2" width={16} /> : <Icon icon={isEditing ? "lucide:save" : "lucide:plus"} width={16} />}
          >
            {isPending ? "Guardando..." : isEditing ? "Actualizar" : "Crear"}
          </Button>
        </DialogActions>
      </form>
    </Dialog>
  );
};
