import { useEffect, useMemo, useState } from 'react';
import { Box, Button, Paper, TextField, Typography, MenuItem, Chip } from '@mui/material';
import { useAuth } from '../../../context/AuthContext';
import CategoriesApi from '../../../api/CategoriesApi';
import TagTypeApi from '../../../api/TagTypeApi';
import { jwtDecode } from 'jwt-decode';

function slugify(s) {
  return (s || '')
    .normalize('NFKD').replace(/[\u0300-\u036f]/g, '')
    .toLowerCase().trim()
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/^-+|-+$/g, '');
}

function extractTenantId(token) {
  try {
    const payload = jwtDecode(token);
    const t = payload?.tenant;
    if (Array.isArray(t)) {
      const hex = t.find(x => typeof x === 'string' && /^[0-9a-f]{24}$/i.test(x));
      return hex || (typeof t[0] === 'string' ? t[0] : '');
    }
    if (typeof t === 'string') return t;
  } catch { }
  return '';
}

function formatDateSafe(value) {
  if (!value) return '—';
  // Accept Date instance, ISO string, or numeric timestamp
  const d = value instanceof Date ? value : new Date(value);
  if (Number.isNaN(d.getTime())) return '—';
  // Treat placeholder/default dates as empty
  const year = d.getUTCFullYear();
  if (year <= 1971) return '—';
  return new Intl.DateTimeFormat(undefined, {
    year: 'numeric',
    month: 'short',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit'
  }).format(d);
}

export default function AddOrEditCategoryForm({ onAdd, initialData, onCancel, materials: materialsProp = [], initialMaterialNames = [] }) {
  const { user } = useAuth();
  const token = user?.thalosToken || localStorage.getItem('thalosToken');
  const api = useMemo(() => new CategoriesApi(token), [token]);
  const tagTypeApi = useMemo(() => new TagTypeApi(token), [token]);

  const [types, setTypes] = useState([]);
  const [allTags, setAllTags] = useState([]);

const tagLabelById = useMemo(() => {
  const map = {};
  for (const t of allTags) {
    const key = t._id;
    map[key] = t.tagName || t.name || key;
  }
  return map;
}, [allTags]);

  const [form, setForm] = useState({
    _id: '',
    id: '',
    tenantId: '',
    tagName: '',
    typeId: '',
    parentTagId: [],
    slug: '',
    displayOrder: 0,
    icon: '',
    status: 'Active',
    createdAt: null,
    createdBy: null,
    updatedAt: null,
    updatedBy: null,
  });

  // cargar tipos (Tag Types) y tags para selects
  useEffect(() => {
    (async () => {
      try {
        // Load all tag types from TagTypeApi
        const typesResp = await tagTypeApi.getAll();
        setTypes(Array.isArray(typesResp) ? typesResp : []);

        // Load all existing tags (used to resolve parentTagId -> labels for Material)
        const tags = typeof api.getAll === 'function' ? await api.getAll() : [];
        setAllTags(Array.isArray(tags) ? tags : []);
      } catch (e) {
        console.error('Failed to load tag types or tags', e);
        setTypes([]);
        setAllTags([]);
      }
    })();
  }, [tagTypeApi, api]);

  // When editing: if we received material names from the grid, map them to IDs once allTags are loaded.
  useEffect(() => {
    if (!Array.isArray(initialMaterialNames) || initialMaterialNames.length === 0) return;
    // If parentTagId already has values (ids), do not override.
    if (Array.isArray(form.parentTagId) && form.parentTagId.length > 0) return;
    if (!Array.isArray(allTags) || allTags.length === 0) return;

    // Build a case-insensitive name -> id map
    const nameToId = new Map(
      allTags.map(t => {
        const _id = t._id;
        const label = (t.tagName || t.name || '').toLowerCase();
        return [label, _id];
      })
    );

    const ids = initialMaterialNames
      .map(n => (typeof n === 'string' ? n.toLowerCase() : ''))
      .map(lower => nameToId.get(lower))
      .filter(Boolean);

    if (ids.length > 0) {
      setForm(prev => ({ ...prev, parentTagId: ids }));
    }
  }, [initialMaterialNames, allTags]);

  // set inicial
  useEffect(() => {
    if (initialData) {
      setForm({
        _id: initialData._id,
        id: initialData.id,
        tenantId: initialData.tenantId || extractTenantId(token) || '',
        tagName: initialData.tagName || initialData.name || '',
        typeId: initialData.typeId || '',
        parentTagId: Array.isArray(initialData.parentTagId) ? initialData.parentTagId : [],
        slug: initialData.slug || slugify(initialData.tagName || initialData.name || ''),
        displayOrder: Number(initialData.displayOrder ?? 0),
        icon: initialData.icon || '',
        status: initialData.status || 'Active',
        createdAt: initialData.createdAt ?? null,
        createdBy: initialData.createdBy ?? null,
        updatedAt: initialData.updatedAt ?? null,
        updatedBy: initialData.updatedBy ?? null,
      });
    } else {
      setForm({
        _id: '',
        id: '',
        tenantId: extractTenantId(token) || '',
        tagName: '',
        typeId: '',
        parentTagId: [],
        slug: '',
        displayOrder: 0,
        icon: '',
        status: 'Active',
        createdAt: null,
        createdBy: null,
        updatedAt: null,
        updatedBy: null,
      });
    }
  }, [initialData]);

  const isEdit = Boolean(form._id);
  const isAdd = !isEdit;

  const setVal = (name, value) => setForm(p => ({ ...p, [name]: value }));

  const handleChange = (e) => {
    const { name, value } = e.target;
    setVal(name, value);
    if (name === 'tagName' && !form._id) {
      setVal('slug', slugify(value));
    }
  };

  const handleSubmit = async () => {
    try {
      const tenantId = extractTenantId(token);

      if (!form.tagName?.trim()) throw new Error('Tag name is required');
      if (!form.typeId) throw new Error('Type is required');
      if (!form.icon?.trim()) throw new Error('Icon is required');
      if (!tenantId) throw new Error('TenantId not found in token');

      const base = {
        id: form.id?.trim() || undefined,
        tagName: form.tagName.trim(),
        typeId: form.typeId,
        parentTagId: form.parentTagId,
        slug: form.slug.trim() || slugify(form.tagName),
        displayOrder: Number(form.displayOrder) || 0,
        icon: form.icon.trim(),
        status: form.status || 'Active',
        tenantId, // requerido por backend (400 si falta)
      };

      if (form._id) {
        const idForUpdate = Boolean(form._id) ? String(form._id) : null;
        if (!idForUpdate) throw new Error('Missing _id for update');
        const payload = {
          _id: idForUpdate,
          ...base,
        };
        console.log('[CategoryForm] SUBMIT (edit) with _id:', idForUpdate, 'payload:', payload);
        await api.update(payload);
      } else {
        await api.create(base);
      }

      // Ensure the parent refresh (loadData) happens before closing the dialog
      if (onAdd) {
        await onAdd();
      }
    } catch (e) {
      console.error('Submit category failed:', e);
      alert(e.message || 'Submit failed');
    }
  };

  const handleDelete = async () => {
    try {
      const idToUse = form._id;
      if (!idToUse) throw new Error('Missing _id to delete');
      console.debug('[CategoryForm] DELETE with _id:', idToUse);
      await api.changeStatus({ id: idToUse, status: 'Inactive' });
      if (onAdd) {
        await onAdd();
      }
    } catch (e) {
      console.error('Delete category failed:', e);
      alert(e.message || 'Delete failed');
    }
  };

  return (
    <Paper sx={{ p: 2 }}>
      <Typography variant="subtitle1" sx={{ mb: 2 }}>
        {form._id ? 'Edit Category' : 'Add Category'}
      </Typography>

      {isAdd && (
        <TextField
          name="tenantId"
          label="Tenant Id"
          value={form.tenantId}
          fullWidth
          sx={{ mb: 2 }}
          InputProps={{ readOnly: true }}
        />
      )}

      <TextField
        name="tagName"
        label="Name"
        value={form.tagName}
        onChange={handleChange}
        fullWidth
        sx={{ mb: 2 }}
        required
      />

      <TextField
        name="typeId"
        label="Category"
        value={form.typeId}
        onChange={handleChange}
        select
        fullWidth
        sx={{ mb: 2 }}
        required
      >
        {types.map((t) => {
          const value = t._id;
          const label = t.typeName || value;
          return (
            <MenuItem key={value} value={value}>
              {label}
            </MenuItem>
          );
        })}
      </TextField>

      <TextField
        name="parentTagId"
        label="Material"
        value={form.parentTagId}
        onChange={(e) => {
          // For MUI Select multiple, e.target.value is an array of selected IDs
          const val = e.target.value;
          setVal('parentTagId', Array.isArray(val) ? val : []);
        }}
        select
        SelectProps={{
          multiple: true,
          renderValue: (selected) => (
            <Box sx={{ display: 'flex', gap: 0.5, flexWrap: 'wrap' }}>
              {selected.map((id) => (
                <Chip key={id} label={tagLabelById[id] || id} size="small" />
              ))}
            </Box>
          ),
        }}
        fullWidth
        sx={{ mb: 2 }}
      >
        {allTags.map((t) => {
          const value = t._id;
          const label = t.tagName || t.name || value;
          return (
            <MenuItem key={value} value={value}>
              {label}
            </MenuItem>
          );
        })}
      </TextField>

      <TextField
        name="slug"
        label="Slug"
        value={form.slug}
        onChange={handleChange}
        fullWidth
        sx={{ mb: 2 }}
      />

      <TextField
        name="displayOrder"
        label="Display order"
        type="number"
        value={form.displayOrder}
        onChange={handleChange}
        fullWidth
        sx={{ mb: 2 }}
      />

      <TextField
        name="icon"
        label="Icon URL"
        value={form.icon}
        onChange={handleChange}
        fullWidth
        sx={{ mb: 2 }}
        required
      />

      <TextField
        name="status"
        label="Status"
        value={form.status}
        onChange={handleChange}
        select
        fullWidth
        sx={{ mb: 2 }}
      >
        <MenuItem value="Active">Active</MenuItem>
        <MenuItem value="Inactive">Inactive</MenuItem>
      </TextField>

      {form._id ? (
        <Box sx={{ display: 'grid', gridTemplateColumns: { xs: '1fr', md: '1fr 1fr' }, gap: 2, mt: 2 }}>
          <TextField label="Created At" value={formatDateSafe(form.createdAt)} InputProps={{ readOnly: true }} fullWidth />
          <TextField label="Created By" value={form.createdBy ?? '—'} InputProps={{ readOnly: true }} fullWidth />
          <TextField label="Updated At" value={formatDateSafe(form.updatedAt)} InputProps={{ readOnly: true }} fullWidth />
          <TextField label="Updated By" value={form.updatedBy ?? '—'} InputProps={{ readOnly: true }} fullWidth />
        </Box>
      ) : null}

      <Box display="flex" justifyContent="space-between" gap={1} mt={3}>
        {form._id ? (
          <Button color="error" onClick={handleDelete}>Delete</Button>
        ) : <span />}
        <Box sx={{ display: 'flex', gap: 1 }}>
          <Button onClick={onCancel} className="button-transparent">Cancel</Button>
          <Button variant="contained" onClick={handleSubmit} className="button-gold">Save</Button>
        </Box>
      </Box>
    </Paper>
  );
}
