import React, { useState, useMemo, useEffect } from 'react';
import {
  Invoice,
  InvoiceStatus,
  PaymentInvoice,
  PaymentCalendarEntry,
  PaymentDirection,
  FinanceAccount
} from '../../types';
import { apiClient } from '../../services/apiClient';
import {
  Calendar,
  CheckCircle2,
  Wallet,
  History,
  Pause,
  XCircle,
  Plus,
  ArrowDownCircle,
  ArrowUpCircle,
  Banknote,
  Landmark
} from 'lucide-react';
import { PaymentCalendarEntryForm } from './PaymentCalendarEntryForm';
import { PaymentStatusModal, PaymentStatusAction, PaymentStatusModalPayload } from './PaymentStatusModal';

type CalendarInterval = 'week' | 'month';

function getPeriodBounds(interval: CalendarInterval): { dateFrom: string; dateTo: string; label: string } {
  const now = new Date();
  const year = now.getFullYear();
  const month = now.getMonth();
  if (interval === 'week') {
    const day = now.getDay();
    const mondayOffset = day === 0 ? -6 : 1 - day;
    const monday = new Date(now);
    monday.setDate(now.getDate() + mondayOffset);
    const sunday = new Date(monday);
    sunday.setDate(monday.getDate() + 6);
    const dateFrom = monday.toISOString().split('T')[0];
    const dateTo = sunday.toISOString().split('T')[0];
    const options: Intl.DateTimeFormatOptions = { day: 'numeric', month: 'short' };
    const label = `${monday.toLocaleDateString('ru-RU', options)} – ${sunday.toLocaleDateString('ru-RU', options)} ${year}`;
    return { dateFrom, dateTo, label };
  }
  const first = new Date(year, month, 1);
  const last = new Date(year, month + 1, 0);
  const dateFrom = first.toISOString().split('T')[0];
  const dateTo = last.toISOString().split('T')[0];
  const label = first.toLocaleDateString('ru-RU', { month: 'long', year: 'numeric' });
  return { dateFrom, dateTo, label };
}

interface PaymentCalendarProps {
  invoices?: Invoice[];
  paymentInvoices?: PaymentInvoice[];
  calendarEntries?: PaymentCalendarEntry[];
  onUpdateStatus?: (id: string, s: InvoiceStatus, extra?: any) => void;
  onUpdatePaymentInvoiceStatus?: (id: number, status: 'paid' | 'postponed' | 'cancelled', payload?: PaymentStatusModalPayload) => Promise<void>;
  onRefreshCalendar?: () => void;
  currentBalance: number;
  currentUserId: string;
  interval?: CalendarInterval;
  onIntervalChange?: (interval: CalendarInterval) => void;
  periodLabel?: string;
}

type RowItem = {
  id: string;
  direction: PaymentDirection;
  amount: number;
  scheduledDate: string;
  contractorName: string;
  description: string;
  probability?: string;
  isCash?: boolean;
  status?: string;
  paymentInvoiceId?: number;
  isOld?: boolean;
  type: 'invoice' | 'entry';
  entryId?: number;
  currency?: string;
};

export const PaymentCalendar: React.FC<PaymentCalendarProps> = ({
  invoices = [],
  paymentInvoices = [],
  calendarEntries = [],
  onUpdateStatus,
  onUpdatePaymentInvoiceStatus,
  onRefreshCalendar,
  currentBalance,
  currentUserId,
  interval = 'month',
  onIntervalChange,
  periodLabel: periodLabelProp
}) => {
  const [filter, setFilter] = useState<'all' | 'planned' | 'paid'>('all');
  const [directionFilter, setDirectionFilter] = useState<'all' | 'outgoing' | 'incoming'>('all');
  const [loading, setLoading] = useState<Record<number, boolean>>({});
  const [showEntryForm, setShowEntryForm] = useState(false);
  const [defaultFormDirection, setDefaultFormDirection] = useState<PaymentDirection>('outgoing');
  const [statusModal, setStatusModal] = useState<{ action: PaymentStatusAction; row: RowItem } | null>(null);
  const [financeAccounts, setFinanceAccounts] = useState<FinanceAccount[]>([]);

  const { dateFrom, dateTo, label } = useMemo(() => getPeriodBounds(interval), [interval]);

  useEffect(() => {
    const load = async () => {
      try {
        const list = await apiClient.get<FinanceAccount[]>('/finance/accounts');
        setFinanceAccounts(Array.isArray(list) ? list : []);
      } catch {
        setFinanceAccounts([]);
      }
    };
    load();
  }, []);
  const periodLabel = periodLabelProp ?? label;

  const invoiceRows: RowItem[] = useMemo(() => {
    const invList = [
      ...invoices.map((inv) => ({
        id: inv.id,
        direction: 'outgoing' as PaymentDirection,
        amount: Number(inv.amount) || 0,
        scheduledDate: inv.scheduledDate || '',
        contractorName: inv.contractorName,
        description: inv.serviceName,
        status: inv.status,
        isOld: true,
        type: 'invoice' as const,
        paymentInvoiceId: undefined
      })),
      ...paymentInvoices.map((inv) => ({
        id: `pi-${inv.id}`,
        direction: 'outgoing' as PaymentDirection,
        amount: Number(inv.totalAmount) || 0,
        scheduledDate: inv.scheduledDate || '',
        contractorName: inv.contractorName,
        description: inv.serviceDescription,
        status: inv.status,
        isOld: false,
        type: 'invoice' as const,
        paymentInvoiceId: inv.id
      }))
    ];
    return invList;
  }, [invoices, paymentInvoices]);

  const entryRows: RowItem[] = useMemo(() => {
    const invoiceIds = new Set(paymentInvoices.map((pi) => pi.id));
    return calendarEntries
      .filter((e) => !e.paymentInvoiceId || !invoiceIds.has(e.paymentInvoiceId))
      .map((e) => ({
        id: `entry-${e.id}`,
        direction: e.direction,
        amount: Number(e.amount) || 0,
        scheduledDate: e.scheduledDate,
        contractorName: e.contractorName,
        description: e.description || e.category,
        probability: e.probability,
        isCash: e.isCash,
        type: 'entry' as const,
        entryId: e.id,
        currency: e.currency
      }));
  }, [calendarEntries, paymentInvoices]);

  const allRows = useMemo(() => {
    const combined = [...invoiceRows, ...entryRows];
    return combined
      .filter((r) => {
        if (directionFilter !== 'all' && r.direction !== directionFilter) return false;
        if (filter === 'planned') {
          if (r.type === 'invoice') return r.status === 'scheduled' || r.status === 'overdue';
          return !r.scheduledDate ? false : true;
        }
        if (filter === 'paid') {
          if (r.type === 'invoice') return r.status === 'paid';
          return false;
        }
        return true;
      })
      .sort((a, b) => (a.scheduledDate || '').localeCompare(b.scheduledDate || ''));
  }, [invoiceRows, entryRows, filter, directionFilter]);

  const scheduledTotalOutgoing =
    invoiceRows.filter((i) => i.status === 'scheduled').reduce((s, i) => s + Number(i.amount) || 0, 0) +
    entryRows.filter((e) => e.direction === 'outgoing').reduce((s, e) => s + Number(e.amount) || 0, 0);
  const scheduledTotalIncoming = entryRows
    .filter((e) => e.direction === 'incoming')
    .reduce((s, e) => s + Number(e.amount) || 0, 0);

  const handlePaymentActionClick = (row: RowItem, action: 'paid' | 'postponed' | 'cancelled') => {
    if (row.type !== 'invoice' || row.isOld) {
      if (onUpdateStatus) onUpdateStatus(row.id, action === 'paid' ? 'paid' : 'scheduled');
      return;
    }
    if (row.paymentInvoiceId && onUpdatePaymentInvoiceStatus) {
      setStatusModal({ action, row });
    }
  };

  const handleStatusModalConfirm = async (payload: PaymentStatusModalPayload) => {
    if (!statusModal || !statusModal.row.paymentInvoiceId || !onUpdatePaymentInvoiceStatus) return;
    const { row, action } = statusModal;
    const id = row.paymentInvoiceId!;
    setStatusModal(null);
    setLoading((prev) => ({ ...prev, [id]: true }));
    try {
      await onUpdatePaymentInvoiceStatus(id, action, payload);
    } catch (err) {
      console.error('Error updating payment invoice status:', err);
      alert('Ошибка при обновлении статуса');
    } finally {
      setLoading((prev) => ({ ...prev, [id]: false }));
    }
  };

  const handleDeleteEntry = async (entryId: number) => {
    if (!window.confirm('Удалить запись из календаря?')) return;
    try {
      await apiClient.delete(`/finance/payment-calendar/entries/${entryId}`);
      onRefreshCalendar?.();
    } catch (err) {
      console.error('Error deleting entry:', err);
      alert('Ошибка удаления');
    }
  };

  const probabilityLabel: Record<string, string> = {
    confirmed: '100%',
    high: '80%',
    medium: '50%',
    low: '30%'
  };

  return (
    <div className="space-y-6 animate-fade-in">
      <div className="flex flex-wrap items-center justify-between gap-4">
        <div className="flex flex-wrap items-center gap-2">
          <div className="flex bg-slate-100 p-1 rounded-xl w-fit">
            <button
              onClick={() => setFilter('all')}
              className={`px-4 py-1.5 text-xs font-bold rounded-lg transition-all ${filter === 'all' ? 'bg-white shadow text-slate-800' : 'text-slate-500'}`}
            >
              Все
            </button>
            <button
              onClick={() => setFilter('planned')}
              className={`px-4 py-1.5 text-xs font-bold rounded-lg transition-all ${filter === 'planned' ? 'bg-white shadow text-slate-800' : 'text-slate-500'}`}
            >
              План
            </button>
            <button
              onClick={() => setFilter('paid')}
              className={`px-4 py-1.5 text-xs font-bold rounded-lg transition-all ${filter === 'paid' ? 'bg-white shadow text-slate-800' : 'text-slate-500'}`}
            >
              Оплачено
            </button>
          </div>
          <div className="flex bg-slate-100 p-1 rounded-xl w-fit">
            <button
              onClick={() => setDirectionFilter('all')}
              className={`px-3 py-1.5 text-xs font-bold rounded-lg transition-all ${directionFilter === 'all' ? 'bg-white shadow text-slate-800' : 'text-slate-500'}`}
            >
              Все
            </button>
            <button
              onClick={() => setDirectionFilter('outgoing')}
              className={`flex items-center gap-1 px-3 py-1.5 text-xs font-bold rounded-lg transition-all ${directionFilter === 'outgoing' ? 'bg-white shadow text-slate-800' : 'text-slate-500'}`}
            >
              <ArrowUpCircle className="w-3.5 h-3.5" /> Расходы
            </button>
            <button
              onClick={() => setDirectionFilter('incoming')}
              className={`flex items-center gap-1 px-3 py-1.5 text-xs font-bold rounded-lg transition-all ${directionFilter === 'incoming' ? 'bg-white shadow text-slate-800' : 'text-slate-500'}`}
            >
              <ArrowDownCircle className="w-3.5 h-3.5" /> Поступления
            </button>
          </div>
        </div>
        <div className="flex items-center gap-3">
          {onIntervalChange && (
            <div className="flex bg-slate-100 p-1 rounded-xl">
              <button
                onClick={() => onIntervalChange('week')}
                className={`px-3 py-1.5 text-xs font-bold rounded-lg transition-all ${interval === 'week' ? 'bg-white shadow text-slate-800' : 'text-slate-500'}`}
              >
                Неделя
              </button>
              <button
                onClick={() => onIntervalChange('month')}
                className={`px-3 py-1.5 text-xs font-bold rounded-lg transition-all ${interval === 'month' ? 'bg-white shadow text-slate-800' : 'text-slate-500'}`}
              >
                Месяц
              </button>
            </div>
          )}
          {financeAccounts.length > 0 ? (
            <div className="flex flex-wrap items-center gap-4">
              <div className="flex flex-wrap gap-3">
                {financeAccounts.filter((a) => a.type === 'bank').map((a) => (
                  <div key={a.id} className="flex items-center gap-2 px-3 py-2 bg-slate-100 rounded-xl border border-slate-200">
                    <Landmark className="w-4 h-4 text-slate-500" />
                    <div>
                      <p className="text-[10px] text-slate-500 font-bold uppercase">{a.name}</p>
                      <p className="text-sm font-black text-slate-800">{Number(a.balance).toLocaleString('ru-RU')} ₽</p>
                    </div>
                  </div>
                ))}
                {financeAccounts.filter((a) => a.type === 'cash').map((a) => (
                  <div key={a.id} className="flex items-center gap-2 px-3 py-2 bg-amber-50 rounded-xl border border-amber-200">
                    <Banknote className="w-4 h-4 text-amber-600" />
                    <div>
                      <p className="text-[10px] text-amber-700 font-bold uppercase">{a.name}</p>
                      <p className="text-sm font-black text-amber-800">{Number(a.balance).toLocaleString('ru-RU')} ₽</p>
                    </div>
                  </div>
                ))}
              </div>
              <p className="text-[10px] text-slate-400 font-black uppercase">Итого: {financeAccounts.reduce((s, a) => s + Number(a.balance), 0).toLocaleString('ru-RU')} ₽</p>
            </div>
          ) : (
            <div className="text-right hidden sm:block">
              <p className="text-[10px] text-slate-400 font-black uppercase tracking-widest">Текущий остаток</p>
              <p className="text-sm font-black text-slate-800">{currentBalance.toLocaleString()} ₽</p>
            </div>
          )}
          <button
            onClick={() => {
              setDefaultFormDirection('outgoing');
              setShowEntryForm(true);
            }}
            className="flex items-center gap-2 px-3 py-2 bg-slate-900 text-white rounded-xl text-xs font-bold hover:bg-slate-800 transition-colors"
          >
            <Plus className="w-4 h-4" /> Добавить
          </button>
        </div>
      </div>

      <div className="bg-white rounded-2xl border border-slate-200 shadow-sm overflow-hidden">
        <div className="p-4 bg-slate-900 text-white flex flex-wrap justify-between items-center gap-4">
          <div className="flex items-center gap-3">
            <div className="p-2 bg-white/10 rounded-lg">
              <Calendar className="w-5 h-5" />
            </div>
            <div>
              <h3 className="font-bold leading-none uppercase tracking-tighter">Платежный календарь</h3>
              <p className="text-[10px] text-slate-400 mt-1 uppercase font-bold tracking-widest">{periodLabel}</p>
            </div>
          </div>
          <div className="flex gap-6">
            <div className="text-right">
              <p className="text-lg font-black">{Number(scheduledTotalOutgoing).toLocaleString('ru-RU')} ₽</p>
              <p className="text-[10px] text-slate-400 uppercase font-bold">К оплате (план)</p>
            </div>
            <div className="text-right">
              <p className="text-lg font-black text-emerald-300">+{Number(scheduledTotalIncoming).toLocaleString('ru-RU')} ₽</p>
              <p className="text-[10px] text-slate-400 uppercase font-bold">Ожидаемые поступления</p>
            </div>
          </div>
        </div>

        <div className="divide-y divide-slate-100">
          {allRows.length === 0 && (
            <div className="p-12 text-center text-slate-400 italic">Нет записей за выбранный период</div>
          )}
          {allRows.map((row) => {
            const isPaid = row.type === 'invoice' && row.status === 'paid';
            const isOverdue = row.type === 'invoice' && row.status === 'overdue';
            const isIncoming = row.direction === 'incoming';
            const day = row.scheduledDate?.split('-')[2] || '??';
            const monthShort = row.scheduledDate
              ? new Date(row.scheduledDate + 'T12:00:00').toLocaleDateString('ru-RU', { month: 'short' })
              : '—';
            return (
              <div
                key={row.id}
                className={`p-4 flex items-center gap-4 hover:bg-slate-50 transition-colors group ${isPaid ? 'bg-slate-50/50' : ''}`}
              >
                <div
                  className={`p-2 rounded-xl text-center min-w-[50px] border ${
                    isPaid
                      ? 'bg-emerald-50 border-emerald-100 text-emerald-600'
                      : isOverdue
                        ? 'bg-red-50 border-red-100 text-red-600'
                        : isIncoming
                          ? 'bg-emerald-50/50 border-emerald-100 text-emerald-700'
                          : 'bg-white border-slate-200 text-slate-500 shadow-sm'
                  }`}
                >
                  <p className="text-xs font-black leading-none">{day}</p>
                  <p className="text-[9px] font-bold uppercase mt-1">{monthShort}</p>
                </div>

                <div className="flex-1 min-w-0">
                  <div className="flex items-center gap-2 mb-0.5 flex-wrap">
                    {isIncoming && <ArrowDownCircle className="w-3.5 h-3.5 text-emerald-500 shrink-0" />}
                    {row.isCash && <Banknote className="w-3.5 h-3.5 text-amber-600 shrink-0" title="Наличные" />}
                    <p
                      className={`text-sm font-bold truncate ${isPaid ? 'text-slate-500' : 'text-slate-800'}`}
                    >
                      {row.contractorName || '—'}
                    </p>
                    {row.type === 'invoice' && isPaid && <CheckCircle2 className="w-3.5 h-3.5 text-emerald-500" />}
                    {row.probability && row.probability !== 'confirmed' && (
                      <span className="text-[9px] font-bold text-slate-400 bg-slate-100 px-1.5 py-0.5 rounded">
                        {probabilityLabel[row.probability] || row.probability}
                      </span>
                    )}
                  </div>
                  <p className="text-[10px] text-slate-400 truncate">{row.description || '—'}</p>
                </div>

                <div className="text-right flex items-center gap-4">
                  <div>
                    <p
                      className={`text-sm font-black ${isPaid ? 'text-slate-400' : isIncoming ? 'text-emerald-700' : 'text-slate-900'}`}
                    >
                      {isIncoming ? '+' : ''}
                      {row.amount.toLocaleString('ru-RU', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}{' '}
                      {row.currency === 'RUB' || !row.currency ? '₽' : row.currency}
                    </p>
                    {!isPaid && !isIncoming && row.type === 'invoice' && (
                      <p className="text-[8px] text-slate-400 font-bold uppercase">
                        Остаток после: {((currentBalance - row.amount) / 1000).toFixed(0)}k
                      </p>
                    )}
                  </div>

                  <div className="flex gap-1">
                    {row.type === 'entry' && row.entryId && (
                      <button
                        onClick={() => handleDeleteEntry(row.entryId!)}
                        className="p-2 bg-red-50 text-red-600 rounded-lg hover:bg-red-100 transition-colors"
                        title="Удалить запись"
                      >
                        <XCircle className="w-4 h-4" />
                      </button>
                    )}
                    {row.type === 'invoice' &&
                      (row.status !== 'paid' ? (
                        <>
                          <button
                            onClick={() => handlePaymentActionClick(row, 'paid')}
                            disabled={loading[row.paymentInvoiceId!]}
                            className="p-2 bg-slate-900 text-white rounded-lg hover:bg-slate-800 disabled:opacity-50"
                            title="Подтвердить оплату"
                          >
                            <Wallet className="w-4 h-4" />
                          </button>
                          {row.paymentInvoiceId && (
                            <>
                              <button
                                onClick={() => handlePaymentActionClick(row, 'postponed')}
                                disabled={loading[row.paymentInvoiceId!]}
                                className="p-2 bg-orange-100 text-orange-600 rounded-lg hover:bg-orange-200 disabled:opacity-50"
                                title="Отложить"
                              >
                                <Pause className="w-4 h-4" />
                              </button>
                              <button
                                onClick={() => handlePaymentActionClick(row, 'cancelled')}
                                disabled={loading[row.paymentInvoiceId!]}
                                className="p-2 bg-red-100 text-red-600 rounded-lg hover:bg-red-200 disabled:opacity-50"
                                title="Отменить"
                              >
                                <XCircle className="w-4 h-4" />
                              </button>
                            </>
                          )}
                        </>
                      ) : (
                        <button
                          onClick={() => handlePaymentActionClick(row, 'postponed')}
                          disabled={loading[row.paymentInvoiceId!]}
                          className="p-2 bg-white text-slate-300 rounded-lg hover:text-indigo-600 disabled:opacity-50"
                          title="Вернуть в план"
                        >
                          <History className="w-4 h-4" />
                        </button>
                      ))}
                  </div>
                </div>
              </div>
            );
          })}
        </div>
      </div>

      {showEntryForm && (
        <PaymentCalendarEntryForm
          currentUserId={currentUserId}
          defaultDirection={defaultFormDirection}
          onSave={async () => {
            setShowEntryForm(false);
            onRefreshCalendar?.();
          }}
          onCancel={() => setShowEntryForm(false)}
        />
      )}

      {statusModal && (
        <PaymentStatusModal
          action={statusModal.action}
          invoiceLabel={`${statusModal.row.contractorName} — ${statusModal.row.amount.toLocaleString('ru-RU')} ₽`}
          onConfirm={handleStatusModalConfirm}
          onCancel={() => setStatusModal(null)}
        />
      )}
    </div>
  );
};
