import { useEffect, useMemo, useState } from 'react';
import { apiRequest } from '../../../shared/services/apiClient';
import { getCurrentUser } from '../../auth/services/sessionService';
import { listContactProfiles } from '../../chat/services/contactProfileService';
import { DataPanel } from './DataPanel';
import { listTemplates } from '../services/templateService';

const inputStyle = {
  width: '100%',
  border: '1px solid var(--color-border)',
  borderRadius: 10,
  padding: '0.85rem 0.9rem',
  background: '#fff',
  color: 'var(--color-text)',
  fontWeight: 600,
};

function getUserId(user) {
  const value = user?.databaseId || user?.id;
  const numeric = Number(value);
  return Number.isFinite(numeric) ? numeric : null;
}

function normalizePhoneToChatId(value) {
  const digits = String(value || '').replace(/\D/g, '');
  if (!digits) return '';
  return `${digits}@c.us`;
}

function getPhoneFromChatId(chatId) {
  return String(chatId || '').split('@')[0].replace(/\D/g, '');
}

function normalizeContact(contact) {
  const phone = String(contact.phone || getPhoneFromChatId(contact.chat_id)).replace(/\D/g, '');
  return {
    id: contact.chat_id || normalizePhoneToChatId(phone),
    name: contact.name || phone || 'Contato sem nome',
    company: contact.company || '',
    phone,
    chatId: contact.chat_id || normalizePhoneToChatId(phone),
  };
}

function renderPreview(content, variables) {
  const name = variables?.nome || 'colaborador';
  return String(content || '')
    .replace(/\{nome\}/gi, name || 'colaborador')
    .replace(/\{cliente\}/gi, name || 'colaborador')
    .replace(/\{data\}/gi, variables?.data || '{data}')
    .replace(/\{link\}/gi, variables?.link || '{link}')
    .replace(/\{variavel\}/gi, variables?.variavel || '{variavel}')
    .replace(/\{variável\}/gi, variables?.variavel || '{variável}');
}

async function startAttendance(payload) {
  return apiRequest('/whatsapp/start-attendance', {
    method: 'POST',
    body: JSON.stringify(payload),
    fallbackMessage: 'Falha ao enviar disparo.',
  });
}

export function MassMessagePanel({
  areas,
  managedAreaNames = [],
  mode = 'admin',
  isMobile = false,
}) {
  const currentUserId = getUserId(getCurrentUser());
  const isAdmin = mode === 'admin';
  const visibleAreaNames = isAdmin ? [] : managedAreaNames;
  const [templates, setTemplates] = useState([]);
  const [contacts, setContacts] = useState([]);
  const [selectedAreaId, setSelectedAreaId] = useState('');
  const [selectedTemplateId, setSelectedTemplateId] = useState('');
  const [defaultName, setDefaultName] = useState('colaborador');
  const [templateDate, setTemplateDate] = useState('');
  const [templateLink, setTemplateLink] = useState('');
  const [templateCustomVariable, setTemplateCustomVariable] = useState('');
  const [numbersText, setNumbersText] = useState('');
  const [contactSearch, setContactSearch] = useState('');
  const [selectedContactIds, setSelectedContactIds] = useState([]);
  const [isSending, setIsSending] = useState(false);
  const [results, setResults] = useState([]);
  const [status, setStatus] = useState('');

  useEffect(() => {
    let isMounted = true;

    listTemplates()
      .then((data) => {
        if (!isMounted) return;
        const approved = Array.isArray(data)
          ? data.filter((template) => {
              const isApproved = template.status === 'approved';
              const isManaged = !visibleAreaNames.length || visibleAreaNames.includes(template.area_nome);
              return isApproved && isManaged;
            })
          : [];
        setTemplates(approved);
        setSelectedTemplateId((current) => current || (approved[0]?.id ? String(approved[0].id) : ''));
      })
      .catch((error) => {
        if (isMounted) setStatus(error.message);
      });

    return () => {
      isMounted = false;
    };
  }, [visibleAreaNames.join('|')]);

  useEffect(() => {
    let isMounted = true;

    listContactProfiles()
      .then((data) => {
        if (!isMounted) return;
        setContacts(Array.isArray(data) ? data.map(normalizeContact).filter((contact) => contact.phone) : []);
      })
      .catch((error) => {
        if (isMounted) setStatus(error.message);
      });

    return () => {
      isMounted = false;
    };
  }, []);

  const selectedTemplate = templates.find((template) => String(template.id) === String(selectedTemplateId));
  const filteredTemplates = useMemo(() => {
    if (!selectedAreaId) return templates;
    return templates.filter((template) => String(template.area_id || '') === String(selectedAreaId));
  }, [templates, selectedAreaId]);

  const numbers = useMemo(
    () =>
      numbersText
        .split(/\r?\n|,|;/)
        .map((item) => item.trim())
        .filter(Boolean),
    [numbersText],
  );

  const selectedContacts = useMemo(
    () => contacts.filter((contact) => selectedContactIds.includes(contact.id)),
    [contacts, selectedContactIds],
  );

  const filteredContacts = useMemo(() => {
    const search = contactSearch.trim().toLowerCase();
    if (!search) return contacts;
    return contacts.filter((contact) =>
      `${contact.name} ${contact.company} ${contact.phone}`.toLowerCase().includes(search),
    );
  }, [contacts, contactSearch]);

  const recipients = useMemo(() => {
    const items = [];
    const seen = new Set();

    numbers.forEach((number) => {
      const chatId = normalizePhoneToChatId(number);
      if (!chatId || seen.has(chatId)) return;
      seen.add(chatId);
      items.push({
        id: chatId,
        number,
        chatId,
        name: defaultName,
      });
    });

    return items;
  }, [defaultName, numbers]);

  useEffect(() => {
    if (selectedTemplate && filteredTemplates.some((template) => String(template.id) === String(selectedTemplateId))) {
      return;
    }
    setSelectedTemplateId(filteredTemplates[0]?.id ? String(filteredTemplates[0].id) : '');
  }, [filteredTemplates, selectedTemplate, selectedTemplateId]);

  function toggleContact(contact) {
    const phone = String(contact.phone || '').replace(/\D/g, '');
    if (!phone) return;

    setSelectedContactIds((current) => {
      const isSelected = current.includes(contact.id);
      return isSelected ? current.filter((id) => id !== contact.id) : [...current, contact.id];
    });

    setNumbersText((current) => {
      const currentNumbers = current
        .split(/\r?\n|,|;/)
        .map((item) => item.trim())
        .filter(Boolean);
      const exists = currentNumbers.some((item) => String(item).replace(/\D/g, '') === phone);
      const nextNumbers = exists
        ? currentNumbers.filter((item) => String(item).replace(/\D/g, '') !== phone)
        : [...currentNumbers, phone];
      return nextNumbers.join('\n');
    });
  }

  function clearSelectedContacts() {
    const selectedPhones = new Set(selectedContacts.map((contact) => contact.phone));
    setSelectedContactIds([]);
    setNumbersText((current) =>
      current
        .split(/\r?\n|,|;/)
        .map((item) => item.trim())
        .filter(Boolean)
        .filter((item) => !selectedPhones.has(String(item).replace(/\D/g, '')))
        .join('\n'),
    );
  }

  async function sendSelectedRecipients() {
    if (!currentUserId) {
      setStatus('Não foi possível identificar o usuário logado.');
      return;
    }
    if (!selectedTemplateId) {
      setStatus('Selecione um template aprovado.');
      return;
    }
    if (!recipients.length) {
      setStatus('Informe ao menos um número ou selecione contatos da agenda.');
      return;
    }

    setIsSending(true);
    setResults([]);
    setStatus('');

    const nextResults = [];
    for (const recipient of recipients) {
      if (!recipient.chatId) {
        nextResults.push({ number: recipient.number, status: 'erro', detail: 'Número inválido' });
        continue;
      }

      try {
        await startAttendance({
          to: recipient.chatId,
          templateId: Number(selectedTemplateId),
          userId: currentUserId,
          areaId: selectedTemplate?.area_id || null,
          variables: {
            nome: defaultName,
            cliente: defaultName,
            data: templateDate,
            link: templateLink,
            variavel: templateCustomVariable,
            'variável': templateCustomVariable,
          },
        });
        nextResults.push({
          number: recipient.number,
          status: 'enviado',
          detail: `${recipient.name || 'Contato'} - template enviado e atendimento iniciado`,
        });
      } catch (error) {
        nextResults.push({ number: recipient.number, status: 'erro', detail: error.message });
      }
      setResults([...nextResults]);
    }

    setStatus(`Disparo finalizado: ${nextResults.filter((item) => item.status === 'enviado').length} enviados.`);
    setIsSending(false);
  }

  return (
    <DataPanel
      title="Disparo em massa"
      description="Envie templates aprovados para uma lista de colaboradores. Após o envio, a conversa aguarda resposta do cliente."
    >
      <div
        style={{
          display: 'grid',
          gridTemplateColumns: isMobile ? '1fr' : 'minmax(0, 1fr) minmax(320px, 0.85fr)',
          gap: '1rem',
        }}
      >
        <div style={{ display: 'grid', gap: '0.85rem' }}>
          <label style={{ display: 'grid', gap: '0.4rem' }}>
            <span style={{ fontWeight: 700 }}>Especialidade</span>
            <select value={selectedAreaId} onChange={(event) => setSelectedAreaId(event.target.value)} style={inputStyle}>
              <option value="">Todas as especialidades</option>
              {areas
                .filter((area) => isAdmin || !managedAreaNames.length || managedAreaNames.includes(area.nome))
                .map((area) => (
                  <option key={area.id} value={area.id}>
                    {area.nome}
                  </option>
                ))}
            </select>
          </label>

          <label style={{ display: 'grid', gap: '0.4rem' }}>
            <span style={{ fontWeight: 700 }}>Template aprovado</span>
            <select value={selectedTemplateId} onChange={(event) => setSelectedTemplateId(event.target.value)} style={inputStyle}>
              <option value="">Selecione</option>
              {filteredTemplates.map((template) => (
                <option key={template.id} value={template.id}>
                  {template.name}
                </option>
              ))}
            </select>
          </label>

          <label style={{ display: 'grid', gap: '0.4rem' }}>
            <span style={{ fontWeight: 700 }}>Nome usado no preview</span>
            <input value={defaultName} onChange={(event) => setDefaultName(event.target.value)} style={inputStyle} />
          </label>

          <div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : 'repeat(3, minmax(0, 1fr))', gap: '0.85rem' }}>
            <label style={{ display: 'grid', gap: '0.4rem' }}>
              <span style={{ fontWeight: 700 }}>Data</span>
              <input value={templateDate} onChange={(event) => setTemplateDate(event.target.value)} placeholder="Ex: 26/05/2026" style={inputStyle} />
            </label>
            <label style={{ display: 'grid', gap: '0.4rem' }}>
              <span style={{ fontWeight: 700 }}>Link</span>
              <input value={templateLink} onChange={(event) => setTemplateLink(event.target.value)} placeholder="https://..." style={inputStyle} />
            </label>
            <label style={{ display: 'grid', gap: '0.4rem' }}>
              <span style={{ fontWeight: 700 }}>Variável</span>
              <input value={templateCustomVariable} onChange={(event) => setTemplateCustomVariable(event.target.value)} placeholder="Valor livre" style={inputStyle} />
            </label>
          </div>

          <label style={{ display: 'grid', gap: '0.4rem' }}>
            <span style={{ fontWeight: 700 }}>Números manuais</span>
            <textarea
              rows={8}
              value={numbersText}
              onChange={(event) => setNumbersText(event.target.value)}
              placeholder="5511999999999&#10;5511888888888"
              style={{ ...inputStyle, resize: 'vertical', lineHeight: 1.5 }}
            />
          </label>

          <button
            type="button"
            onClick={sendSelectedRecipients}
            disabled={isSending}
            style={{
              border: 'none',
              borderRadius: 12,
              padding: '0.95rem 1rem',
              background: 'linear-gradient(135deg, var(--color-primary), #0b5a86)',
              color: '#fff',
              fontWeight: 800,
              opacity: isSending ? 0.7 : 1,
            }}
          >
            {isSending ? 'Enviando...' : `Enviar para ${recipients.length || 0} contato(s)`}
          </button>

          {status ? <span style={{ color: 'var(--color-primary)', fontWeight: 800 }}>{status}</span> : null}
        </div>

        <aside style={{ display: 'grid', gap: '0.85rem', alignContent: 'start' }}>
          <article
            style={{
              border: '1px solid var(--color-border)',
              borderRadius: 14,
              padding: '1rem',
              background: '#fff',
              display: 'grid',
              gap: '0.75rem',
            }}
          >
            <div>
              <strong style={{ display: 'block' }}>Agenda de contatos</strong>
              <span style={{ color: 'var(--color-text-soft)', fontSize: '0.9rem' }}>
                Selecione contatos salvos para incluir no disparo.
              </span>
            </div>
            <input
              value={contactSearch}
              onChange={(event) => setContactSearch(event.target.value)}
              placeholder="Buscar por nome, empresa ou telefone"
              style={inputStyle}
            />
            <div style={{ display: 'grid', gap: '0.45rem', maxHeight: 260, overflowY: 'auto', paddingRight: '0.2rem' }}>
              {filteredContacts.map((contact) => {
                const isSelected = selectedContactIds.includes(contact.id);
                return (
                  <button
                    key={contact.id}
                    type="button"
                    onClick={() => toggleContact(contact)}
                    style={{
                      border: '1px solid',
                      borderColor: isSelected ? 'rgba(0, 164, 183, 0.36)' : 'var(--color-border)',
                      borderRadius: 10,
                      padding: '0.7rem',
                      background: isSelected ? 'rgba(0, 164, 183, 0.08)' : '#fff',
                      textAlign: 'left',
                      display: 'grid',
                      gap: '0.2rem',
                    }}
                  >
                    <strong>{contact.name}</strong>
                    <span style={{ color: 'var(--color-text-soft)', fontSize: '0.88rem' }}>
                      +{contact.phone}{contact.company ? ` · ${contact.company}` : ''}
                    </span>
                  </button>
                );
              })}
              {!filteredContacts.length ? (
                <span style={{ color: 'var(--color-text-soft)', fontWeight: 700 }}>
                  Nenhum contato encontrado na agenda.
                </span>
              ) : null}
            </div>
            {selectedContacts.length ? (
              <button
                type="button"
                onClick={clearSelectedContacts}
                style={{
                  border: '1px solid var(--color-border)',
                  borderRadius: 10,
                  padding: '0.75rem',
                  background: '#fff',
                  color: 'var(--color-primary)',
                  fontWeight: 800,
                }}
              >
                Limpar seleção ({selectedContacts.length})
              </button>
            ) : null}
          </article>

          <article
            style={{
              border: '1px solid rgba(0, 164, 183, 0.24)',
              borderRadius: 14,
              padding: '1rem',
              background: 'rgba(0, 164, 183, 0.06)',
              lineHeight: 1.5,
            }}
          >
            <strong style={{ display: 'block', color: 'var(--color-primary)', marginBottom: '0.45rem' }}>
              Preview
            </strong>
            {selectedTemplate
              ? renderPreview(selectedTemplate.content, { nome: defaultName, data: templateDate, link: templateLink, variavel: templateCustomVariable })
              : 'Selecione um template aprovado.'}
          </article>

          <article
            style={{
              border: '1px solid var(--color-border)',
              borderRadius: 14,
              padding: '1rem',
              background: '#fff',
              color: 'var(--color-text-soft)',
              fontWeight: 700,
            }}
          >
            Destinatários no campo: {numbers.length}.
          </article>

          <div style={{ display: 'grid', gap: '0.55rem', maxHeight: 320, overflowY: 'auto' }}>
            {results.map((result) => (
              <div
                key={`${result.number}-${result.status}`}
                style={{
                  border: '1px solid var(--color-border)',
                  borderRadius: 10,
                  padding: '0.75rem',
                  background: result.status === 'enviado' ? 'rgba(16,185,129,0.08)' : 'rgba(181,31,31,0.08)',
                }}
              >
                <strong style={{ display: 'block' }}>{result.number}</strong>
                <span style={{ color: 'var(--color-text-soft)' }}>{result.detail}</span>
              </div>
            ))}
          </div>
        </aside>
      </div>
    </DataPanel>
  );
}
