import React, { useCallback, useEffect, useState } from 'react';
import {
  Row,
  Col,
  Table,
  Button,
  DatePicker,
  Input,
  Tooltip,
  message,
  Space,
} from 'antd';
import {
  LeftOutlined,
  RightOutlined,
  DownloadOutlined,
} from '@ant-design/icons';
import dayjs, { Dayjs } from 'dayjs';
import { AppContainer } from '../../components/AppContainer';
import SummaryCard from '../../components/SummaryCard';
import jwtAxios from '../../api/axiosInstance';
import { ENDPOINTS } from '../../api/endpoints';

export interface CashBankDailyReportProps {
  account: 'CASH' | 'BANK';
  title: string;
}

interface LedgerItem {
  id: string;
  date: string;
  voucherNo: string;
  type: string;
  typeLabelEnglish: string;
  account: 'CASH' | 'BANK';
  paymentMode: 'CASH' | 'UPI' | 'BANK';
  party: string;
  description: string;
  varavu: number;
  patru: number;
  balance: number;
}

export const CashBankDailyReport: React.FC<CashBankDailyReportProps> = ({
  account,
  title,
}) => {
  // Date state
  const [selectedDate, setSelectedDate] = useState<Dayjs>(dayjs());
  const [openingDateDayjs, setOpeningDateDayjs] = useState<Dayjs | null>(null);

  // Filters & loading
  const [loading, setLoading] = useState<boolean>(false);
  const [exportLoading, setExportLoading] = useState<'excel' | 'pdf' | null>(null);
  const [searchText, setSearchText] = useState<string>('');

  // Ledger data
  const [ledgerItems, setLedgerItems] = useState<LedgerItem[]>([]);
  const [summary, setSummary] = useState({
    openingBalance: 0,
    totalCredit: 0,
    totalDebit: 0,
    closingBalance: 0,
  });

  // Boundary checks
  const isTodayOrFuture = selectedDate.isSame(dayjs(), 'day') || selectedDate.isAfter(dayjs(), 'day');
  const isAtOpeningDate = openingDateDayjs
    ? selectedDate.isSame(openingDateDayjs, 'day') || selectedDate.isBefore(openingDateDayjs, 'day')
    : false;

  // 1. Fetch opening date metadata
  const fetchOpeningDate = useCallback(async () => {
    try {
      const res = await jwtAxios.get(ENDPOINTS.CASH_BANK_BALANCE);
      if (res.data?.success && res.data.data?.openingDate) {
        setOpeningDateDayjs(dayjs(res.data.data.openingDate));
      }
    } catch (err: any) {
      console.error('Failed to load opening date:', err);
    }
  }, []);

  // 2. Fetch daily report transactions
  const fetchReport = useCallback(async (dateObj: Dayjs = selectedDate) => {
    setLoading(true);
    try {
      const dateStr = dateObj.format('YYYY-MM-DD');
      const params = new URLSearchParams();
      params.set('date', dateStr);
      params.set('account', account);
      if (searchText.trim()) params.set('search', searchText.trim());

      const res = await jwtAxios.get(`${ENDPOINTS.CASH_BANK_LEDGER}?${params.toString()}`);
      if (res.data?.success) {
        const data = res.data.data;
        setLedgerItems(data.entries || []);
        setSummary({
          openingBalance: Number(data.openingBalance || 0),
          totalCredit: Number(data.totalVaravu || 0),
          totalDebit: Number(data.totalPatru || 0),
          closingBalance: Number(data.closingBalance || 0),
        });
        if (data.openingDate && !openingDateDayjs) {
          setOpeningDateDayjs(dayjs(data.openingDate));
        }
      }
    } catch (err: any) {
      message.error(err.response?.data?.message || `Failed to fetch ${title}`);
      setLedgerItems([]);
    } finally {
      setLoading(false);
    }
  }, [account, title, selectedDate, searchText, openingDateDayjs]);

  useEffect(() => {
    fetchOpeningDate();
  }, [fetchOpeningDate]);

  useEffect(() => {
    fetchReport(selectedDate);
  }, [selectedDate, fetchReport]);

  // Date Navigation handlers
  const handlePrevDay = () => {
    if (isAtOpeningDate) {
      message.warning(`Cannot navigate behind Opening Balance date (${openingDateDayjs?.format('DD-MM-YYYY')}).`);
      return;
    }
    setSelectedDate((prev) => prev.subtract(1, 'day'));
  };

  const handleNextDay = () => {
    if (isTodayOrFuture) return;
    setSelectedDate((prev) => prev.add(1, 'day'));
  };

  // Export handler
  const handleExport = async (format: 'excel' | 'pdf') => {
    setExportLoading(format);
    try {
      const dateStr = selectedDate.format('YYYY-MM-DD');
      const params = new URLSearchParams();
      params.set('date', dateStr);
      params.set('account', account);
      if (searchText.trim()) params.set('search', searchText.trim());

      const endpoint =
        format === 'excel' ? ENDPOINTS.CASH_BANK_EXPORT_EXCEL : ENDPOINTS.CASH_BANK_EXPORT_PDF;
      const res = await jwtAxios.get(`${endpoint}?${params.toString()}`, {
        responseType: 'blob',
      });

      const blob = new Blob([res.data], {
        type:
          format === 'excel'
            ? 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
            : 'application/pdf',
      });
      const url = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      const cleanName = title.replace(/\s+/g, '_');
      link.download = `${cleanName}_${dateStr}.${format === 'excel' ? 'xlsx' : 'pdf'}`;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      window.URL.revokeObjectURL(url);
      message.success(`${title} ${format.toUpperCase()} downloaded`);
    } catch (err: any) {
      message.error(`Failed to export ${format.toUpperCase()}`);
    } finally {
      setExportLoading(null);
    }
  };

  // Table Columns
  const columns = [
    {
      title: 'Date',
      dataIndex: 'date',
      key: 'date',
      width: 130,
      render: (d: string) => (d ? dayjs(d).format('DD-MM-YYYY') : selectedDate.format('DD-MM-YYYY')),
    },
    {
      title: 'Transaction Details',
      dataIndex: 'party',
      key: 'party',
      render: (_: any, r: LedgerItem) => {
        let label = r.typeLabelEnglish || r.type;
        if (account === 'BANK' && r.type === 'SALE') {
          label = 'Cash bill pay';
        }
        return (
          <span>
            <span className="font-medium text-gray-800">{label}</span>
            {r.party && <span className="text-gray-500 ml-2">({r.party})</span>}
          </span>
        );
      },
    },
    {
      title: 'Debit',
      dataIndex: 'patru',
      key: 'patru',
      align: 'right' as const,
      width: 160,
      render: (p: number) => (p > 0 ? Number(p).toFixed(2) : '-'),
    },
    {
      title: 'Credit',
      dataIndex: 'varavu',
      key: 'varavu',
      align: 'right' as const,
      width: 160,
      render: (v: number) => (v > 0 ? Number(v).toFixed(2) : '-'),
    },
    {
      title: 'Tally Balance',
      dataIndex: 'balance',
      key: 'balance',
      align: 'right' as const,
      width: 170,
      render: (b: number) => Number(b).toFixed(2),
    },
  ];

  return (
    <AppContainer title={title}>
      {/* 1. Summary Cards (Clean like Expense module) */}
      <Row gutter={[16, 16]} style={{ marginBottom: 20 }}>
        <Col xs={24} sm={12} md={8}>
          <SummaryCard
            label="Balance"
            value={summary.closingBalance}
            color="#722ed1"
            icon={<span style={{ fontSize: 20 }}>💰</span>}
          />
        </Col>
        <Col xs={24} sm={12} md={8}>
          <SummaryCard
            label="Total Debit"
            value={summary.totalDebit}
            color="#f5222d"
            icon={<span style={{ fontSize: 20 }}>📉</span>}
          />
        </Col>
        <Col xs={24} sm={12} md={8}>
          <SummaryCard
            label="Total Credit"
            value={summary.totalCredit}
            color="#52c41a"
            icon={<span style={{ fontSize: 20 }}>📈</span>}
          />
        </Col>

      </Row>

      {/* 2. Search boxes & Date Navigation */}
      <div className="flex justify-between items-center mb-4 pb-4 border-b border-gray-200">
        <Space>
          <Tooltip
            title={
              isAtOpeningDate
                ? `Cannot navigate behind Opening Date (${openingDateDayjs?.format('DD-MM-YYYY')})`
                : 'Previous Day'
            }
          >
            <Button
              icon={<LeftOutlined />}
              onClick={handlePrevDay}
              disabled={isAtOpeningDate}
            />
          </Tooltip>

          <DatePicker
            value={selectedDate}
            onChange={(d) => d && setSelectedDate(d)}
            format="DD-MM-YYYY"
            allowClear={false}
            disabledDate={(current) =>
              Boolean(
                (openingDateDayjs && current.isBefore(openingDateDayjs, 'day')) ||
                current.isAfter(dayjs(), 'day')
              )
            }
          />

          <Tooltip title={isTodayOrFuture ? 'Cannot navigate to future dates' : 'Next Day'}>
            <Button
              icon={<RightOutlined />}
              onClick={handleNextDay}
              disabled={isTodayOrFuture}
            />
          </Tooltip>

          <Input.Search
            placeholder="Search details..."
            value={searchText}
            onChange={(e) => setSearchText(e.target.value)}
            onSearch={() => fetchReport(selectedDate)}
            allowClear
            style={{ width: 240 }}
          />
        </Space>

        <Space>
          <Button
            icon={<DownloadOutlined />}
            loading={exportLoading === 'excel'}
            style={{ color: '#52c41a', borderColor: '#52c41a' }}
            onClick={() => handleExport('excel')}
          >
            Excel
          </Button>
          <Button
            icon={<DownloadOutlined />}
            loading={exportLoading === 'pdf'}
            danger
            onClick={() => handleExport('pdf')}
          >
            PDF
          </Button>
        </Space>
      </div>

      {/* 3. Clean Ant Design Table */}
      <Table
        rowKey="id"
        columns={columns}
        dataSource={ledgerItems}
        loading={loading}
        pagination={{
          pageSize: 15,
          showSizeChanger: true,
        }}
      />
    </AppContainer>
  );
};

export default CashBankDailyReport;
