
import React, { useState, useMemo, useEffect, useCallback } from 'react';
import { MOCK_BUILDINGS } from '../constants';
import { Invoice, InvoiceStatus, PaymentInvoice, PaymentCalendarEntry } from '../types';
import { Plus } from 'lucide-react';
import { apiClient, authFetch } from '../services/apiClient';

function getCalendarPeriod(interval: 'week' | 'month'): { dateFrom: string; dateTo: 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);
    return {
      dateFrom: monday.toISOString().split('T')[0],
      dateTo: sunday.toISOString().split('T')[0]
    };
  }
  const first = new Date(year, month, 1);
  const last = new Date(year, month + 1, 0);
  return {
    dateFrom: first.toISOString().split('T')[0],
    dateTo: last.toISOString().split('T')[0]
  };
}

// Imported modular components
import { FinanceSummary } from './finance/FinanceSummary';
import { InvoiceRegistry } from './finance/InvoiceRegistry';
import { PaymentCalendar } from './finance/PaymentCalendar';
import { FinanceReports } from './finance/FinanceReports';
import { ReportUploader } from './finance/ReportUploader';
import { ReportProcessing } from './finance/ReportProcessing';
import { BuildingFinancialSummary } from './finance/BuildingFinancialSummary';
import { ReportsGrid } from './finance/ReportsGrid';
import { ReportDetailView } from './finance/ReportDetailView';
import { DebtorReportDetailView } from './finance/DebtorReportDetailView';
import { ReportTypesGrid } from './finance/ReportTypesGrid';
import { FinancialReport } from '../types';
import { PaymentInvoiceList } from './finance/PaymentInvoiceList';
import { PaymentInvoiceDetail } from './finance/PaymentInvoiceDetail';
import { PaymentInvoiceForm } from './finance/PaymentInvoiceForm';
import { allowedSubsForSection } from '../constants/permissions';
import { useSubPermission } from '../contexts/PermissionsContext';
import type { User } from '../types';

type FinanceTab = 'summary' | 'invoices' | 'calendar' | 'reports';
type ReportsView = 'types' | 'upload' | 'processing' | 'detail' | 'list';
type PaymentInvoicesView = 'list' | 'detail' | 'form';

const FINANCE_TABS: FinanceTab[] = ['summary', 'invoices', 'calendar', 'reports'];
const SUBTAB_KEY = 'mkd_subTab_finance';

export type FinanceInvoicePrefill = {
  purposeType: 'event';
  purposeEventId?: string;
  purposeDescription?: string;
  totalAmount?: number;
} | null;

interface FinanceModuleProps {
  currentUser?: User | null;
  externalInvoiceId?: number | null;
  externalInvoicePrefill?: FinanceInvoicePrefill;
  onInvoiceHandled?: () => void;
  /** Детальные права: null/пусто = все вкладки по роли */
  allowedPermissions?: string[] | null;
}

export const FinanceModule: React.FC<FinanceModuleProps> = ({ currentUser, externalInvoiceId, externalInvoicePrefill, onInvoiceHandled, allowedPermissions }) => {
  const visibleTabs = useMemo(() => {
    const allowed = allowedSubsForSection(allowedPermissions ?? [], 'finance');
    if (allowed === 'all') return FINANCE_TABS;
    return FINANCE_TABS.filter((t) => allowed.includes(t));
  }, [allowedPermissions]);

  const [activeTab, setActiveTab] = useState<FinanceTab>(() => {
    const s = localStorage.getItem(SUBTAB_KEY);
    const tab = (s && FINANCE_TABS.includes(s as FinanceTab)) ? s as FinanceTab : 'summary';
    return tab;
  });

  const { canEdit: canEditCurrentTab, scopeOwn: scopeOwnCurrentTab } = useSubPermission('finance', activeTab);

  useEffect(() => {
    if (visibleTabs.length > 0 && !visibleTabs.includes(activeTab)) {
      setActiveTab(visibleTabs[0]);
    }
  }, [visibleTabs, activeTab]);

  useEffect(() => {
    if (visibleTabs.includes(activeTab)) localStorage.setItem(SUBTAB_KEY, activeTab);
  }, [activeTab, visibleTabs]);
  const [reportsView, setReportsView] = useState<ReportsView>('types');
  const [currentJobId, setCurrentJobId] = useState<string | null>(null);
  const [currentReportId, setCurrentReportId] = useState<number | null>(null);
  const [selectedReport, setSelectedReport] = useState<FinancialReport | null>(null);
  const [selectedBuildingId, setSelectedBuildingId] = useState<string | null>(null);
  const [selectedReportType, setSelectedReportType] = useState<string | undefined>(undefined);
  const [selectedReportTypeName, setSelectedReportTypeName] = useState<string | undefined>(undefined);
  const [totalReportsCount, setTotalReportsCount] = useState<number>(0);
  
  // Новая система счетов на оплату
  const [paymentInvoicesView, setPaymentInvoicesView] = useState<PaymentInvoicesView>('list');
  const [selectedPaymentInvoice, setSelectedPaymentInvoice] = useState<PaymentInvoice | null>(null);
  const [paymentInvoices, setPaymentInvoices] = useState<PaymentInvoice[]>([]);
  const currentUserId = currentUser?.id ?? '';
  const [formPrefill, setFormPrefill] = useState<FinanceInvoicePrefill>(null);
  const [calendarEntries, setCalendarEntries] = useState<PaymentCalendarEntry[]>([]);
  const [calendarInterval, setCalendarInterval] = useState<'week' | 'month'>('month');
  
  const [invoices, setInvoices] = useState<Invoice[]>(() => 
    MOCK_BUILDINGS.flatMap(b => b.financials.invoices.map(inv => ({
        ...inv,
        closingDocsReceived: Math.random() > 0.5,
        status: inv.status as InvoiceStatus
    })))
  );

  const fetchCalendarEntries = useCallback(async () => {
    const { dateFrom, dateTo } = getCalendarPeriod(calendarInterval);
    try {
      const res = await apiClient.get<{ entries: PaymentCalendarEntry[] }>(
        `/finance/payment-calendar/entries?dateFrom=${dateFrom}&dateTo=${dateTo}&limit=500`
      );
      setCalendarEntries(res?.entries ?? []);
    } catch (err) {
      console.error('Error fetching payment calendar entries:', err);
      setCalendarEntries([]);
    }
  }, [calendarInterval]);

  // Загружаем счета и записи календаря при открытии вкладки «Календарь оплат»
  useEffect(() => {
    if (activeTab === 'calendar') {
      fetchPaymentInvoices();
      fetchCalendarEntries();
    }
  }, [activeTab, fetchCalendarEntries]);

  // Загружаем количество отчетов для отображения на главном экране
  useEffect(() => {
    if (activeTab === 'reports' && reportsView === 'types') {
      fetchReportsCount();
    }
  }, [activeTab, reportsView]);

  const fetchReportsCount = async () => {
    try {
      const response = await authFetch('/api/finance/reports');
      if (response.ok) {
        const data = await response.json();
        setTotalReportsCount(Array.isArray(data) ? data.length : 0);
      }
    } catch (err) {
      console.error('Error fetching reports count:', err);
    }
  };

  // Если пришел внешний запрос открыть конкретный счет
  useEffect(() => {
    const openFromExternal = async () => {
      if (!externalInvoiceId) return;
      try {
        const invoice = await apiClient.get<PaymentInvoice>(`/finance/payment-invoices/${externalInvoiceId}`);
        setSelectedPaymentInvoice(invoice);
        setActiveTab('invoices');
        setPaymentInvoicesView('detail');
        if (onInvoiceHandled) {
          onInvoiceHandled();
        }
      } catch (err) {
        console.error('Error opening external invoice:', err);
      }
    };
    openFromExternal();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [externalInvoiceId]);

  // Если пришло предзаполнение формы счета (например, по мероприятию)
  useEffect(() => {
    if (!externalInvoicePrefill) return;
    setFormPrefill(externalInvoicePrefill);
    setPaymentInvoicesView('form');
    setSelectedPaymentInvoice(null);
    setActiveTab('invoices');
    if (onInvoiceHandled) {
      onInvoiceHandled();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [externalInvoicePrefill]);

  const fetchPaymentInvoices = async () => {
    try {
      const response = await apiClient.get<{ invoices: PaymentInvoice[] }>('/finance/payment-invoices?status=scheduled&limit=100');
      setPaymentInvoices(response.invoices);
    } catch (err) {
      console.error('Error fetching payment invoices:', err);
    }
  };

  const financialData = useMemo(() => {
    const totalBalance = MOCK_BUILDINGS.reduce((sum, b) => sum + b.financials.balance, 0);
    const scheduledAmount = invoices.filter(i => i.status === 'scheduled').reduce((sum, i) => sum + i.amount, 0);
    const totalDebt = MOCK_BUILDINGS.reduce((sum, b) => sum + b.financials.debt, 0);
    const missingDocs = invoices.filter(i => i.status === 'paid' && !i.closingDocsReceived).length;

    return { totalBalance, totalDebt, scheduledAmount, missingDocs };
  }, [invoices]);
  
  const updateInvoiceStatus = (id: string, newStatus: InvoiceStatus, extra?: Partial<Invoice>) => {
    setInvoices(prev => prev.map(inv => 
        inv.id === id ? { ...inv, status: newStatus, ...extra } : inv
    ));
  };

  const handleAddInvoice = () => {
    setPaymentInvoicesView('form');
    setSelectedPaymentInvoice(null);
    setActiveTab('invoices');
  };

  const handleSavePaymentInvoice = async (invoiceData: Partial<PaymentInvoice>) => {
    try {
      if (selectedPaymentInvoice) {
        // Обновление существующего счета
        await apiClient.put(`/finance/payment-invoices/${selectedPaymentInvoice.id}`, invoiceData);
      } else {
        // Создание нового счета
        await apiClient.post('/finance/payment-invoices', invoiceData);
      }
      setFormPrefill(null);
      setPaymentInvoicesView('list');
      setSelectedPaymentInvoice(null);
      fetchPaymentInvoices();
    } catch (err) {
      console.error('Error saving payment invoice:', err);
      throw err;
    }
  };

  const handleUpdatePaymentInvoiceStatus = async (
    id: number,
    status: 'paid' | 'postponed' | 'cancelled',
    payload?: { paymentDate?: string; paymentRef?: string; isCash?: boolean; postponedDate?: string; cancelReason?: string }
  ) => {
    try {
      await apiClient.post(`/finance/payment-invoices/${id}/update-payment-status`, {
        status,
        paymentDate: payload?.paymentDate,
        paymentRef: payload?.paymentRef,
        isCash: payload?.isCash,
        postponedDate: payload?.postponedDate,
        cancelReason: payload?.cancelReason
      });
      fetchPaymentInvoices();
    } catch (err) {
      console.error('Error updating payment invoice status:', err);
      throw err;
    }
  };

  return (
    <div className="animate-fade-in pb-20 space-y-6">
      <div className="flex flex-wrap justify-between items-center gap-4">
        <h2 className="text-xl font-bold text-slate-800">Финансовый отдел</h2>
        {canEditCurrentTab && activeTab === 'invoices' && (
          <div className="flex gap-2">
            <button onClick={handleAddInvoice} className="bg-primary-600 text-white p-2 rounded-xl shadow-lg shadow-primary-500/30 flex items-center gap-2 px-3 text-xs font-bold active:scale-95 transition-transform">
              <Plus className="w-4 h-4" /> Новый счет
            </button>
          </div>
        )}
      </div>
      
      {/* Tabs */}
      <div className="flex p-1 bg-slate-200/50 rounded-xl overflow-x-auto no-scrollbar">
         {[
           {id: 'summary', label: 'Сводка'}, 
           {id: 'invoices', label: 'Реестр счетов'}, 
           {id: 'calendar', label: 'Календарь оплат'},
           {id: 'reports', label: 'Отчеты'}
         ].filter((tab) => visibleTabs.includes(tab.id as FinanceTab)).map((tab) => (
           <button
             key={tab.id}
             onClick={() => setActiveTab(tab.id as FinanceTab)}
             className={`flex-shrink-0 min-w-[7rem] px-4 py-2 text-xs font-bold whitespace-nowrap rounded-lg transition-all ${activeTab === tab.id ? 'bg-white text-primary-600 shadow-sm' : 'text-slate-500 hover:text-slate-700'}`}
           >
             {tab.label}
           </button>
         ))}
      </div>

      {/* Sheet Content Rendering */}
      <div className="min-h-[280px] sm:min-h-[360px] md:min-h-[500px]">
        {activeTab === 'summary' && <FinanceSummary data={financialData} />}
        {activeTab === 'invoices' && (
          <>
            {paymentInvoicesView === 'form' && (
              <div className="bg-white rounded-2xl border border-slate-200 shadow-sm p-6">
                <PaymentInvoiceForm
                  invoice={selectedPaymentInvoice || undefined}
                  initialPrefill={formPrefill ?? undefined}
                  currentUserId={currentUserId}
                  onSave={handleSavePaymentInvoice}
                  onCancel={() => {
                    setFormPrefill(null);
                    setPaymentInvoicesView('list');
                    setSelectedPaymentInvoice(null);
                  }}
                />
              </div>
            )}
            {paymentInvoicesView === 'detail' && selectedPaymentInvoice && (
              <PaymentInvoiceDetail
                invoice={selectedPaymentInvoice}
                currentUserId={currentUserId}
                onBack={() => {
                  setPaymentInvoicesView('list');
                  setSelectedPaymentInvoice(null);
                }}
                onUpdate={() => {
                  fetchPaymentInvoices();
                  // Перезагружаем детали счета
                  apiClient.get(`/finance/payment-invoices/${selectedPaymentInvoice.id}`)
                    .then(inv => setSelectedPaymentInvoice(inv))
                    .catch(err => console.error('Error fetching invoice details:', err));
                }}
              />
            )}
            {paymentInvoicesView === 'list' && (
              <PaymentInvoiceList
                onInvoiceClick={(invoice) => {
                  setSelectedPaymentInvoice(invoice);
                  setPaymentInvoicesView('detail');
                }}
                onCreateNew={handleAddInvoice}
                currentUserId={currentUserId}
                canEdit={canEditCurrentTab}
                scopeOwn={scopeOwnCurrentTab}
              />
            )}
          </>
        )}
        {activeTab === 'calendar' && (
            <PaymentCalendar
                invoices={invoices}
                paymentInvoices={paymentInvoices}
                calendarEntries={calendarEntries}
                onUpdateStatus={updateInvoiceStatus}
                onUpdatePaymentInvoiceStatus={handleUpdatePaymentInvoiceStatus}
                onRefreshCalendar={() => {
                  fetchPaymentInvoices();
                  fetchCalendarEntries();
                }}
                currentBalance={financialData.totalBalance}
                currentUserId={currentUserId}
                interval={calendarInterval}
                onIntervalChange={setCalendarInterval}
            />
        )}
        {activeTab === 'reports' && (
          <div className="space-y-6">
            {/* Детальный просмотр отчета */}
            {reportsView === 'detail' && selectedReport && selectedReport.reportType === 'debtors' && (
              <DebtorReportDetailView
                report={selectedReport}
                onBack={() => {
                  setReportsView('list');
                  setSelectedReport(null);
                }}
              />
            )}
            {reportsView === 'detail' && selectedReport && selectedReport.reportType !== 'debtors' && (
              <ReportDetailView
                report={selectedReport}
                onBack={() => {
                  setReportsView('list');
                  setSelectedReport(null);
                }}
              />
            )}

            {/* Список загруженных отчетов */}
            {reportsView === 'list' && (
              <ReportsGrid
                onReportClick={(report) => {
                  setSelectedReport(report);
                  setReportsView('detail');
                }}
                reportTypeFilter={selectedReportType}
                onBack={() => {
                  setReportsView('types');
                  setSelectedReportType(undefined);
                }}
              />
            )}

            {/* Загрузка данных (старый вариант без предустановленного типа) */}
            {reportsView === 'upload' && !selectedReportType && (
              <ReportUploader
                onUploadSuccess={(reportId, jobId) => {
                  setCurrentReportId(reportId);
                  setCurrentJobId(jobId ?? null);
                  window.dispatchEvent(new CustomEvent('mkd-finance-reports-changed'));
                  if (jobId) {
                    setReportsView('processing');
                  } else {
                    fetchReportsCount();
                    setReportsView('list');
                  }
                }}
                onUploadError={(error) => {
                  console.error('Ошибка загрузки:', error);
                }}
                onClose={() => {
                  setReportsView('types');
                  setSelectedReportType(undefined);
                }}
              />
            )}

            {/* Обработка */}
            {reportsView === 'processing' && currentJobId && (
              <ReportProcessing
                jobId={currentJobId}
                reportId={currentReportId || undefined}
                onComplete={() => {
                  window.dispatchEvent(new CustomEvent('mkd-finance-reports-changed'));
                  fetchReportsCount();
                  setReportsView('types');
                  setCurrentJobId(null);
                  setCurrentReportId(null);
                  setSelectedReportType(undefined);
                }}
                onViewReports={() => {
                  // Обновляем счетчик отчетов перед переходом к списку
                  fetchReportsCount();
                  setReportsView('list');
                  setCurrentJobId(null);
                  setCurrentReportId(null);
                  setSelectedReportType(undefined);
                }}
              />
            )}

            {reportsView === 'processing' && !currentJobId && (
              <div className="bg-white rounded-2xl border border-slate-200 shadow-sm p-12 text-center">
                <p className="text-slate-500">Нет активных процессов обработки</p>
                <button
                  onClick={() => setReportsView('types')}
                  className="mt-4 text-primary-600 hover:text-primary-700 font-medium"
                >
                  Вернуться к типам отчетов
                </button>
              </div>
            )}

            {/* Типы отчетов (основной экран) */}
            {reportsView === 'types' && (
              <ReportTypesGrid
                onReportTypeClick={(reportType) => {
                  // При клике на квадратик открываем модальное окно загрузки с предустановленным типом
                  setSelectedReportType(reportType.reportType);
                  setSelectedReportTypeName(reportType.name);
                  setReportsView('upload');
                }}
                onViewReportsClick={() => {
                  setReportsView('list');
                  setSelectedReportType(undefined);
                }}
                totalReportsCount={totalReportsCount}
              />
            )}
            
            {/* Модальное окно загрузки с предустановленным типом */}
            {reportsView === 'upload' && selectedReportType && (
              <div className="relative">
                <ReportUploader
                  presetReportType={selectedReportType as any}
                  reportTypeName={selectedReportTypeName}
                  onUploadSuccess={(reportId, jobId) => {
                    setCurrentReportId(reportId);
                    setCurrentJobId(jobId ?? null);
                    window.dispatchEvent(new CustomEvent('mkd-finance-reports-changed'));
                    fetchReportsCount();
                    if (jobId) {
                      setReportsView('processing');
                    } else {
                      setReportsView('list');
                      setSelectedReportType(undefined);
                    }
                  }}
                  onUploadError={(error) => {
                    console.error('Ошибка загрузки:', error);
                  }}
                  onViewReports={() => {
                    setReportsView('list');
                    setSelectedReportType(undefined);
                    setSelectedReportTypeName(undefined);
                  }}
                  onClose={() => {
                    setReportsView('types');
                    setSelectedReportType(undefined);
                    setSelectedReportTypeName(undefined);
                  }}
                />
              </div>
            )}
          </div>
        )}
      </div>
    </div>
  );
};
