import { useState, useMemo, useEffect, useCallback } from "react";
import { format } from "date-fns";
import { ptBR } from "date-fns/locale";
import {
  DollarSign,
  TrendingUp,
  TrendingDown,
  Building2,
  User,
  Receipt,
  Filter,
  Calendar,
  Search,
  CalendarIcon,
  Loader2,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Calendar as CalendarComponent } from "@/components/ui/calendar";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  Pagination,
  PaginationContent,
  PaginationItem,
  PaginationLink,
  PaginationNext,
  PaginationPrevious,
} from "@/components/ui/pagination";
import { Badge } from "@/components/ui/badge";
import { personalAgent, FinancialIndicators, ExpenseItem, ExpensesResponse, ExpensesFilters, ExpenseCategory } from "@/services/personalAgent";
import { GlobalFunctions, TransferAreaProperties } from "@/GlobalFunctions";
import { toast } from "@/hooks/use-toast";

// Mapeamento de categoria_id para cores (cores padrão caso não tenha categoria)
const categoryColorMap: Record<number, string> = {
  1: "bg-orange-500/10 text-orange-600 border-orange-500/20", // Alimentação
  2: "bg-yellow-500/10 text-yellow-600 border-yellow-500/20", // Combustível
  3: "bg-purple-500/10 text-purple-600 border-purple-500/20", // Hospedagem
  4: "bg-blue-500/10 text-blue-600 border-blue-500/20", // Estacionamento
  5: "bg-indigo-500/10 text-indigo-600 border-indigo-500/20", // Pedágio
  6: "bg-cyan-500/10 text-cyan-600 border-cyan-500/20", // Transporte
};

// Função auxiliar para obter informações da categoria
const getCategoryInfo = (categoriaId: number | undefined | null, categories: ExpenseCategory[]) => {
  // Se não tem categoria_id válido, retorna padrão
  if (categoriaId === undefined || categoriaId === null || categoriaId === 0) {
    return {
      label: "Outros",
      color: "bg-gray-500/10 text-gray-600 border-gray-500/20",
    };
  }
  
  // Converte para número caso venha como string
  const id = typeof categoriaId === 'string' ? parseInt(categoriaId, 10) : categoriaId;
  
  // Busca a categoria na lista carregada
  const category = categories.find(cat => cat.id === id);
  
  // Se encontrou a categoria, usa o nome dela
  if (category) {
    const color = categoryColorMap[id] || "bg-gray-500/10 text-gray-600 border-gray-500/20";
    return {
      label: category.nome,
      color: color,
    };
  }
  
  // Se não encontrou mas tem ID válido, usa o ID com cor padrão
  const color = categoryColorMap[id] || "bg-gray-500/10 text-gray-600 border-gray-500/20";
  return {
    label: `Categoria ${id}`,
    color: color,
  };
};

function formatCurrency(value: number) {
  return new Intl.NumberFormat("pt-BR", {
    style: "currency",
    currency: "BRL",
  }).format(value);
}

function formatDateTime(dateTimeString: string) {
  // Formata "2026-01-14 10:38:57" para Date
  const date = new Date(dateTimeString.replace(" ", "T"));
  return {
    date: date.toLocaleDateString("pt-BR"),
    time: date.toLocaleTimeString("pt-BR", { hour: "2-digit", minute: "2-digit" }),
  };
}

export default function Financas() {
  const [searchTerm, setSearchTerm] = useState("");
  const [typeFilter, setTypeFilter] = useState<string>("all");
  const [categoryFilter, setCategoryFilter] = useState<string>("all"); // Agora será o ID da categoria ou "all"
  const [startDate, setStartDate] = useState<Date | undefined>(undefined);
  const [endDate, setEndDate] = useState<Date | undefined>(undefined);
  const [currentPage, setCurrentPage] = useState(1);
  const itemsPerPage = 10;
  
  // Estados para os indicadores financeiros da API
  const [loadingIndicators, setLoadingIndicators] = useState(true);
  const [indicators, setIndicators] = useState<FinancialIndicators | null>(null);
  
  // Estados para as despesas da API
  const [loadingExpenses, setLoadingExpenses] = useState(true);
  const [expensesData, setExpensesData] = useState<ExpensesResponse | null>(null);
  const [userEmail, setUserEmail] = useState<string>("");
  
  // Estados para as categorias da API
  const [loadingCategories, setLoadingCategories] = useState(true);
  const [categories, setCategories] = useState<ExpenseCategory[]>([]);

  // Carrega os indicadores financeiros da API
  useEffect(() => {
    const loadFinancialIndicators = async () => {
      try {
        setLoadingIndicators(true);
        
        // Obtém o email do usuário logado
        let userEmail = GlobalFunctions.getUsuarioLogado().email;
        
        // Se não tem email, tenta obter do Transfer Area como fallback
        if (!userEmail) {
          const transferEmail = GlobalFunctions.getTransferProperty(
            TransferAreaProperties.UsuarioEmail
          );
          if (transferEmail) {
            userEmail = transferEmail as string;
          }
        }
        
        // Se ainda não tem email, tenta obter do token novamente após refresh
        if (!userEmail) {
          try {
            await GlobalFunctions.getToken();
            await new Promise(resolve => setTimeout(resolve, 500));
            userEmail = GlobalFunctions.getUsuarioLogado().email;
          } catch (error) {
            console.error("Erro ao fazer refresh do token:", error);
          }
        }
        
        if (!userEmail) {
          console.error("Financas: Não foi possível obter email do usuário");
          toast({
            title: "Erro",
            description: "Email do usuário não encontrado. Por favor, faça login novamente.",
            variant: "destructive",
          });
          setLoadingIndicators(false);
          return;
        }
        
        // Busca os indicadores financeiros da API
        const response = await personalAgent.getFinancialIndicators(userEmail);
        
        if (response.success) {
          setIndicators(response);
        } else {
          throw new Error(response.message || "Erro ao carregar indicadores financeiros");
        }
      } catch (error: unknown) {
        console.error("Erro ao carregar indicadores financeiros:", error);
        const errorMessage = error instanceof Error ? error.message : String(error);
        toast({
          title: "Erro",
          description: errorMessage || "Erro ao carregar indicadores financeiros.",
          variant: "destructive",
        });
      } finally {
        setLoadingIndicators(false);
      }
    };
    
    loadFinancialIndicators();
  }, []);

  // Função auxiliar para obter o email do usuário
  const getUserEmail = async (): Promise<string | null> => {
    let email = GlobalFunctions.getUsuarioLogado().email;
    
    if (!email) {
      const transferEmail = GlobalFunctions.getTransferProperty(
        TransferAreaProperties.UsuarioEmail
      );
      if (transferEmail) {
        email = transferEmail as string;
      }
    }
    
    if (!email) {
      try {
        await GlobalFunctions.getToken();
        await new Promise(resolve => setTimeout(resolve, 500));
        email = GlobalFunctions.getUsuarioLogado().email;
      } catch (error) {
        console.error("Erro ao fazer refresh do token:", error);
      }
    }
    
    return email || null;
  };

  // Carrega as despesas da API
  const loadExpenses = useCallback(async (page: number = 1) => {
    const emailToUse = userEmail || await getUserEmail();
    if (!emailToUse) {
      setLoadingExpenses(false);
      return;
    }
    
    if (!userEmail && emailToUse) {
      setUserEmail(emailToUse);
    }

    try {
      setLoadingExpenses(true);
      
      // Prepara filtros para a API
      const filters: ExpensesFilters = {
        page,
        per_page: itemsPerPage,
      };
      
      if (searchTerm.trim()) {
        filters.descricao = searchTerm.trim();
      }
      
      if (categoryFilter !== "all") {
        // Usa o ID da categoria diretamente
        const categoriaId = parseInt(categoryFilter, 10);
        if (!isNaN(categoriaId)) {
          filters.categoria_id = categoriaId;
        }
      }
      
      if (startDate) {
        filters.data_inicial = format(startDate, "yyyy-MM-dd");
      }
      
      if (endDate) {
        filters.data_final = format(endDate, "yyyy-MM-dd");
      }
      
      const response = await personalAgent.getExpenses(emailToUse, filters);
      
      if (response.success) {
        // Garante que a resposta tenha estrutura válida mesmo quando não há dados
        const safeResponse: ExpensesResponse = {
          success: response.success,
          total_registros: response.total_registros || 0,
          total_paginas: response.total_paginas || 0,
          per_page: response.per_page || itemsPerPage,
          pagina_atual: response.pagina_atual || page,
          data: Array.isArray(response.data) 
            ? response.data.filter((item) => item && item.id && Object.keys(item).length > 0)
            : [],
        };
        setExpensesData(safeResponse);
      } else {
        throw new Error("Erro ao carregar despesas");
      }
    } catch (error: unknown) {
      console.error("Erro ao carregar despesas:", error);
      const errorMessage = error instanceof Error ? error.message : String(error);
      toast({
        title: "Erro",
        description: errorMessage || "Erro ao carregar despesas.",
        variant: "destructive",
      });
    } finally {
      setLoadingExpenses(false);
    }
  }, [userEmail, searchTerm, categoryFilter, startDate, endDate, itemsPerPage]);

  // Carrega o email do usuário e as categorias na montagem do componente
  useEffect(() => {
    const initData = async () => {
      // Carrega email do usuário
      const email = await getUserEmail();
      if (email) {
        setUserEmail(email);
      }
      
      // Carrega categorias
      try {
        setLoadingCategories(true);
        const categoriesData = await personalAgent.getCategories();
        setCategories(categoriesData);
      } catch (error) {
        console.error("Erro ao carregar categorias:", error);
        toast({
          title: "Aviso",
          description: "Não foi possível carregar as categorias. Usando categorias padrão.",
          variant: "default",
        });
      } finally {
        setLoadingCategories(false);
      }
    };
    initData();
  }, []);

  // Debounce para busca de descrição
  useEffect(() => {
    const timeoutId = setTimeout(() => {
      if (userEmail) {
        setCurrentPage(1); // Reseta para página 1 ao buscar
        loadExpenses(1);
      }
    }, 500); // Aguarda 500ms após parar de digitar

    return () => clearTimeout(timeoutId);
  }, [searchTerm, userEmail, loadExpenses]);

  // Carrega despesas quando os filtros ou página mudam (exceto searchTerm que tem debounce)
  useEffect(() => {
    if (userEmail) {
      loadExpenses(currentPage);
    }
  }, [currentPage, typeFilter, categoryFilter, startDate, endDate, userEmail, loadExpenses]);

  // Calculate totals - usa dados da API se disponível
  const totals = useMemo(() => {
    if (indicators && indicators.success) {
      return {
        total: parseFloat(indicators.total_despesas) || 0,
        corporate: parseFloat(indicators.total_corporativo) || 0,
        personal: parseFloat(indicators.total_pessoal) || 0,
      };
    }
    
    return { total: 0, personal: 0, corporate: 0 };
  }, [indicators]);

  // Filtra despesas por tipo (se necessário, já que a API pode não filtrar por tipo)
  const filteredExpenses = useMemo(() => {
    if (!expensesData || !expensesData.data || !Array.isArray(expensesData.data)) {
      return [];
    }
    
    // Filtra objetos vazios ou inválidos
    let expenses = expensesData.data.filter((expense) => {
      // Verifica se o expense é válido e tem propriedades necessárias
      // categoria_id pode ser opcional, então não validamos ele aqui
      return expense && 
             typeof expense === 'object' && 
             expense.id && 
             expense.descricao && 
             expense.data_hora &&
             expense.valor;
    });
    
    // Filtra por tipo se necessário (a API pode não ter esse filtro)
    if (typeFilter !== "all") {
      expenses = expenses.filter((expense) => expense.tipo === typeFilter);
    }
    
    return expenses;
  }, [expensesData, typeFilter]);

  const clearFilters = () => {
    setSearchTerm("");
    setTypeFilter("all");
    setCategoryFilter("all");
    setStartDate(undefined);
    setEndDate(undefined);
    setCurrentPage(1);
  };

  return (
    <div className="space-y-6 animate-fade-in">
      {/* Header */}
      <div>
        <h1 className="text-2xl font-bold gradient-text">Finanças</h1>
        <p className="text-muted-foreground mt-1">
          Análise de despesas pessoais e corporativas identificadas pelo agente
        </p>
      </div>

      {/* Indicators */}
      <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
        <Card className="metric-card">
          <CardContent className="p-5">
            <div className="flex items-center justify-between">
              <div>
                <p className="text-sm text-muted-foreground">Total de Despesas</p>
                {loadingIndicators ? (
                  <div className="flex items-center gap-2 mt-1">
                    <Loader2 className="w-4 h-4 animate-spin text-muted-foreground" />
                    <span className="text-sm text-muted-foreground">Carregando...</span>
                  </div>
                ) : (
                  <>
                    <p className="text-2xl font-bold mt-1">{formatCurrency(totals.total)}</p>
                  </>
                )}
              </div>
              <div className="w-12 h-12 rounded-xl bg-primary/10 flex items-center justify-center">
                <DollarSign className="w-6 h-6 text-primary" />
              </div>
            </div>
          </CardContent>
        </Card>

        <Card className="metric-card">
          <CardContent className="p-5">
            <div className="flex items-center justify-between">
              <div>
                <p className="text-sm text-muted-foreground">Despesas Corporativas</p>
                {loadingIndicators ? (
                  <div className="flex items-center gap-2 mt-1">
                    <Loader2 className="w-4 h-4 animate-spin text-muted-foreground" />
                    <span className="text-sm text-muted-foreground">Carregando...</span>
                  </div>
                ) : (
                  <>
                    <p className="text-2xl font-bold mt-1">{formatCurrency(totals.corporate)}</p>
                  </>
                )}
              </div>
              <div className="w-12 h-12 rounded-xl bg-secondary/10 flex items-center justify-center">
                <Building2 className="w-6 h-6 text-secondary" />
              </div>
            </div>
          </CardContent>
        </Card>

        <Card className="metric-card">
          <CardContent className="p-5">
            <div className="flex items-center justify-between">
              <div>
                <p className="text-sm text-muted-foreground">Despesas Pessoais</p>
                {loadingIndicators ? (
                  <div className="flex items-center gap-2 mt-1">
                    <Loader2 className="w-4 h-4 animate-spin text-muted-foreground" />
                    <span className="text-sm text-muted-foreground">Carregando...</span>
                  </div>
                ) : (
                  <>
                    <p className="text-2xl font-bold mt-1">{formatCurrency(totals.personal)}</p>
                  </>
                )}
              </div>
              <div className="w-12 h-12 rounded-xl bg-warning/10 flex items-center justify-center">
                <User className="w-6 h-6 text-warning" />
              </div>
            </div>
          </CardContent>
        </Card>
      </div>

      {/* Filters */}
      <Card>
        <CardHeader className="pb-3">
          <CardTitle className="text-base flex items-center gap-2">
            <Filter className="w-4 h-4" />
            Filtros
          </CardTitle>
        </CardHeader>
        <CardContent>
          <div className="flex flex-col gap-3">
            {/* First row: Search + Date filters */}
            <div className="flex flex-col md:flex-row gap-3">
              <div className="flex-1">
                <div className="relative">
                  <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
                  <Input
                    placeholder="Buscar por descrição..."
                    value={searchTerm}
                    onChange={(e) => {
                      setSearchTerm(e.target.value);
                      setCurrentPage(1);
                    }}
                    className="pl-9"
                  />
                </div>
              </div>
              <Popover>
                <PopoverTrigger asChild>
                  <Button
                    variant="outline"
                    className={cn(
                      "w-full md:w-[160px] justify-start text-left font-normal",
                      !startDate && "text-muted-foreground"
                    )}
                  >
                    <CalendarIcon className="mr-2 h-4 w-4" />
                    {startDate ? format(startDate, "dd/MM/yyyy") : "Data inicial"}
                  </Button>
                </PopoverTrigger>
                <PopoverContent className="w-auto p-0" align="start">
                  <CalendarComponent
                    mode="single"
                    selected={startDate}
                    onSelect={(date) => {
                      setStartDate(date);
                      setCurrentPage(1);
                    }}
                    locale={ptBR}
                    initialFocus
                    className={cn("p-3 pointer-events-auto")}
                  />
                </PopoverContent>
              </Popover>
              <Popover>
                <PopoverTrigger asChild>
                  <Button
                    variant="outline"
                    className={cn(
                      "w-full md:w-[160px] justify-start text-left font-normal",
                      !endDate && "text-muted-foreground"
                    )}
                  >
                    <CalendarIcon className="mr-2 h-4 w-4" />
                    {endDate ? format(endDate, "dd/MM/yyyy") : "Data final"}
                  </Button>
                </PopoverTrigger>
                <PopoverContent className="w-auto p-0" align="start">
                  <CalendarComponent
                    mode="single"
                    selected={endDate}
                    onSelect={(date) => {
                      setEndDate(date);
                      setCurrentPage(1);
                    }}
                    locale={ptBR}
                    disabled={(date) => startDate ? date < startDate : false}
                    initialFocus
                    className={cn("p-3 pointer-events-auto")}
                  />
                </PopoverContent>
              </Popover>
            </div>
            
            {/* Second row: Type + Category + Clear */}
            <div className="flex flex-col md:flex-row gap-3">
              <Select
                value={typeFilter}
                onValueChange={(value) => {
                  setTypeFilter(value);
                  setCurrentPage(1);
                }}
              >
                <SelectTrigger className="w-full md:w-[180px]">
                  <SelectValue placeholder="Tipo" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="all">Todos os tipos</SelectItem>
                  <SelectItem value="pessoal">Pessoal</SelectItem>
                  <SelectItem value="corporativo">Corporativo</SelectItem>
                </SelectContent>
              </Select>
              <Select
                value={categoryFilter}
                onValueChange={(value) => {
                  setCategoryFilter(value);
                  setCurrentPage(1);
                }}
                disabled={loadingCategories}
              >
                <SelectTrigger className="w-full md:w-[180px]">
                  <SelectValue placeholder={loadingCategories ? "Carregando..." : "Categoria"} />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="all">Todas categorias</SelectItem>
                  {categories.map((category) => (
                    <SelectItem key={category.id} value={category.id.toString()}>
                      {category.nome}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
              <Button variant="outline" onClick={clearFilters}>
                Limpar filtros
              </Button>
            </div>
          </div>
        </CardContent>
      </Card>

      {/* Table */}
      <Card>
        <CardHeader className="pb-3">
          <CardTitle className="text-base flex items-center gap-2">
            <Receipt className="w-4 h-4" />
            Registro de Despesas
          </CardTitle>
        </CardHeader>
        <CardContent>
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead className="w-[140px]">
                  <div className="flex items-center gap-1">
                    <Calendar className="w-3.5 h-3.5" />
                    Data/Hora
                  </div>
                </TableHead>
                <TableHead>Descrição</TableHead>
                <TableHead className="w-[120px]">Tipo</TableHead>
                <TableHead className="w-[130px]">Categoria</TableHead>
                <TableHead className="w-[120px] text-right">Valor</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {loadingExpenses ? (
                <TableRow>
                  <TableCell colSpan={5} className="text-center py-8">
                    <div className="flex items-center justify-center gap-2">
                      <Loader2 className="w-4 h-4 animate-spin text-muted-foreground" />
                      <span className="text-muted-foreground">Carregando despesas...</span>
                    </div>
                  </TableCell>
                </TableRow>
              ) : filteredExpenses.length === 0 ? (
                <TableRow>
                  <TableCell colSpan={5} className="text-center py-8 text-muted-foreground">
                    {expensesData && expensesData.total_registros === 0 
                      ? "Nenhuma despesa encontrada." 
                      : "Nenhuma despesa encontrada com os filtros aplicados."}
                  </TableCell>
                </TableRow>
              ) : (
                filteredExpenses.map((expense) => {
                  // Validação adicional para garantir que o expense é válido
                  if (!expense || !expense.id || !expense.data_hora || !expense.descricao || !expense.valor) {
                    return null;
                  }
                  
                  try {
                    const { date, time } = formatDateTime(expense.data_hora);
                    // Usa categoria_id diretamente (pode ser number, undefined ou null)
                    const categoriaId = expense.categoria_id;
                    const categoryInfo = getCategoryInfo(categoriaId, categories);
                    const valor = parseFloat(expense.valor) || 0;
                    
                    return (
                      <TableRow key={expense.id}>
                        <TableCell>
                          <div className="flex flex-col">
                            <span className="font-medium">{date}</span>
                            <span className="text-xs text-muted-foreground">{time}</span>
                          </div>
                        </TableCell>
                        <TableCell>
                          <span className="font-medium">{expense.descricao || "Sem descrição"}</span>
                        </TableCell>
                        <TableCell>
                          <Badge
                            variant="outline"
                            className={
                              expense.tipo === "corporativo"
                                ? "bg-secondary/10 text-secondary border-secondary/20"
                                : "bg-warning/10 text-warning border-warning/20"
                            }
                          >
                            {expense.tipo === "corporativo" ? (
                              <Building2 className="w-3 h-3 mr-1" />
                            ) : (
                              <User className="w-3 h-3 mr-1" />
                            )}
                            {expense.tipo === "corporativo" ? "Corp." : "Pessoal"}
                          </Badge>
                        </TableCell>
                        <TableCell>
                          {categoryInfo ? (
                            <Badge
                              variant="outline"
                              className={categoryInfo.color}
                            >
                              {categoryInfo.label}
                            </Badge>
                          ) : (
                            <Badge
                              variant="outline"
                              className="bg-gray-500/10 text-gray-600 border-gray-500/20"
                            >
                              Sem categoria
                            </Badge>
                          )}
                        </TableCell>
                        <TableCell className="text-right font-semibold">
                          {formatCurrency(valor)}
                        </TableCell>
                      </TableRow>
                    );
                  } catch (error) {
                    console.error("Erro ao renderizar despesa:", error, expense);
                    return null;
                  }
                }).filter(Boolean) // Remove nulls do array
              )}
            </TableBody>
          </Table>

          {/* Pagination */}
          {expensesData && expensesData.total_paginas > 0 && expensesData.total_paginas > 1 && (
            <div className="mt-4 flex items-center justify-between">
              <p className="text-sm text-muted-foreground">
                Mostrando {(currentPage - 1) * itemsPerPage + 1} a{" "}
                {Math.min(currentPage * itemsPerPage, expensesData.total_registros)} de{" "}
                {expensesData.total_registros} registros
              </p>
              <Pagination>
                <PaginationContent>
                  <PaginationItem>
                    <PaginationPrevious
                      onClick={() => {
                        if (currentPage > 1) {
                          setCurrentPage(currentPage - 1);
                        }
                      }}
                      className={
                        currentPage === 1
                          ? "pointer-events-none opacity-50"
                          : "cursor-pointer"
                      }
                    />
                  </PaginationItem>
                  {Array.from({ length: expensesData.total_paginas }, (_, i) => i + 1).map((page) => (
                    <PaginationItem key={page}>
                      <PaginationLink
                        onClick={() => setCurrentPage(page)}
                        isActive={currentPage === page}
                        className="cursor-pointer"
                      >
                        {page}
                      </PaginationLink>
                    </PaginationItem>
                  ))}
                  <PaginationItem>
                    <PaginationNext
                      onClick={() => {
                        if (currentPage < expensesData.total_paginas) {
                          setCurrentPage(currentPage + 1);
                        }
                      }}
                      className={
                        currentPage === expensesData.total_paginas
                          ? "pointer-events-none opacity-50"
                          : "cursor-pointer"
                      }
                    />
                  </PaginationItem>
                </PaginationContent>
              </Pagination>
            </div>
          )}
        </CardContent>
      </Card>
    </div>
  );
}
