import { useState, useCallback } from 'react';
import { ArrowLeft, Calculator, Download } from 'lucide-react';
import { useLocation, useNavigate } from 'react-router-dom';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';

import api, { type Transaction } from '@/lib/api';
import {
  MONTH_NAMES_ES as MONTH_NAMES,
  MONTH_NAMES_ES_SHORT as MONTH_NAMES_SHORT,
} from '@/lib/dates';
import { useBudget } from '@/hooks/useBudget';
import { Button } from '@/components/ui/button';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import ErrorState from '@/components/ErrorState';
import PeriodNavigator from '@/components/PeriodNavigator';
import MonthlyDetail from '@/components/budget/MonthlyDetail';
import RecurringItemsManager from '@/components/budget/RecurringItemsManager';
import TransactionList from '@/components/TransactionList';
import ConvertToInstallmentsDialog from '@/components/transactions/ConvertToInstallmentsDialog';


const MIN_YEAR = 2026;
const MAX_YEAR = 2030;

export default function Budget() {
  const currentYear = Math.max(MIN_YEAR, new Date().getFullYear());
  const location = useLocation();
  const navigate = useNavigate();
  // Proyecciones row clicks land here with the clicked period in the state.
  const navState = location.state as
    | { from?: string; year?: number; month?: number }
    | null;
  const cameFromProyecciones = navState?.from === 'proyecciones';
  const initialYear =
    navState?.year && navState.year >= MIN_YEAR && navState.year <= MAX_YEAR
      ? navState.year
      : currentYear;
  const {
    year,
    setYear,
    selectedMonth,
    setSelectedMonth,
    monthDetail,
    recurringItems,
    monthLoading,
    error: budgetError,
    addItem,
    updateItem,
    deleteItem,
    refresh,
  } = useBudget(initialYear, navState?.month);
  const queryClient = useQueryClient();

  const [subTab, setSubTab] = useState<'detail' | 'transactions'>('detail');
  const [txSearch, setTxSearch] = useState('');
  const [txSource, setTxSource] = useState<'CREDIT_CARD' | 'CASH_AND_TRANSFER'>('CREDIT_CARD');
  const [convertTx, setConvertTx] = useState<Transaction | null>(null);

  const txQuery = useQuery({
    queryKey: ['transactions', 'budget', year, selectedMonth, txSource, txSearch],
    queryFn: async ({ signal }) => {
      const params: Record<string, string | number | boolean | undefined> = {
        search: txSearch || undefined,
        limit: 200,
      };
      if (txSource === 'CREDIT_CARD') {
        params.source = 'CREDIT_CARD';
        // Credit card: billing cycle that ends around the 18th of selectedMonth
        const prevMonth = selectedMonth === 1 ? 12 : selectedMonth - 1;
        const prevYear = selectedMonth === 1 ? year - 1 : year;
        params.cycle_year = prevYear;
        params.cycle_month = prevMonth;
      } else {
        // Cash + Transfer merged: calendar month, exclude credit card
        params.exclude_source = 'CREDIT_CARD';
        const startDate = `${year}-${String(selectedMonth).padStart(2, '0')}-01`;
        const endMonth = selectedMonth === 12 ? 1 : selectedMonth + 1;
        const endYear = selectedMonth === 12 ? year + 1 : year;
        const endDate = `${endYear}-${String(endMonth).padStart(2, '0')}-01`;
        params.start_date = startDate;
        params.end_date = endDate;
      }
      const { data } = await api.get<Transaction[]>('/transactions/', { params, signal });
      const INCOME_TYPES = ['DEPOSITO', 'SALARY'];
      return data.filter((tx) => !INCOME_TYPES.includes(tx.transaction_type));
    },
    placeholderData: (prev) => prev,
  });
  const transactions = txQuery.data ?? [];

  // Make the period explicit: budget month M on the card tab = the billing
  // cycle 18/(M-1) → 18/M; cash/transfers use the calendar month.
  const cyclePrevMonth = selectedMonth === 1 ? 12 : selectedMonth - 1;
  const cycleLabel =
    txSource === 'CREDIT_CARD'
      ? `Ciclo 18 ${MONTH_NAMES_SHORT[cyclePrevMonth].toLowerCase()} – 18 ${MONTH_NAMES_SHORT[selectedMonth].toLowerCase()}`
      : `Mes de ${MONTH_NAMES[selectedMonth].toLowerCase()}`;

  const invalidateTransactionsAndBudget = useCallback(() => {
    queryClient.invalidateQueries({ queryKey: ['transactions'] });
    queryClient.invalidateQueries({ queryKey: ['installment-plans'] });
    refresh();
  }, [queryClient, refresh]);

  const handleToggleDeferred = useCallback(async (tx: Transaction) => {
    try {
      await api.patch(`/transactions/${tx.id}`, {
        deferred_to_next_cycle: !tx.deferred_to_next_cycle,
      });
      toast.success(
        tx.deferred_to_next_cycle
          ? 'Transacción restaurada a su ciclo original'
          : 'Transacción diferida al siguiente ciclo',
      );
    } catch {
      toast.error('No se pudo actualizar la transacción');
      return;
    }
    invalidateTransactionsAndBudget();
  }, [invalidateTransactionsAndBudget]);

  const handleNavigateToTransactions = useCallback(() => {
    setTxSource('CASH_AND_TRANSFER');
    setSubTab('transactions');
  }, []);

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3">
          {cameFromProyecciones && (
            <Button
              variant="ghost"
              size="sm"
              className="mr-4 text-muted-foreground"
              onClick={() => navigate('/proyecciones')}
              aria-label="Volver a Proyecciones"
            >
              <ArrowLeft className="w-4 h-4 mr-1" aria-hidden="true" />
              Proyecciones
            </Button>
          )}
          <Calculator className="w-6 h-6 text-primary" />
          <h1 className="text-2xl font-bold tracking-tight">Presupuesto</h1>
        </div>
        <PeriodNavigator
          label={String(year)}
          onPrev={() => setYear(year - 1)}
          onNext={() => setYear(year + 1)}
          prevDisabled={year <= MIN_YEAR}
          nextDisabled={year >= MAX_YEAR}
        />
      </div>

      <Tabs defaultValue="overview">
        <TabsList>
          <TabsTrigger value="overview">Resumen</TabsTrigger>
          <TabsTrigger value="items">Items Recurrentes</TabsTrigger>
        </TabsList>

        <TabsContent value="overview" className="mt-4">
          <Tabs
            value={subTab}
            onValueChange={(v) => setSubTab(v as typeof subTab)}
          >
            <div className="flex items-center justify-between">
              <TabsList variant="line">
                <TabsTrigger value="detail">Detalle</TabsTrigger>
                <TabsTrigger value="transactions">Transacciones</TabsTrigger>
              </TabsList>
              <PeriodNavigator
                variant="ghost"
                label={`${MONTH_NAMES[selectedMonth]} ${year}`}
                labelClassName="text-sm font-medium w-28 text-center"
                onPrev={() => setSelectedMonth(selectedMonth - 1)}
                onNext={() => setSelectedMonth(selectedMonth + 1)}
                prevDisabled={selectedMonth <= 1}
                nextDisabled={selectedMonth >= 12}
              />
            </div>

            <TabsContent value="detail" className="space-y-6 mt-4">
              {budgetError ? (
                <ErrorState onRetry={refresh} />
              ) : (
                <MonthlyDetail
                  detail={monthDetail}
                  loading={monthLoading || !monthDetail}
                  onNavigateToTransactions={handleNavigateToTransactions}
                />
              )}
            </TabsContent>

            <TabsContent value="transactions" className="mt-4">
              {txQuery.isError ? (
                <ErrorState
                  message="No se pudieron cargar las transacciones"
                  onRetry={() => txQuery.refetch()}
                />
              ) : (
              <TransactionList
                transactions={transactions}
                loading={txQuery.isPending}
                source={txSource === 'CREDIT_CARD' ? 'CREDIT_CARD' : 'CASH'}
                search={txSearch}
                onSearchChange={setTxSearch}
                onRefresh={invalidateTransactionsAndBudget}
                showCategory={txSource === 'CREDIT_CARD'}
                showSourceIcon={txSource === 'CASH_AND_TRANSFER'}
                emptyMessage={`Sin transacciones de ${txSource === 'CREDIT_CARD' ? 'tarjeta' : 'efectivo o transferencia'} en ${MONTH_NAMES[selectedMonth]}`}
                onToggleDeferred={txSource === 'CREDIT_CARD' ? handleToggleDeferred : undefined}
                onConvertTasaCero={txSource === 'CREDIT_CARD' ? setConvertTx : undefined}
                summaryLabel={cycleLabel}
                toolbarLeft={
                  <Tabs
                    value={txSource}
                    onValueChange={(v) => setTxSource(v as typeof txSource)}
                  >
                    <TabsList>
                      <TabsTrigger value="CREDIT_CARD">Tarjeta</TabsTrigger>
                      <TabsTrigger value="CASH_AND_TRANSFER">Efectivo y Transferencias</TabsTrigger>
                    </TabsList>
                  </Tabs>
                }
                toolbarRight={
                  <Button
                    variant="outline"
                    size="sm"
                    onClick={() => window.open('/api/v1/transactions/export', '_blank')}
                    title="Descargar todas las transacciones como CSV"
                  >
                    <Download className="w-4 h-4 mr-2" aria-hidden="true" />
                    CSV
                  </Button>
                }
              />
              )}
            </TabsContent>
          </Tabs>
        </TabsContent>

        <TabsContent value="items" className="mt-4">
          <RecurringItemsManager
            items={recurringItems}
            onAdd={addItem}
            onUpdate={updateItem}
            onDelete={deleteItem}
          />
        </TabsContent>
      </Tabs>

      <ConvertToInstallmentsDialog
        open={convertTx !== null}
        onOpenChange={(open) => !open && setConvertTx(null)}
        onSaved={invalidateTransactionsAndBudget}
        tx={convertTx}
      />
    </div>
  );
}
