import React, { useCallback, useEffect, useState } from 'react';
import {
  Row,
  Col,
  Table,
  Button,
  DatePicker,
  Select,
  Input,
  Modal,
  Form,
  InputNumber,
  message,
  Spin,
  Tag,
  Space,
  Alert,
  Tooltip,
} from 'antd';
import {
  SwapOutlined,
  SettingOutlined,
  LockOutlined,
  ReloadOutlined,
  DownloadOutlined,
  LeftOutlined,
  RightOutlined,
} from '@ant-design/icons';
import dayjs, { Dayjs } from 'dayjs';
import { useNavigate } from 'react-router-dom';
import { AppContainer } from '../../components/AppContainer';
import SummaryCard from '../../components/SummaryCard';
import jwtAxios from '../../api/axiosInstance';
import { ENDPOINTS } from '../../api/endpoints';

interface BalancesData {
  openingDate: string;
  remarks?: string;
  openingCashInHand: number;
  openingCashInBank: number;
  openingCombined: number;
  totalCashVaravu: number;
  totalCashPatru: number;
  currentCashInHand: number;
  totalBankVaravu: number;
  totalBankPatru: number;
  currentCashInBank: number;
  totalTransfers: number;
  totalCombinedBalance: number;
  isLocked?: boolean;
}

interface LedgerItem {
  id: string;
  date: string;
  voucherNo: string;
  type: 'SALE' | 'CUSTOMER_RECEIPT' | 'SUPPLIER_PAYMENT' | 'EXPENSE' | 'TRANSFER';
  typeLabelEnglish: string;
  account: 'CASH' | 'BANK';
  paymentMode: 'CASH' | 'UPI' | 'BANK';
  party: string;
  description: string;
  varavu: number;
  patru: number;
  balance: number;
  source: string;
  sourceId: string;
}

const TYPE_CONFIG: Record<string, { color: string; label: string }> = {
  SALE: { color: 'blue', label: 'Sale' },
  CUSTOMER_RECEIPT: { color: 'green', label: 'Customer Receipt' },
  SUPPLIER_PAYMENT: { color: 'orange', label: 'Supplier Payment' },
  EXPENSE: { color: 'volcano', label: 'Expense' },
  TRANSFER: { color: 'purple', label: 'Cash to Bank' },
};

export const CashBank: React.FC = () => {
  const navigate = useNavigate();

  // State
  const [loading, setLoading] = useState(false);
  const [exportLoading, setExportLoading] = useState<'excel' | 'pdf' | null>(null);
  const [balances, setBalances] = useState<BalancesData | null>(null);
  const [ledgerItems, setLedgerItems] = useState<LedgerItem[]>([]);
  const [ledgerSummary, setLedgerSummary] = useState({
    openingBalance: 0,
    totalVaravu: 0,
    totalPatru: 0,
    closingBalance: 0,
  });

  // Single Date filter (defaults to today), Account, Search
  const [selectedDate, setSelectedDate] = useState<Dayjs>(dayjs());
  const [accountFilter, setAccountFilter] = useState<'ALL' | 'CASH' | 'BANK'>('ALL');
  const [searchText, setSearchText] = useState<string>('');

  // Opening Balance Modal
  const [openingModalVisible, setOpeningModalVisible] = useState(false);
  const [openingForm] = Form.useForm();

  // Currency Formatter
  const fmt = (val?: number | null) => {
    const n = Number(val ?? 0);
    return isNaN(n) ? '0.00' : n.toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
  };

  // Fetch balances
  const fetchBalances = useCallback(async () => {
    try {
      const res = await jwtAxios.get(ENDPOINTS.CASH_BANK_BALANCE);
      if (res.data?.success) {
        setBalances(res.data.data);
      }
    } catch (err: any) {
      console.error('Failed to fetch balances:', err);
    }
  }, []);

  // Fetch single date ledger
  const fetchLedger = useCallback(async () => {
    setLoading(true);
    try {
      const dateStr = selectedDate.format('YYYY-MM-DD');
      const params = new URLSearchParams();
      params.set('date', dateStr);
      if (accountFilter !== 'ALL') params.set('account', accountFilter);
      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 || []);
        setLedgerSummary({
          openingBalance: data.openingBalance || 0,
          totalVaravu: data.totalVaravu || 0,
          totalPatru: data.totalPatru || 0,
          closingBalance: data.closingBalance || 0,
        });
      }
    } catch (err: any) {
      message.error(err.response?.data?.message || 'Failed to fetch ledger data');
    } finally {
      setLoading(false);
    }
  }, [selectedDate, accountFilter, searchText]);

  // Initial load
  useEffect(() => {
    fetchBalances();
    fetchLedger();
  }, [fetchBalances, fetchLedger]);

  // Refresh
  const handleRefresh = () => {
    fetchBalances();
    fetchLedger();
    message.success('Refreshed');
  };

  const openingDateDayjs = balances?.openingDate ? dayjs(balances.openingDate) : null;
  const isAtOpeningDate = openingDateDayjs
    ? selectedDate.isSame(openingDateDayjs, 'day') || selectedDate.isBefore(openingDateDayjs, 'day')
    : false;
  const isTodayOrFuture = selectedDate.isSame(dayjs(), 'day') || selectedDate.isAfter(dayjs(), 'day');

  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'));
  };

  // Jump to today
  const handleSetToday = () => {
    setSelectedDate(dayjs());
  };

  // Update opening balance
  const handleOpeningSubmit = async (values: any) => {
    try {
      setLoading(true);
      const payload = {
        openingCashInHand: values.openingCashInHand,
        openingCashInBank: values.openingCashInBank,
        openingDate: values.openingDate.format('YYYY-MM-DD'),
        remarks: values.remarks?.trim() || undefined,
      };

      const res = await jwtAxios.post(ENDPOINTS.CASH_BANK_OPENING_BALANCE, payload);
      if (res.data?.success) {
        message.success('Opening balance saved & locked successfully!');
        setOpeningModalVisible(false);
        fetchBalances();
        fetchLedger();
      }
    } catch (err: any) {
      message.error(err.response?.data?.message || 'Failed to save opening balance');
    } finally {
      setLoading(false);
    }
  };

  // Export handlers
  const handleExport = async (format: 'excel' | 'pdf') => {
    setExportLoading(format);
    try {
      const dateStr = selectedDate.format('YYYY-MM-DD');
      const params = new URLSearchParams();
      params.set('date', dateStr);
      if (accountFilter !== 'ALL') params.set('account', accountFilter);
      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;
      link.download = `Cash_Bank_Ledger_${dateStr}.${format === 'excel' ? 'xlsx' : 'pdf'}`;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      window.URL.revokeObjectURL(url);
      message.success(`Ledger ${format.toUpperCase()} downloaded`);
    } catch (err: any) {
      message.error(`Failed to export ${format.toUpperCase()}`);
    } finally {
      setExportLoading(null);
    }
  };

  // Clean, focused columns
  const columns = [
    {
      title: '#',
      dataIndex: 'index',
      key: 'index',
      width: 45,
      align: 'center' as const,
      render: (_: any, __: any, index: number) => index + 1,
    },
    {
      title: 'Voucher No',
      dataIndex: 'voucherNo',
      key: 'voucherNo',
      width: 130,
      render: (v: string) => <span className="font-medium text-gray-800 text-xs">{v}</span>,
    },
    {
      title: 'Type',
      dataIndex: 'type',
      key: 'type',
      width: 140,
      render: (t: string) => {
        const config = TYPE_CONFIG[t] || { color: 'default', label: t };
        return (
          <Tag color={config.color} className="text-xs font-medium">
            {config.label}
          </Tag>
        );
      },
    },
    {
      title: 'Account',
      dataIndex: 'account',
      key: 'account',
      width: 110,
      render: (acc: string) =>
        acc === 'CASH' ? (
          <Tag color="green" className="text-xs">Cash</Tag>
        ) : (
          <Tag color="blue" className="text-xs">Bank / UPI</Tag>
        ),
    },
    {
      title: 'Party / Description',
      dataIndex: 'party',
      key: 'party',
      render: (party: string, r: LedgerItem) => (
        <div className="truncate max-w-xs">
          <span className="font-medium text-gray-800 text-xs">{party}</span>
          {r.description && r.description !== party && (
            <span className="text-xs text-gray-400 ml-1.5">({r.description})</span>
          )}
        </div>
      ),
    },
    {
      title: 'Varavu (+)',
      dataIndex: 'varavu',
      key: 'varavu',
      align: 'right' as const,
      width: 125,
      render: (v: number) =>
        v > 0 ? (
          <span className="font-semibold text-emerald-600 text-xs">+{fmt(v)}</span>
        ) : (
          <span className="text-gray-300 text-xs">—</span>
        ),
    },
    {
      title: 'Patru (-)',
      dataIndex: 'patru',
      key: 'patru',
      align: 'right' as const,
      width: 125,
      render: (p: number) =>
        p > 0 ? (
          <span className="font-semibold text-rose-600 text-xs">-{fmt(p)}</span>
        ) : (
          <span className="text-gray-300 text-xs">—</span>
        ),
    },
    {
      title: 'Balance (₹)',
      dataIndex: 'balance',
      key: 'balance',
      align: 'right' as const,
      width: 135,
      render: (b: number) => (
        <span className={`font-semibold text-xs ${b >= 0 ? 'text-blue-700' : 'text-rose-600'}`}>
          ₹{fmt(b)}
        </span>
      ),
    },
  ];

  return (
    <AppContainer
      title="Cash & Bank Book"
      headerAction={
        <Space>
          <Button
            type="primary"
            icon={<SwapOutlined />}
            onClick={() => navigate('/cash-bank/transfer')}
            className="bg-blue-600 hover:bg-blue-700 font-medium"
          >
            Move Cash to Bank
          </Button>
          <Button
            icon={balances?.isLocked ? <LockOutlined /> : <SettingOutlined />}
            onClick={() => {
              if (balances) {
                openingForm.setFieldsValue({
                  openingCashInHand: balances.openingCashInHand,
                  openingCashInBank: balances.openingCashInBank,
                  openingDate: dayjs(balances.openingDate),
                  remarks: balances.remarks || '',
                });
              }
              setOpeningModalVisible(true);
            }}
          >
            {balances?.isLocked ? 'Opening Balance (Locked)' : 'Set Opening Balance'}
          </Button>
          <Button icon={<ReloadOutlined />} onClick={handleRefresh} />
        </Space>
      }
    >
      <Spin spinning={loading}>
        {/* 1. Summary Cards (Clean like Expense module) */}
        <Row gutter={[16, 16]} style={{ marginBottom: 20 }}>
          <Col xs={24} sm={12} md={6}>
            <SummaryCard
              label="Cash in Hand"
              value={balances?.currentCashInHand ?? 0}
              color="#52c41a"
              icon={<span style={{ fontSize: 20 }}>💵</span>}
            />
          </Col>
          <Col xs={24} sm={12} md={6}>
            <SummaryCard
              label="Cash in Bank (UPI & Bank)"
              value={balances?.currentCashInBank ?? 0}
              color="#1677ff"
              icon={<span style={{ fontSize: 20 }}>🏦</span>}
            />
          </Col>
          <Col xs={24} sm={12} md={6}>
            <SummaryCard
              label="Total Combined Balance"
              value={balances?.totalCombinedBalance ?? 0}
              color="#722ed1"
              icon={<span style={{ fontSize: 20 }}>💰</span>}
            />
          </Col>
          <Col xs={24} sm={12} md={6}>
            <SummaryCard
              label="Day Closing Balance"
              value={ledgerSummary.closingBalance}
              color="#fa8c16"
              icon={<span style={{ fontSize: 20 }}>📈</span>}
            />
          </Col>
        </Row>

        {/* 2. Search, Filters & 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>
            {!selectedDate.isSame(dayjs(), 'day') && (
              <Button
                type="link"
                size="small"
                onClick={handleSetToday}
                className="text-xs font-medium text-blue-600 p-0"
              >
                Today
              </Button>
            )}
            <Select
              value={accountFilter}
              onChange={(val) => setAccountFilter(val)}
              style={{ width: 150 }}
              options={[
                { value: 'ALL', label: 'All Accounts' },
                { value: 'CASH', label: 'Cash in Hand' },
                { value: 'BANK', label: 'Bank / UPI' },
              ]}
            />
            <Input.Search
              placeholder="Search details, voucher, party..."
              value={searchText}
              onChange={(e) => setSearchText(e.target.value)}
              allowClear
              style={{ width: 240 }}
            />
          </Space>

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

        {/* 3. Ledger Table */}
        <Table
          columns={columns}
          dataSource={ledgerItems}
          rowKey="id"
          pagination={{ pageSize: 15, showSizeChanger: true }}
          size="middle"
          className="shadow-xs rounded-lg overflow-hidden bg-white border border-gray-200"
          locale={{ emptyText: `No transactions on ${selectedDate.format('DD-MM-YYYY')}` }}
        />

        {/* Opening Balance Modal */}
        <Modal
          title={
            <div className="flex items-center gap-2">
              {balances?.isLocked ? (
                <>
                  <LockOutlined className="text-gray-600" />
                  <span>Initial Opening Balances (Locked)</span>
                </>
              ) : (
                <>
                  <SettingOutlined className="text-emerald-600" />
                  <span>Set Initial Opening Balances</span>
                </>
              )}
            </div>
          }
          open={openingModalVisible}
          onCancel={() => setOpeningModalVisible(false)}
          footer={null}
          destroyOnHidden
        >
          {balances?.isLocked ? (
            <Alert
              type="info"
              showIcon
              className="mb-4"
              message="Opening Balance is Permanently Locked"
              description="Initial opening balances were configured once during book setup and are permanently locked to preserve ledger audit and accounting integrity."
            />
          ) : (
            <Alert
              type="warning"
              showIcon
              className="mb-4"
              message="One-Time Setup"
              description="Enter your starting Cash in Hand and Cash in Bank. Once saved, this opening balance is permanently locked to preserve ledger integrity."
            />
          )}

          <Form form={openingForm} layout="vertical" onFinish={handleOpeningSubmit}>
            <Form.Item
              label={<span className="font-medium text-gray-700">Opening Date</span>}
              name="openingDate"
              rules={[{ required: true, message: 'Please select opening date' }]}
            >
              <DatePicker
                className="w-full"
                format="DD-MM-YYYY"
                allowClear={false}
                disabled={balances?.isLocked}
              />
            </Form.Item>

            <Form.Item
              label={<span className="font-medium text-gray-700">Opening Cash in Hand (₹)</span>}
              name="openingCashInHand"
              rules={[{ required: true, message: 'Please enter opening cash in hand' }]}
            >
              <InputNumber
                className="w-full"
                placeholder="₹ 0.00"
                min={0}
                precision={2}
                formatter={(val) => `${val}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
                parser={(val: any) => (val ? val.replace(/\$\s?|(,*)/g, '') : '')}
                size="large"
                disabled={balances?.isLocked}
              />
            </Form.Item>

            <Form.Item
              label={<span className="font-medium text-gray-700">Opening Cash in Bank (₹)</span>}
              name="openingCashInBank"
              rules={[{ required: true, message: 'Please enter opening cash in bank' }]}
            >
              <InputNumber
                className="w-full"
                placeholder="₹ 0.00"
                min={0}
                precision={2}
                formatter={(val) => `${val}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
                parser={(val: any) => (val ? val.replace(/\$\s?|(,*)/g, '') : '')}
                size="large"
                disabled={balances?.isLocked}
              />
            </Form.Item>

            <Form.Item label="Remarks" name="remarks">
              <Input.TextArea
                placeholder="E.g. Initial balance as per audit / passbook"
                rows={2}
                disabled={balances?.isLocked}
              />
            </Form.Item>

            <div className="flex justify-end gap-2 mt-4">
              <Button onClick={() => setOpeningModalVisible(false)}>
                {balances?.isLocked ? 'Close' : 'Cancel'}
              </Button>
              {!balances?.isLocked && (
                <Button type="primary" htmlType="submit" className="bg-emerald-600 hover:bg-emerald-700">
                  Save & Lock Opening Balance
                </Button>
              )}
            </div>
          </Form>
        </Modal>
      </Spin>
    </AppContainer>
  );
};

export default CashBank;
