import { useEffect, useState } from 'react';
import {
  DatePicker,
  Input,
  Select,
  Space,
  Spin,
  Table,
  message,
  Tag,
  Button,
  Row,
  Col,
} from 'antd';
import { DownloadOutlined, FilePdfOutlined, RedoOutlined } from '@ant-design/icons';
import dayjs, { Dayjs } from 'dayjs';
import { AppContainer } from '../../components/AppContainer';
import jwtAxios from '../../api/axiosInstance';
import { ENDPOINTS } from '../../api/endpoints';
import SummaryCard from '../../components/SummaryCard';

const ENTITY_LABEL = 'Final Stock Report';
const ENTITY_ENDPOINT = ENDPOINTS.STOCK_FINAL_REPORT;
const ENTITY_EXPORT = ENDPOINTS.STOCK_FINAL_EXPORT;
const ENTITY_EXPORT_PDF = ENDPOINTS.STOCK_FINAL_EXPORT_PDF;

interface NamedOption {
  id: string;
  name: string;
}

const { RangePicker } = DatePicker;

const StockReport = () => {
  const [searchText, setSearchText] = useState('');
  const [dateRange, setDateRange] = useState<[Dayjs, Dayjs] | null>(null);
  const [supplierId, setSupplierId] = useState<string | undefined>(undefined);
  const [vegetableId, setVegetableId] = useState<string | undefined>(undefined);

  const [data, setData] = useState<any[]>([]);
  const [loading, setLoading] = useState<boolean>(false);
  const [exportLoading, setExportLoading] = useState<boolean>(false);
  const [exportPdfLoading, setExportPdfLoading] = useState<boolean>(false);

  const [suppliers, setSuppliers] = useState<NamedOption[]>([]);
  const [vegetables, setVegetables] = useState<NamedOption[]>([]);

  // KPI Summary calculations
  const [summary, setSummary] = useState({
    totalPurchasedKg: 0,
    totalWholesaleSalesKg: 0,
    totalWholesaleSpoilageKg: 0,
    totalRetailAllocatedKg: 0,
    totalRetailSalesKg: 0,
    totalRetailSpoilageKg: 0,
    totalRetailReturnedKg: 0,
    totalWholesaleBalanceKg: 0,
    totalRetailBalanceKg: 0,
    totalNetAvailableStockKg: 0,
  });

  const [pagination, setPagination] = useState({
    current: 1,
    pageSize: Number(import.meta.env.VITE_PAGE_SIZE) || 10,
    total: 0,
    totalPages: 0,
  });

  // Fetch filter metadata
  const fetchMeta = async () => {
    try {
      const res = await jwtAxios.get(ENDPOINTS.PURCHASE_META);
      const result = res.data?.result || {
        suppliers: [],
        vegetables: [],
      };
      setSuppliers(result.suppliers || []);
      setVegetables(result.vegetables || []);
    } catch (err: any) {
      message.error(err.response?.data?.message || 'Failed to fetch filter options');
      setSuppliers([]);
      setVegetables([]);
    }
  };

  const fetchData = async (
    page: number = pagination.current,
    limit: number = pagination.pageSize,
    search: string = searchText,
    range: [Dayjs, Dayjs] | null = dateRange,
    supplier: string | null | undefined = supplierId,
    vegetable: string | null | undefined = vegetableId
  ) => {
    setLoading(true);

    try {
      let url = `${ENTITY_ENDPOINT}?page=${page}&limit=${limit}&search=${search}`;
      if (range) {
        url += `&dateFrom=${range[0].format('YYYY-MM-DD')}&dateTo=${range[1].format('YYYY-MM-DD')}`;
      }
      if (supplier) {
        url += `&supplierId=${supplier}`;
      }
      if (vegetable) {
        url += `&vegetableId=${vegetable}`;
      }

      const res = await jwtAxios.get(url);
      const records = res.data?.result?.data || [];
      const metaInfo = res.data?.result?.meta || {};
      const summaryInfo = res.data?.result?.sum || res.data?.result?.summary || {};

      const formattedData = records.map((item: any, idx: number) => ({
        key: item.id || idx,
        ...item,
      }));

      setData(formattedData);

      // If backend provides summary statistics, set them, otherwise calculate locally
      if (res.data?.result?.sum || res.data?.result?.summary) {
        setSummary({
          totalPurchasedKg: Number(summaryInfo.purchasedQty ?? summaryInfo.totalPurchasedKg ?? 0),
          totalWholesaleSalesKg: Number(summaryInfo.wholesaleSalesQty ?? summaryInfo.totalWholesaleSalesKg ?? 0),
          totalWholesaleSpoilageKg: Number(summaryInfo.wholesaleSpoilageQty ?? summaryInfo.totalWholesaleSpoilageKg ?? 0),
          totalRetailAllocatedKg: Number(summaryInfo.retailAllocatedQty ?? summaryInfo.totalRetailAllocatedKg ?? 0),
          totalRetailSalesKg: Number(summaryInfo.retailSalesQty ?? summaryInfo.totalRetailSalesKg ?? 0),
          totalRetailSpoilageKg: Number(summaryInfo.retailSpoilageQty ?? summaryInfo.totalRetailSpoilageKg ?? 0),
          totalRetailReturnedKg: Number(summaryInfo.retailReturnedQty ?? summaryInfo.totalRetailReturnedKg ?? 0),
          totalWholesaleBalanceKg: Number(summaryInfo.wholesaleRemainingQty ?? summaryInfo.totalWholesaleBalanceKg ?? 0),
          totalRetailBalanceKg: Number(summaryInfo.retailRemainingQty ?? summaryInfo.totalRetailBalanceKg ?? 0),
          totalNetAvailableStockKg: Number(
            (summaryInfo.wholesaleRemainingQty ?? summaryInfo.totalWholesaleBalanceKg ?? 0) +
            (summaryInfo.retailRemainingQty ?? summaryInfo.totalRetailBalanceKg ?? 0)
          ),
        });
      } else {
        // Fallback aggregate from local records
        const localSummary = formattedData.reduce(
          (acc: any, item: any) => {
            acc.totalPurchasedKg += Number(item.quantity || 0);
            acc.totalWholesaleSalesKg += Number(item.wholesaleSalesQty || 0);
            acc.totalWholesaleSpoilageKg += Number(item.wholesaleSpoilageQty || 0);
            acc.totalRetailAllocatedKg += Number(item.retailAllocatedQty || 0);
            acc.totalRetailSalesKg += Number(item.retailSalesQty || 0);
            acc.totalRetailSpoilageKg += Number(item.retailSpoilageQty || 0);
            acc.totalRetailReturnedKg += Number(item.retailReturnedQty || 0);
            acc.totalWholesaleBalanceKg += Number(item.remainingQuantity || item.wholesaleBalanceKg || 0);
            acc.totalRetailBalanceKg += Number(item.retailRemainingQty || item.retailBalanceKg || 0);
            return acc;
          },
          {
            totalPurchasedKg: 0,
            totalWholesaleSalesKg: 0,
            totalWholesaleSpoilageKg: 0,
            totalRetailAllocatedKg: 0,
            totalRetailSalesKg: 0,
            totalRetailSpoilageKg: 0,
            totalRetailReturnedKg: 0,
            totalWholesaleBalanceKg: 0,
            totalRetailBalanceKg: 0,
          }
        );
        localSummary.totalNetAvailableStockKg = localSummary.totalWholesaleBalanceKg + localSummary.totalRetailBalanceKg;
        setSummary(localSummary);
      }

      setPagination((prev) => ({
        ...prev,
        current: metaInfo.page ?? page,
        pageSize: metaInfo.limit ?? limit,
        total: metaInfo.total ?? prev.total,
        totalPages: metaInfo.totalPages ?? prev.totalPages,
      }));
    } catch (err: any) {
      message.error(err.response?.data?.message || 'Failed to fetch final stock report');
      setData([]);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchMeta();
    fetchData(1, pagination.pageSize, '', null, undefined, undefined);
  }, []);

  const handleExport = async () => {
    if (!data || data.length === 0) {
      message.warning('No data available to export');
      return;
    }
    setExportLoading(true);
    try {
      const params = new URLSearchParams();
      if (searchText) params.set('search', searchText);
      if (dateRange) {
        params.set('dateFrom', dateRange[0].format('YYYY-MM-DD'));
        params.set('dateTo', dateRange[1].format('YYYY-MM-DD'));
      }
      if (supplierId) params.set('supplierId', supplierId);
      if (vegetableId) params.set('vegetableId', vegetableId);

      const url = `${ENTITY_EXPORT}${params.toString() ? '?' + params.toString() : ''}`;
      const response = await jwtAxios.get(url, { responseType: 'blob' });

      const disposition = response.headers['content-disposition'];
      let fileName = `final-stock-report-${dayjs().format('YYYY-MM-DD')}.xlsx`;
      if (disposition) {
        const match = disposition.match(/filename\*?=(?:UTF-8'')?"?([^"\n;]+)"?/i);
        if (match?.[1]) fileName = decodeURIComponent(match[1]);
      }

      const blob = new Blob([response.data], {
        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      });
      const objectUrl = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = objectUrl;
      link.download = fileName;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      window.URL.revokeObjectURL(objectUrl);

      message.success('Final stock report exported successfully');
    } catch (err: any) {
      message.error(err.response?.data?.message || 'Failed to export final stock report');
    } finally {
      setExportLoading(false);
    }
  };

  const handleExportPdf = async () => {
    if (!data || data.length === 0) {
      message.warning('No data available to export');
      return;
    }
    setExportPdfLoading(true);
    try {
      const params = new URLSearchParams();
      if (searchText) params.set('search', searchText);
      if (dateRange) {
        params.set('dateFrom', dateRange[0].format('YYYY-MM-DD'));
        params.set('dateTo', dateRange[1].format('YYYY-MM-DD'));
      }
      if (supplierId) params.set('supplierId', supplierId);
      if (vegetableId) params.set('vegetableId', vegetableId);

      const url = `${ENTITY_EXPORT_PDF}${params.toString() ? '?' + params.toString() : ''}`;
      const response = await jwtAxios.get(url, { responseType: 'blob' });

      const disposition = response.headers['content-disposition'];
      let fileName = `stock-report-${dayjs().format('YYYY-MM-DD')}.pdf`;
      if (disposition) {
        const match = disposition.match(/filename\*?=(?:UTF-8'')?"?([^"\n;]+)"?/i);
        if (match?.[1]) fileName = decodeURIComponent(match[1]);
      }

      const blob = new Blob([response.data], { type: 'application/pdf' });
      const objectUrl = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = objectUrl;
      link.download = fileName;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      window.URL.revokeObjectURL(objectUrl);

      message.success('Stock report PDF exported successfully');
    } catch (err: any) {
      message.error(err.response?.data?.message || 'Failed to export stock report PDF');
    } finally {
      setExportPdfLoading(false);
    }
  };

  const handleResetFilters = () => {
    setSearchText('');
    setDateRange(null);
    setSupplierId(undefined);
    setVegetableId(undefined);
    fetchData(1, pagination.pageSize, '', null, null, null);
  };

  const columns = [
    {
      title: 'S.No',
      render: (_: any, __: any, index: number) => (pagination.current - 1) * pagination.pageSize + index + 1,
      width: 55,
    },
    {
      title: 'Lot No',
      dataIndex: 'lotNo',
      ellipsis: true,
      render: (text: string) => <Tag color="blue">{text || '-'}</Tag>,
    },
    {
      title: 'Vegetable',
      render: (_: any, record: any) => record.vegetable?.name || record.vegetableName || '-',
    },
    {
      title: 'Supplier',
      render: (_: any, record: any) =>
        record.supplier?.name || record.cashSupplierName || record.supplierName || record.quickSupplierName || '-',
    },
    {
      title: 'Purchased Qty',
      dataIndex: 'quantity',
      render: (qty: any, record: any) => {
        const isBagOnly = record.unit !== 'KG' && Number(record.quantity || 0) === 0;
        const unitLabel = isBagOnly ? (record.unit === 'BOX' ? 'BOX' : 'BAG') : 'KG';
        const displayQty = isBagOnly ? Number(record.bags || 0) : Number(qty || 0);
        return <Tag color="purple">{displayQty} {unitLabel}</Tag>;
      },
    },
    {
      title: 'Wholesale Sales',
      dataIndex: 'wholesaleSalesQty',
      render: (qty: any, record: any) => {
        const isBagOnly = record.unit !== 'KG' && Number(record.quantity || 0) === 0;
        const unitLabel = isBagOnly ? (record.unit === 'BOX' ? 'BOX' : 'BAG') : 'KG';
        return <span>{Number(qty || 0)} {unitLabel}</span>;
      },
    },
    {
      title: 'Wholesale Spoilage',
      dataIndex: 'wholesaleSpoilageQty',
      render: (qty: any, record: any) => {
        const isBagOnly = record.unit !== 'KG' && Number(record.quantity || 0) === 0;
        const displayUnit = isBagOnly ? 'BAG' : 'KG';
        const val = Number(qty || 0);
        return val > 0 ? <Tag color="red">{val} {displayUnit}</Tag> : <span>0 {displayUnit}</span>;
      },
    },
    {
      title: 'Allocated to Retail',
      dataIndex: 'retailAllocatedQty',
      render: (qty: any, record: any) => {
        const isBagOnly = record.unit !== 'KG' && Number(record.quantity || 0) === 0;
        const displayUnit = isBagOnly ? 'BAG' : 'KG';
        const val = Number(qty || 0);
        return val > 0 ? <Tag color="cyan">{val} {displayUnit}</Tag> : <span>0 {displayUnit}</span>;
      },
    },
    {
      title: 'Retail Sales',
      dataIndex: 'retailSalesQty',
      render: (qty: any, record: any) => {
        const isBagOnly = record.unit !== 'KG' && Number(record.quantity || 0) === 0;
        const displayUnit = isBagOnly ? 'BAG' : 'KG';
        const val = Number(qty || 0);
        return val > 0 ? <Tag color="geekblue">{val} {displayUnit}</Tag> : <span>0 {displayUnit}</span>;
      },
    },
    {
      title: 'Retail Spoilage',
      dataIndex: 'retailSpoilageQty',
      render: (qty: any, record: any) => {
        const isBagOnly = record.unit !== 'KG' && Number(record.quantity || 0) === 0;
        const displayUnit = isBagOnly ? 'BAG' : 'KG';
        const val = Number(qty || 0);
        return val > 0 ? <Tag color="volcano">{val} {displayUnit}</Tag> : <span>0 {displayUnit}</span>;
      },
    },
    {
      title: 'Retail Returns',
      dataIndex: 'retailReturnedQty',
      render: (qty: any, record: any) => {
        const isBagOnly = record.unit !== 'KG' && Number(record.quantity || 0) === 0;
        const displayUnit = isBagOnly ? 'BAG' : 'KG';
        const val = Number(qty || 0);
        return val > 0 ? <Tag color="orange">{val} {displayUnit}</Tag> : <span>0 {displayUnit}</span>;
      },
    },
    {
      title: 'Wholesale Balance',
      render: (_: any, record: any) => {
        const isBagOnly = record.unit !== 'KG' && Number(record.quantity || 0) === 0;
        const displayUnit = isBagOnly ? 'BAG' : 'KG';
        const rem = isBagOnly ? Number(record.remainingBags ?? 0) : Number(record.remainingQuantity ?? record.wholesaleBalanceKg ?? 0);
        return <Tag color={rem === 0 ? 'red' : 'green'}>{rem} {displayUnit}</Tag>;
      },
    },
    {
      title: 'Retail Balance',
      render: (_: any, record: any) => {
        const isBagOnly = record.unit !== 'KG' && Number(record.quantity || 0) === 0;
        const displayUnit = isBagOnly ? 'BAG' : 'KG';
        const rem = Number(record.retailRemainingQty ?? record.retailBalanceKg ?? 0);
        return <Tag color={rem === 0 ? 'red' : 'cyan'}>{rem} {displayUnit}</Tag>;
      },
    },
    {
      title: 'Net Total Stock',
      render: (_: any, record: any) => {
        const isBagOnly = record.unit !== 'KG' && Number(record.quantity || 0) === 0;
        const displayUnit = isBagOnly ? 'BAG' : 'KG';
        const wholesaleRem = isBagOnly ? Number(record.remainingBags ?? 0) : Number(record.remainingQuantity ?? record.wholesaleBalanceKg ?? 0);
        const retailRem = Number(record.retailRemainingQty ?? record.retailBalanceKg ?? 0);
        const total = wholesaleRem + retailRem;
        return <Tag color={total === 0 ? 'red' : 'gold'} className="font-bold">{total} {displayUnit}</Tag>;
      },
    },
  ];

  return (
    <div>
      <Spin spinning={loading}>
        <AppContainer
          title={ENTITY_LABEL}
          headerAction={
            <Space>
              <Button
                icon={<DownloadOutlined />}
                style={{ color: '#52c41a', borderColor: '#52c41a' }}
                onClick={handleExport}
                loading={exportLoading}
              >
                Export Excel
              </Button>
              <Button
                icon={<FilePdfOutlined />}
                style={{ color: '#ff4d4f', borderColor: '#ff4d4f' }}
                onClick={handleExportPdf}
                loading={exportPdfLoading}
              >
                Export PDF
              </Button>
            </Space>
          }
        >
          {/* Summary Cards */}
          <Row gutter={[16, 16]} className="mb-6">
            <Col xs={24} sm={12} md={6}>
              <SummaryCard
                label="Purchased Inward (KG)"
                value={summary.totalPurchasedKg}
                showCurrency={false}
                color="#722ed1"
                icon={<DownloadOutlined />}
              />
            </Col>
            <Col xs={24} sm={12} md={6}>
              <SummaryCard
                label="Wholesale Sales (KG)"
                value={summary.totalWholesaleSalesKg}
                showCurrency={false}
                color="#1677ff"
                icon={<RedoOutlined />}
              />
            </Col>
            <Col xs={24} sm={12} md={6}>
              <SummaryCard
                label="Retail Allocated (KG)"
                value={summary.totalRetailAllocatedKg}
                showCurrency={false}
                color="#fa8c16"
                icon={<DownloadOutlined />}
              />
            </Col>
            <Col xs={24} sm={12} md={6}>
              <SummaryCard
                label="Stock In-Hand (KG)"
                value={summary.totalNetAvailableStockKg}
                showCurrency={false}
                color="#52c41a"
                icon={<RedoOutlined />}
              />
            </Col>
          </Row>

          {/* Filter Bar */}
          <div className="flex flex-wrap justify-between items-center gap-3 mb-4 pb-4 border-b border-gray-200">
            <Space wrap>
              <RangePicker
                value={dateRange as any}
                onChange={(dates) => {
                  const range = dates ? (dates as [Dayjs, Dayjs]) : null;
                  setDateRange(range);
                  fetchData(1, pagination.pageSize, searchText, range, supplierId, vegetableId);
                }}
              />

              <Select
                placeholder="Select Vegetable"
                allowClear
                showSearch
                value={vegetableId}
                style={{ width: 180 }}
                optionFilterProp="label"
                filterOption={(input, option) =>
                  (option?.label ?? '').toString().toLowerCase().includes(input.toLowerCase())
                }
                options={vegetables.map((v) => ({ label: v.name, value: v.id }))}
                onChange={(val) => {
                  setVegetableId(val);
                  fetchData(1, pagination.pageSize, searchText, dateRange, supplierId, val ?? null);
                }}
              />

              <Select
                placeholder="Select Supplier"
                allowClear
                showSearch
                value={supplierId}
                style={{ width: 180 }}
                optionFilterProp="label"
                filterOption={(input, option) =>
                  (option?.label ?? '').toString().toLowerCase().includes(input.toLowerCase())
                }
                options={suppliers.map((s) => ({ label: s.name, value: s.id }))}
                onChange={(val) => {
                  setSupplierId(val);
                  fetchData(1, pagination.pageSize, searchText, dateRange, val ?? null, vegetableId);
                }}
              />

              <Input.Search
                placeholder="Search Lot No..."
                value={searchText}
                onChange={(e) => {
                  const val = e.target.value;
                  setSearchText(val);
                  if (!val) {
                    fetchData(1, pagination.pageSize, '', dateRange, supplierId, vegetableId);
                  }
                }}
                onSearch={(val) => fetchData(1, pagination.pageSize, val, dateRange, supplierId, vegetableId)}
                allowClear
                style={{ width: 180 }}
              />
            </Space>

            <Button icon={<RedoOutlined />} onClick={handleResetFilters}>
              Reset Filters
            </Button>
          </div>

          {/* Table */}
          <Table
            rowKey="key"
            columns={columns}
            dataSource={data}
            loading={loading}
            scroll={{ x: 'max-content', y: 450 }}
            pagination={{
              current: pagination.current,
              pageSize: pagination.pageSize,
              total: pagination.total,
              showSizeChanger: true,
            }}
            onChange={(pageInfo) => {
              fetchData(pageInfo.current!, pageInfo.pageSize!, searchText, dateRange, supplierId, vegetableId);
            }}
          />
          <div className="text-center mt-2">
            <Tag color="cyan">
              Page {pagination.current} of {pagination.totalPages}
            </Tag>
          </div>
        </AppContainer>
      </Spin>
    </div>
  );
};

export default StockReport;
