import React, { useState, useEffect, useMemo, useCallback } from 'react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Textarea } from '@/components/ui/textarea';
import { Card, CardContent } from '@/components/ui/card';
import { Checkbox } from '@/components/ui/checkbox';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { Info, Package, RefreshCw } from 'lucide-react';
import { useApontamentosProducao } from '@/hooks/useApontamentosProducao';
import { usePecas } from '@/hooks/usePecas';
import { useOFs } from '@/hooks/useOFs';
import { useComponentesAgrupados } from '@/hooks/useComponentesAgrupados';
import { SeletorItensOtimizado } from './SeletorItensOtimizado';
import { toast } from 'sonner';

interface ItemDisponivel {
  id: string;
  marca: string;
  descricao: string;
  tipo: 'peca' | 'componente';
  quantidade_disponivel: number;
  processo_atual_permitido: number;
  nome_processo?: string;
}

// Cache local para manter seleções básicas do formulário
const formCache = {
  of_number: '',
  fase: '',
  processo_id: '',
  data_apontamento: new Date().toISOString().split('T')[0]
};

export const ApontamentoForm = () => {
  const [formData, setFormData] = useState({
    of_number: formCache.of_number || '',
    fase: formCache.fase || '',
    data_apontamento: formCache.data_apontamento || new Date().toISOString().split('T')[0],
    processo_id: formCache.processo_id || '',
    quantidade_produzida: '',
    observacoes: '',
    todas_disponiveis: false
  });

  const [itemSelecionado, setItemSelecionado] = useState<ItemDisponivel | null>(null);
  const [saving, setSaving] = useState(false);
  const [cacheValido, setCacheValido] = useState(false);

  const { criarApontamento, refetch, processos, apontamentos, loading: loadingApontamentos } = useApontamentosProducao();
  const { pecas, loading: loadingPecas } = usePecas();
  const { ofs } = useOFs();
  const { componentesAgrupados, loading: loadingComponentes } = useComponentesAgrupados(formData.of_number, formData.fase, pecas);

  // Buscar fases únicas da OF selecionada
  const fasesDisponiveis = useMemo(() => {
    if (!formData.of_number || !pecas.length) return [];
    return Array.from(
      new Set(
        pecas
          .filter(peca => peca.of_number === formData.of_number)
          .map(peca => peca.etapa_fase)
          .filter(Boolean)
      )
    ).sort();
  }, [pecas, formData.of_number]);

  // Processo selecionado atualmente
  const processoSelecionado = useMemo(() => {
    return processos.find(p => p.id === formData.processo_id) || null;
  }, [processos, formData.processo_id]);

  // Salvar cache quando seleções básicas mudam
  const updateCache = useCallback((updates: Partial<typeof formData>) => {
    Object.assign(formCache, updates);
    try {
      localStorage.setItem('apontamento_cache', JSON.stringify(formCache));
    } catch (e) {
      console.warn('Erro ao salvar cache:', e);
    }
  }, []);

  // Carregar cache inicial
  useEffect(() => {
    const savedCache = localStorage.getItem('apontamento_cache');
    if (savedCache) {
      try {
        const parsed = JSON.parse(savedCache);
        Object.assign(formCache, parsed);
        setFormData(prev => ({
          ...prev,
          of_number: formCache.of_number || '',
          fase: formCache.fase || '',
          processo_id: formCache.processo_id || '',
          data_apontamento: formCache.data_apontamento || new Date().toISOString().split('T')[0]
        }));
        setCacheValido(true);
      } catch (error) {
        console.log('Erro ao carregar cache:', error);
      }
    }
  }, []);

  // Cálculo reativo de peças e componentes disponíveis para o processo selecionado
  const itensDisponiveis = useMemo(() => {
    const { of_number, fase, processo_id } = formData;

    if (!of_number || !fase || !processo_id || !pecas.length) {
      return { pecasDisponiveis: [], componentesDisponiveis: [] };
    }

    const ordemProcesso = processoSelecionado?.ordem || 1;
    const nomeProcesso = processoSelecionado?.nome || `${ordemProcesso}`;

    // Reordenar processos para identificar sequencialidade
    const processosOrdenados = [...processos].sort((a, b) => a.ordem - b.ordem);
    const indexAtual = processosOrdenados.findIndex(p => p.id === processo_id);
    const procAtual = processosOrdenados[indexAtual];

    // 1. Peças da OF e Fase selecionadas
    const pecasDaFase = pecas.filter(
      p => p.of_number === of_number && p.etapa_fase === fase
    );

    const pecasDisponiveis: ItemDisponivel[] = [];

    pecasDaFase.forEach(peca => {
      // Calcular quanto já foi apontado desta peça neste processo
      const totalApontadoAtual = apontamentos
        .filter(a => a.tipo_apontamento === 'peca' && a.peca_id === peca.id && a.processo_id === processo_id)
        .reduce((sum, a) => sum + (Number(a.quantidade_produzida) || 0), 0);

      let qtdDisponivelParaEntrar = Number(peca.quantidade) || 0;

      // Regra: peças sem componentes não passam por solda
      if (!peca.tem_componentes && procAtual && procAtual.nome.toLowerCase().includes('solda')) {
        qtdDisponivelParaEntrar = 0;
      } else if (indexAtual > 0) {
        // Encontrar processo anterior válido
        let processoAnteriorValido = null;
        for (let i = indexAtual - 1; i >= 0; i--) {
          const p = processosOrdenados[i];
          if (!peca.tem_componentes && p.nome.toLowerCase().includes('solda')) {
            continue; // Pula a solda na busca do processo anterior para peças simples
          }
          processoAnteriorValido = p;
          break;
        }

        if (processoAnteriorValido) {
           qtdDisponivelParaEntrar = apontamentos
              .filter(a => a.tipo_apontamento === 'peca' && a.peca_id === peca.id && a.processo_id === processoAnteriorValido.id)
              .reduce((sum, a) => sum + (Number(a.quantidade_produzida) || 0), 0);
        }
      }

      const saldoDisponivel = Math.max(0, qtdDisponivelParaEntrar - totalApontadoAtual);

      if (saldoDisponivel > 0) {
        pecasDisponiveis.push({
          id: peca.id,
          marca: peca.marca,
          descricao: peca.descricao || '',
          tipo: 'peca',
          quantidade_disponivel: saldoDisponivel,
          processo_atual_permitido: ordemProcesso,
          nome_processo: nomeProcesso
        });
      }
    });

    // 2. Componentes da OF e Fase selecionadas
    const componentesDisponiveis: ItemDisponivel[] = [];

    if (componentesAgrupados && componentesAgrupados.length > 0) {
      componentesAgrupados.forEach(comp => {
        let qtdDisponivelParaEntrarComp = Number(comp.quantidade_total) || 0;

        if (indexAtual > 0) {
           const processoAnteriorValido = processosOrdenados[indexAtual - 1];
           if (processoAnteriorValido) {
              qtdDisponivelParaEntrarComp = apontamentos
                .filter(a => a.tipo_apontamento === 'componente' && comp.componente_ids.includes(a.componente_id || '') && a.processo_id === processoAnteriorValido.id)
                .reduce((sum, a) => sum + (Number(a.quantidade_produzida) || 0), 0);
           }
        }

        const totalApontadoComp = apontamentos
          .filter(a => a.tipo_apontamento === 'componente' && comp.componente_ids.includes(a.componente_id || '') && a.processo_id === processo_id)
          .reduce((sum, a) => sum + (Number(a.quantidade_produzida) || 0), 0);

        const saldoComp = Math.max(0, qtdDisponivelParaEntrarComp - totalApontadoComp);

        if (saldoComp > 0) {
          componentesDisponiveis.push({
            id: comp.componente_ids[0] || '',
            marca: comp.marca_componente,
            descricao: comp.descricao || comp.perfil || '',
            tipo: 'componente',
            quantidade_disponivel: saldoComp,
            processo_atual_permitido: ordemProcesso,
            nome_processo: nomeProcesso
          });
        }
      });
    }

    return { pecasDisponiveis, componentesDisponiveis };
  }, [formData, pecas, apontamentos, processoSelecionado, componentesAgrupados, processos]);

  // Sincronizar item selecionado caso não exista mais na lista disponível
  useEffect(() => {
    if (itemSelecionado) {
      const listaAtual = itemSelecionado.tipo === 'peca' 
        ? itensDisponiveis.pecasDisponiveis 
        : itensDisponiveis.componentesDisponiveis;
      
      const itemAindaExiste = listaAtual.find(i => i.id === itemSelecionado.id);
      if (!itemAindaExiste) {
        setItemSelecionado(null);
        setFormData(prev => ({ ...prev, quantidade_produzida: '', todas_disponiveis: false }));
      } else if (itemAindaExiste.quantidade_disponivel !== itemSelecionado.quantidade_disponivel) {
        setItemSelecionado(itemAindaExiste);
      }
    }
  }, [itensDisponiveis, itemSelecionado]);

  // Auto-preenchimento da quantidade quando "todas disponíveis" é marcado
  useEffect(() => {
    if (formData.todas_disponiveis && itemSelecionado) {
      setFormData(prev => ({
        ...prev,
        quantidade_produzida: itemSelecionado.quantidade_disponivel.toString()
      }));
    }
  }, [formData.todas_disponiveis, itemSelecionado]);

  const handleBatchSelect = async (items: ItemDisponivel[], tipo: 'peca' | 'componente') => {
    if (items.length === 0) {
      toast.error('Nenhum item disponível para registro em lote');
      return;
    }

    const totalItens = items.length;
    const tipoTexto = tipo === 'peca' ? 'peças' : 'componentes';
    
    const confirmacao = window.confirm(
      `Deseja registrar ${totalItens} ${tipoTexto} com suas respectivas quantidades totais disponíveis?\n\n` +
      `Total de itens: ${totalItens}\n` +
      `Processo: ${processoSelecionado?.nome || 'N/A'}`
    );

    if (!confirmacao) return;

    setSaving(true);
    let sucessos = 0;
    let erros = 0;

    try {
      for (const item of items) {
        try {
          const apontamentoData: Parameters<typeof criarApontamento>[0] = {
            of_number: formData.of_number,
            tipo_apontamento: item.tipo,
            processo_id: formData.processo_id,
            quantidade_produzida: item.quantidade_disponivel,
            data_apontamento: formData.data_apontamento,
            observacoes: `Registro em lote - ${tipoTexto}`
          };

          if (item.tipo === 'componente') {
            apontamentoData.componente_id = item.id;
          } else {
            apontamentoData.peca_id = item.id;
          }

          const result = await criarApontamento(apontamentoData);
          
          if (result.success) {
            sucessos++;
          } else {
            erros++;
          }
        } catch (error) {
          erros++;
          console.error(`Erro ao processar ${item.marca}:`, error);
        }
      }

      if (sucessos > 0) {
        toast.success(`${sucessos} ${tipoTexto} registradas com sucesso!${erros > 0 ? ` (${erros} com erro)` : ''}`);
        await refetch();
        resetFormForNewEntry();
      } else {
        toast.error(`Erro ao registrar ${tipoTexto} em lote`);
      }

    } catch (error) {
      console.error('Erro no registro em lote:', error);
      toast.error('Erro inesperado no registro em lote');
    } finally {
      setSaving(false);
    }
  };

  const handleOFChange = (ofNumber: string) => {
    const updates = {
      of_number: ofNumber,
      fase: '',
      processo_id: '',
      quantidade_produzida: '',
      todas_disponiveis: false
    };
    setFormData(prev => ({ ...prev, ...updates }));
    updateCache({ of_number: ofNumber, fase: '', processo_id: '' });
    setItemSelecionado(null);
  };

  const handleFaseChange = (fase: string) => {
    const updates = {
      fase: fase,
      processo_id: '',
      quantidade_produzida: '',
      todas_disponiveis: false
    };
    setFormData(prev => ({ ...prev, ...updates }));
    updateCache({ fase: fase, processo_id: '' });
    setItemSelecionado(null);
  };

  const handleProcessoChange = (processoId: string) => {
    const updates = {
      processo_id: processoId,
      quantidade_produzida: '',
      todas_disponiveis: false
    };
    setFormData(prev => ({ ...prev, ...updates }));
    updateCache({ processo_id: processoId });
    setItemSelecionado(null);
  };

  const handleItemSelect = (item: ItemDisponivel) => {
    setItemSelecionado(item);
    setFormData(prev => ({
      ...prev,
      quantidade_produzida: '',
      todas_disponiveis: false
    }));
  };

  const handleQuantidadeChange = (value: string) => {
    const quantidade = parseInt(value);
    
    if (itemSelecionado && quantidade > itemSelecionado.quantidade_disponivel) {
      toast.error(`Quantidade não pode ser maior que ${itemSelecionado.quantidade_disponivel} unidades disponíveis`);
      return;
    }
    
    setFormData(prev => ({ 
      ...prev, 
      quantidade_produzida: value,
      todas_disponiveis: false
    }));
  };

  const resetFormForNewEntry = () => {
    setItemSelecionado(null);
    setFormData(prev => ({
      ...prev,
      quantidade_produzida: '',
      observacoes: '',
      todas_disponiveis: false
    }));
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    
    if (!itemSelecionado || !formData.processo_id || !formData.quantidade_produzida) {
      toast.error('Preencha todos os campos obrigatórios');
      return;
    }

    const quantidade = parseInt(formData.quantidade_produzida);
    
    if (isNaN(quantidade) || quantidade <= 0 || quantidade > itemSelecionado.quantidade_disponivel) {
      toast.error('Quantidade inválida');
      return;
    }

    setSaving(true);
    
    try {
      const apontamentoData: Parameters<typeof criarApontamento>[0] = {
        of_number: formData.of_number,
        tipo_apontamento: itemSelecionado.tipo,
        processo_id: formData.processo_id,
        quantidade_produzida: quantidade,
        data_apontamento: formData.data_apontamento,
        observacoes: formData.observacoes || undefined
      };

      if (itemSelecionado.tipo === 'componente') {
        apontamentoData.componente_id = itemSelecionado.id;
      } else {
        apontamentoData.peca_id = itemSelecionado.id;
      }

      const result = await criarApontamento(apontamentoData);

      if (result.success) {
        toast.success('Apontamento registrado com sucesso!');
        await refetch();
        resetFormForNewEntry();
      }
    } catch (error) {
      console.error('Erro no submit:', error);
      toast.error('Erro ao registrar apontamento');
    } finally {
      setSaving(false);
    }
  };

  const limparCache = () => {
    localStorage.removeItem('apontamento_cache');
    Object.assign(formCache, {
      of_number: '',
      fase: '',
      processo_id: '',
      data_apontamento: new Date().toISOString().split('T')[0]
    });
    setFormData({
      of_number: '',
      fase: '',
      data_apontamento: new Date().toISOString().split('T')[0],
      processo_id: '',
      quantidade_produzida: '',
      observacoes: '',
      todas_disponiveis: false
    });
    setItemSelecionado(null);
    setCacheValido(false);
    toast.success('Cache limpo com sucesso!');
  };

  const isLoadingItens = loadingPecas || loadingApontamentos || loadingComponentes;

  return (
    <form onSubmit={handleSubmit} className="space-y-6">
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
        <div className="space-y-4">
          {/* Cache status */}
          {cacheValido && (
            <Alert>
              <Info className="h-4 w-4" />
              <AlertDescription className="flex items-center justify-between">
                <span>Seleções anteriores foram restauradas do cache</span>
                <Button
                  type="button"
                  variant="outline"
                  size="sm"
                  onClick={limparCache}
                  className="ml-2"
                >
                  <RefreshCw className="h-3 w-3 mr-1" />
                  Limpar
                </Button>
              </AlertDescription>
            </Alert>
          )}

          {/* Campos de seleção básicos */}
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div>
              <Label htmlFor="of">Ordem de Fabricação *</Label>
              <Select value={formData.of_number} onValueChange={handleOFChange}>
                <SelectTrigger>
                  <SelectValue placeholder="Selecione a OF" />
                </SelectTrigger>
                <SelectContent>
                  {ofs.map((of) => (
                    <SelectItem key={of.id} value={of.num_of}>
                      {of.num_of} - {of.descritivo}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            {formData.of_number && (
              <div>
                <Label htmlFor="fase">Fase *</Label>
                <Select value={formData.fase} onValueChange={handleFaseChange}>
                  <SelectTrigger>
                    <SelectValue placeholder="Selecione a fase" />
                  </SelectTrigger>
                  <SelectContent>
                    {fasesDisponiveis.map((fase) => (
                      <SelectItem key={fase} value={fase}>
                        {fase}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
            )}
          </div>

          {formData.fase && (
            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
              <div>
                <Label htmlFor="data">Data do Apontamento *</Label>
                <Input
                  id="data"
                  type="date"
                  value={formData.data_apontamento}
                  onChange={(e) => {
                    const newDate = e.target.value;
                    setFormData(prev => ({ ...prev, data_apontamento: newDate }));
                    updateCache({ data_apontamento: newDate });
                  }}
                />
              </div>

              <div>
                <Label>Processo *</Label>
                <Select value={formData.processo_id} onValueChange={handleProcessoChange}>
                  <SelectTrigger>
                    <SelectValue placeholder="Selecione o processo" />
                  </SelectTrigger>
                  <SelectContent>
                    {processos.map((processo) => (
                      <SelectItem key={processo.id} value={processo.id}>
                        {processo.ordem}. {processo.nome}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
            </div>
          )}

          {/* Informação sobre o processo */}
          {processoSelecionado && (
            <Alert>
              <Info className="h-4 w-4" />
              <AlertDescription>
                {`Processo: ${processoSelecionado.ordem}. ${processoSelecionado.nome}. Selecione as peças ou componentes com saldo pendente para apontar.`}
              </AlertDescription>
            </Alert>
          )}

          {/* Seletor de itens otimizado com funcionalidade de lote */}
          {formData.processo_id && (
            <div className="max-h-96 overflow-y-auto">
              <SeletorItensOtimizado
                pecasDisponiveis={itensDisponiveis.pecasDisponiveis}
                componentesDisponiveis={itensDisponiveis.componentesDisponiveis}
                itemSelecionado={itemSelecionado}
                onItemSelect={handleItemSelect}
                onBatchSelect={handleBatchSelect}
                loading={isLoadingItens}
              />
            </div>
          )}

          {/* Quantidade produzida */}
          {itemSelecionado && (
            <div>
              <Label htmlFor="quantidade">Quantidade Produzida *</Label>
              <div className="flex items-center space-x-2">
                <Input
                  id="quantidade"
                  type="number"
                  min="1"
                  max={itemSelecionado.quantidade_disponivel}
                  placeholder="0"
                  value={formData.quantidade_produzida}
                  onChange={(e) => handleQuantidadeChange(e.target.value)}
                  disabled={formData.todas_disponiveis}
                />
                <div className="flex items-center space-x-2">
                  <Checkbox
                    id="todas-disponiveis"
                    checked={formData.todas_disponiveis}
                    onCheckedChange={(checked) => setFormData(prev => ({ 
                      ...prev, 
                      todas_disponiveis: !!checked,
                      quantidade_produzida: checked ? itemSelecionado.quantidade_disponivel.toString() : ''
                    }))}
                  />
                  <Label htmlFor="todas-disponiveis" className="text-sm whitespace-nowrap">
                    todas ({itemSelecionado.quantidade_disponivel})
                  </Label>
                </div>
              </div>
            </div>
          )}

          <div>
            <Label htmlFor="observacoes">Observações</Label>
            <Textarea
              id="observacoes"
              placeholder="Observações sobre o apontamento..."
              value={formData.observacoes}
              onChange={(e) => setFormData(prev => ({ ...prev, observacoes: e.target.value }))}
              rows={3}
            />
          </div>
        </div>

        {/* Card de informações do item selecionado */}
        <div className="space-y-4">
          <Card className="bg-muted/50 h-fit">
            <CardContent className="p-4">
              <h4 className="font-medium flex items-center gap-2 mb-3">
                <Package className="h-4 w-4" />
                Informações do Item Selecionado
              </h4>
              {!itemSelecionado ? (
                <div className="text-sm text-muted-foreground">
                  Selecione um item para ver as informações ou use os botões para registro em lote
                </div>
              ) : (
                <div className="space-y-2 text-sm">
                  <div><strong>Tipo:</strong> {itemSelecionado.tipo === 'componente' ? 'Componente' : 'Peça'}</div>
                  <div><strong>Marca:</strong> {itemSelecionado.marca}</div>
                  <div><strong>OF:</strong> {formData.of_number}</div>
                  <div><strong>Fase:</strong> {formData.fase}</div>
                  <div><strong>Processo:</strong> {processoSelecionado ? `${processoSelecionado.ordem}. ${processoSelecionado.nome}` : 'N/A'}</div>
                  <div><strong>Descrição:</strong> {itemSelecionado.descricao || 'N/A'}</div>
                  <div><strong>Quantidade Disponível:</strong> {itemSelecionado.quantidade_disponivel} unidades</div>
                </div>
              )}
            </CardContent>
          </Card>

          {/* Botões de ação */}
          <div className="flex justify-end space-x-2">
            {formData.of_number && formData.fase && formData.processo_id && (
              <Button 
                type="button"
                variant="outline"
                onClick={resetFormForNewEntry}
                disabled={saving}
              >
                Novo Item
              </Button>
            )}
            <Button 
              type="submit" 
              disabled={saving || !itemSelecionado || !formData.processo_id || isLoadingItens} 
              className="min-w-32"
            >
              {saving ? 'Salvando...' : 'Registrar Apontamento'}
            </Button>
          </div>
        </div>
      </div>
    </form>
  );
};
