'use client';

import { useState, useMemo, useCallback, useEffect, useRef } from 'react';
import { format, parseISO } from 'date-fns';
import { ko } from 'date-fns/locale';
import { Download, FileText, Loader2, RefreshCw, Calendar } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
  TableFooter,
} from '@/components/ui/table';
import { DatePicker } from '@/components/ui/date-picker';
import { PageLayout } from '@/components/organisms/PageLayout';
import { PageHeader } from '@/components/organisms/PageHeader';
import { formatNumber as formatAmount } from '@/lib/utils/amount';
import { Badge } from '@/components/ui/badge';
import type { NoteReceivableItem, DailyAccountItem } from './types';
import { MATCH_STATUS_LABELS, MATCH_STATUS_COLORS } from './types';
import { getNoteReceivables, getDailyAccounts, getDailyReportSummary, exportDailyReportExcel } from './actions';
import { toast } from 'sonner';
import { isNextRedirectError } from '@/lib/utils/redirect-error';
import { usePermission } from '@/hooks/usePermission';

// ===== Props 인터페이스 =====
interface DailyReportProps {
  initialNoteReceivables?: NoteReceivableItem[];
  initialDailyAccounts?: DailyAccountItem[];
}

export function DailyReport({ initialNoteReceivables = [], initialDailyAccounts = [] }: DailyReportProps) {
  const { canExport } = usePermission();
  // ===== 상태 관리 =====
  const [selectedDate, setSelectedDate] = useState(() => format(new Date(), 'yyyy-MM-dd'));
  const [noteReceivables, setNoteReceivables] = useState<NoteReceivableItem[]>(initialNoteReceivables);
  const [dailyAccounts, setDailyAccounts] = useState<DailyAccountItem[]>(initialDailyAccounts);
  const [summary, setSummary] = useState<{
    noteReceivableTotal: number;
    foreignCurrencyTotal: number;
    cashAssetTotal: number;
    krwTotals: { carryover: number; income: number; expense: number; balance: number };
    usdTotals: { carryover: number; income: number; expense: number; balance: number };
  } | null>(null);
  const [isLoading, setIsLoading] = useState(!initialNoteReceivables.length);

  // ===== 데이터 로드 =====
  const loadData = useCallback(async () => {
    setIsLoading(true);
    try {
      const [noteResult, accountResult, summaryResult] = await Promise.all([
        getNoteReceivables({ date: selectedDate }),
        getDailyAccounts({ date: selectedDate }),
        getDailyReportSummary({ date: selectedDate }),
      ]);

      if (noteResult.success) {
        setNoteReceivables(noteResult.data);
      }

      if (accountResult.success) {
        setDailyAccounts(accountResult.data);
      }

      if (summaryResult.success && summaryResult.data) {
        setSummary({
          noteReceivableTotal: summaryResult.data.noteReceivableTotal,
          foreignCurrencyTotal: summaryResult.data.foreignCurrencyTotal,
          cashAssetTotal: summaryResult.data.cashAssetTotal,
          krwTotals: summaryResult.data.krwTotals,
          usdTotals: summaryResult.data.usdTotals,
        });
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('Failed to load daily report:', error);
    } finally {
      setIsLoading(false);
    }
  }, [selectedDate]);

  // ===== 초기 로드 및 날짜 변경시 재로드 =====
  const isInitialMount = useRef(true);
  const prevDateRef = useRef(selectedDate);

  useEffect(() => {
    // 초기 마운트 또는 날짜가 실제로 변경된 경우에만 로드
    if (isInitialMount.current || prevDateRef.current !== selectedDate) {
      isInitialMount.current = false;
      prevDateRef.current = selectedDate;
      loadData();
    }
  }, [selectedDate, loadData]);

  // ===== 어음 합계 (API 요약 사용) =====
  const noteReceivableTotal = useMemo(() => {
    return summary?.noteReceivableTotal ?? noteReceivables.reduce((sum, item) => sum + item.currentBalance, 0);
  }, [summary, noteReceivables]);

  // ===== 일별 계좌 합계 (API 요약 사용) =====
  const accountTotals = useMemo(() => {
    if (summary) {
      return { krw: summary.krwTotals, usd: summary.usdTotals };
    }

    const krwAccounts = dailyAccounts.filter(item => item.currency === 'KRW');
    const usdAccounts = dailyAccounts.filter(item => item.currency === 'USD');

    const krwTotal = krwAccounts.reduce(
      (acc, item) => ({
        carryover: acc.carryover + item.carryover,
        income: acc.income + item.income,
        expense: acc.expense + item.expense,
        balance: acc.balance + item.balance,
      }),
      { carryover: 0, income: 0, expense: 0, balance: 0 }
    );

    const usdTotal = usdAccounts.reduce(
      (acc, item) => ({
        carryover: acc.carryover + item.carryover,
        income: acc.income + item.income,
        expense: acc.expense + item.expense,
        balance: acc.balance + item.balance,
      }),
      { carryover: 0, income: 0, expense: 0, balance: 0 }
    );

    return { krw: krwTotal, usd: usdTotal };
  }, [summary, dailyAccounts]);

  // ===== 현금성 자산 합계 =====
  const cashAssetTotal = useMemo(() => {
    return {
      carryover: accountTotals.krw.carryover,
      income: accountTotals.krw.income,
      expense: accountTotals.krw.expense,
      balance: accountTotals.krw.balance,
    };
  }, [accountTotals]);

  // ===== 선택된 날짜 정보 =====
  const selectedDateInfo = useMemo(() => {
    try {
      const date = parseISO(selectedDate);
      return {
        formatted: format(date, 'yyyy년 M월 d일', { locale: ko }),
        dayOfWeek: format(date, 'EEEE', { locale: ko }),
      };
    } catch {
      return { formatted: '', dayOfWeek: '' };
    }
  }, [selectedDate]);

  // ===== 엑셀 다운로드 =====
  const handleExcelDownload = useCallback(async () => {
    const result = await exportDailyReportExcel({ date: selectedDate });

    if (result.success && result.data) {
      const url = URL.createObjectURL(result.data);
      const a = document.createElement('a');
      a.href = url;
      a.download = result.filename || `일일일보_${selectedDate}.xlsx`;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
      toast.success('엑셀 파일이 다운로드되었습니다.');
    } else {
      toast.error(result.error || '엑셀 다운로드에 실패했습니다.');
    }
  }, [selectedDate]);

  return (
    <PageLayout>
      {/* 헤더 */}
      <PageHeader
        title="일일 일보"
        description="일일 자금 현황을 한눈에 확인합니다."
        icon={FileText}
      />

      {/* 헤더 액션 (날짜 선택, 버튼 등) */}
      <Card>
        <CardContent className="p-4">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-4">
              <div className="flex items-center gap-2">
                <Calendar className="h-4 w-4 text-gray-500" />
                <span className="text-sm font-medium text-gray-700">조회 일자</span>
                <DatePicker
                  value={selectedDate}
                  onChange={setSelectedDate}
                  className="w-[170px]"
                  size="sm"
                />
              </div>
            </div>
            <div className="flex items-center gap-2">
              <Button
                variant="outline"
                size="sm"
                onClick={loadData}
                disabled={isLoading}
              >
                {isLoading ? (
                  <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                ) : (
                  <RefreshCw className="mr-2 h-4 w-4" />
                )}
                새로고침
              </Button>
              {canExport && (
                <Button variant="outline" size="sm" onClick={handleExcelDownload}>
                  <Download className="mr-2 h-4 w-4" />
                  엑셀 다운로드
                </Button>
              )}
            </div>
          </div>
        </CardContent>
      </Card>

      {/* 어음 및 외상매출채권현황 */}
      <Card>
        <CardContent className="pt-6">
          <div className="flex items-center justify-between mb-4">
            <h3 className="text-lg font-semibold">어음 및 외상매출채권현황</h3>
          </div>
          <div className="rounded-md border overflow-x-auto">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead className="font-semibold">내용</TableHead>
                  <TableHead className="font-semibold text-right w-[150px]">현재 잔액</TableHead>
                  <TableHead className="font-semibold text-center w-[120px]">발행일</TableHead>
                  <TableHead className="font-semibold text-center w-[120px]">만기일</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {isLoading ? (
                  <TableRow>
                    <TableCell colSpan={4} className="text-center py-8">
                      <div className="flex items-center justify-center gap-2">
                        <Loader2 className="h-5 w-5 animate-spin text-gray-400" />
                        <span className="text-gray-500">데이터를 불러오는 중...</span>
                      </div>
                    </TableCell>
                  </TableRow>
                ) : noteReceivables.length === 0 ? (
                  <TableRow>
                    <TableCell colSpan={4} className="text-center py-8 text-muted-foreground">
                      데이터가 없습니다.
                    </TableCell>
                  </TableRow>
                ) : (
                  noteReceivables.map((item) => (
                    <TableRow key={item.id} className="hover:bg-muted/50">
                      <TableCell>{item.content}</TableCell>
                      <TableCell className="text-right">{formatAmount(item.currentBalance)}</TableCell>
                      <TableCell className="text-center">{item.issueDate}</TableCell>
                      <TableCell className="text-center">{item.dueDate}</TableCell>
                    </TableRow>
                  ))
                )}
              </TableBody>
              {noteReceivables.length > 0 && (
                <TableFooter>
                  <TableRow className="bg-muted/50 font-medium">
                    <TableCell className="font-bold">합계</TableCell>
                    <TableCell className="text-right font-bold">{formatAmount(noteReceivableTotal)}</TableCell>
                    <TableCell></TableCell>
                    <TableCell></TableCell>
                  </TableRow>
                </TableFooter>
              )}
            </Table>
          </div>
        </CardContent>
      </Card>

      {/* 일자별 상세 */}
      <Card>
        <CardContent className="pt-6">
          <div className="flex items-center justify-between mb-4">
            <h3 className="text-lg font-semibold">
              일자: {selectedDateInfo.formatted} {selectedDateInfo.dayOfWeek}
            </h3>
          </div>
          <div className="rounded-md border overflow-x-auto">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead className="font-semibold w-[200px]">구분</TableHead>
                  <TableHead className="font-semibold text-center w-[80px]">상태</TableHead>
                  <TableHead className="font-semibold text-right w-[150px]">전월 이월</TableHead>
                  <TableHead className="font-semibold text-right w-[120px]">수입</TableHead>
                  <TableHead className="font-semibold text-right w-[120px]">지출</TableHead>
                  <TableHead className="font-semibold text-right w-[120px]">잔액</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {isLoading ? (
                  <TableRow>
                    <TableCell colSpan={6} className="text-center py-8">
                      <div className="flex items-center justify-center gap-2">
                        <Loader2 className="h-5 w-5 animate-spin text-gray-400" />
                        <span className="text-gray-500">데이터를 불러오는 중...</span>
                      </div>
                    </TableCell>
                  </TableRow>
                ) : dailyAccounts.length === 0 ? (
                  <TableRow>
                    <TableCell colSpan={6} className="text-center py-8 text-muted-foreground">
                      데이터가 없습니다.
                    </TableCell>
                  </TableRow>
                ) : (
                  <>
                    {/* KRW 계좌들 */}
                    {dailyAccounts
                      .filter(item => item.currency === 'KRW')
                      .map((item) => (
                        <TableRow key={item.id} className="hover:bg-muted/50">
                          <TableCell>{item.category}</TableCell>
                          <TableCell className="text-center">
                            <Badge className={MATCH_STATUS_COLORS[item.matchStatus]}>
                              {MATCH_STATUS_LABELS[item.matchStatus]}
                            </Badge>
                          </TableCell>
                          <TableCell className="text-right">{formatAmount(item.carryover)}</TableCell>
                          <TableCell className="text-right">{formatAmount(item.income)}</TableCell>
                          <TableCell className="text-right">{formatAmount(item.expense)}</TableCell>
                          <TableCell className="text-right">{formatAmount(item.balance)}</TableCell>
                        </TableRow>
                      ))}
                  </>
                )}
              </TableBody>
              {dailyAccounts.length > 0 && (
                <TableFooter>
                  {/* 외화원 (USD) 합계 */}
                  <TableRow className="bg-blue-50/50">
                    <TableCell className="font-semibold">외화원 (USD) 합계</TableCell>
                    <TableCell></TableCell>
                    <TableCell className="text-right">${formatAmount(accountTotals.usd.carryover)}</TableCell>
                    <TableCell className="text-right">${formatAmount(accountTotals.usd.income)}</TableCell>
                    <TableCell className="text-right">${formatAmount(accountTotals.usd.expense)}</TableCell>
                    <TableCell className="text-right">${formatAmount(accountTotals.usd.balance)}</TableCell>
                  </TableRow>
                  {/* 현금성 자산 합계 */}
                  <TableRow className="bg-muted/50 font-medium">
                    <TableCell className="font-bold">현금성 자산 합계</TableCell>
                    <TableCell></TableCell>
                    <TableCell className="text-right font-bold">{formatAmount(cashAssetTotal.carryover)}</TableCell>
                    <TableCell className="text-right font-bold">{formatAmount(cashAssetTotal.income)}</TableCell>
                    <TableCell className="text-right font-bold">{formatAmount(cashAssetTotal.expense)}</TableCell>
                    <TableCell className="text-right font-bold">{formatAmount(cashAssetTotal.balance)}</TableCell>
                  </TableRow>
                </TableFooter>
              )}
            </Table>
          </div>
        </CardContent>
      </Card>
    </PageLayout>
  );
}