import { useEffect, useRef, useState } from 'react';
import {
  Button,
  Form,
  Input,
  Modal,
  Popconfirm,
  Popover,
  Select,
  Space,
  Spin,
  Table,
  Tag,
  Typography,
  Alert,
  message,
} from 'antd';
import {
  PlusOutlined,
  EditOutlined,
  DeleteOutlined,
  // FilterOutlined,
  // SearchOutlined,
  UploadOutlined,
  DownloadOutlined,
} from '@ant-design/icons';
import { AppContainer } from '../../components/AppContainer';
import jwtAxios from '../../api/axiosInstance';
import { ENDPOINTS } from '../../api/endpoints';

const { Text } = Typography;

const ENTITY_LABEL = 'Vegetable';
const ENTITY_ENDPOINT = ENDPOINTS.VEGETABLES;

interface RowResult {
  row: number;
  name: string;
  status: 'imported' | 'skipped';
  reason?: string;
}

interface DataRecord {
  key: number;
  name: string;
  tamilName: string;
  status: boolean;
  isFlexible?: boolean;
}

const Vegetables = () => {
  const [form] = Form.useForm();
  const [open, setOpen] = useState(false);
  // null = "Add" mode. Holds the record's id while editing.
  const [editingId, setEditingId] = useState<string | null>(null);
  const [searchText, setSearchText] = useState('');
  // null = "All" (no status filter sent to backend)
  const [statusFilter, setStatusFilter] = useState<boolean | null>(null);
  const [data, setData] = useState<DataRecord[]>([]);
  const [loading, setLoading] = useState<boolean>(false);
  const [statuses, setStatuses] = useState<Record<string, boolean>>({});
  const [pagination, setPagination] = useState({
    current: 1,
    pageSize: Number(import.meta.env.VITE_PAGE_SIZE) || 10,
    total: 0,
    totalPages: 0
  });

  // ── Import modal state ──
  const [importOpen, setImportOpen] = useState(false);
  const [importLoading, setImportLoading] = useState(false);
  const [importFile, setImportFile] = useState<File | null>(null);
  const [importResults, setImportResults] = useState<{ importedCount: number; skippedCount: number; results: RowResult[] } | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);

  // ── Import handlers ──────────────────────────────────────────
  const handleOpenImport = () => {
    setImportFile(null);
    setImportResults(null);
    setImportOpen(true);
  };

  const handleDownloadTemplate = async () => {
    try {
      const response = await jwtAxios.get(ENDPOINTS.VEGETABLES_IMPORT_TEMPLATE, { responseType: 'blob' });
      const blob = new Blob([response.data], {
        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      });
      const url = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = 'vegetable-import-template.xlsx';
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      window.URL.revokeObjectURL(url);
    } catch {
      message.error('Failed to download template');
    }
  };

  const handleImportSave = async () => {
    if (!importFile) {
      message.warning('Please choose an Excel file first.');
      return;
    }
    setImportLoading(true);
    try {
      const formData = new FormData();
      formData.append('file', importFile);
      const res = await jwtAxios.post(ENDPOINTS.VEGETABLES_IMPORT, formData, {
        headers: { 'Content-Type': 'multipart/form-data' },
      });
      setImportResults(res.data);
      message.success(res.data.message);
      fetchData(1, pagination.pageSize, '');
    } catch (err: any) {
      message.error(err.response?.data?.message || 'Import failed');
    } finally {
      setImportLoading(false);
    }
  };

  const handleAdd = () => {
    setEditingId(null);
    form.resetFields();
    setOpen(true);
  };

  // Edit button click — GET the single record by id, then populate the
  // same form/modal used for "Add". We just switch modes with editingId.
  const handleEdit = async (id: string) => {
    setLoading(true);
    try {
      const res = await jwtAxios.get(`${ENTITY_ENDPOINT}/${id}`);
      // Adjust this line if your single-record response is wrapped
      // differently (e.g. res.data.result.data instead of res.data.result).
      const record = res.data?.result ?? res.data;

      form.setFieldsValue({
        name: record.name,
        tamilName: record.tamilName,
        status: record.status,
        hindiName: record.hindiName ?? '',
        kannadaName: record.kannadaName ?? '',
        malayalamName: record.malayalamName ?? '',
        teluguName: record.teluguName ?? '',
        hsnCode: record.hsnCode ?? '',
        isFlexible: record.isFlexible ?? false,
      });

      setEditingId(id);
      setOpen(true);
    } catch (err: any) {
      message.error(err.response?.data?.message || `Failed to load ${ENTITY_LABEL.toLowerCase()}`);
    } finally {
      setLoading(false);
    }
  };

  // -----------------------------
  // Fetch statuses — ONLY ONCE on mount. This never changes after load,
  // so it does not belong inside fetchData (which runs on every
  // search / page change).
  // -----------------------------
  const fetchStatuses = async () => {
    try {
      const statusRes = await jwtAxios.get(ENDPOINTS.STATUS);
      // Response shape is already { "Active": true, "Inactive": false }
      setStatuses(statusRes.data || {});
    } catch (err: any) {
      message.error(err.response?.data?.message || 'Failed to fetch statuses');
      setStatuses({});
    }
  };

  // -----------------------------
  // Fetch list — runs on initial load, page change, page-size change,
  // and whenever a search or status filter is triggered.
  // -----------------------------
  const fetchData = async (
    page: number = pagination.current,
    limit: number = pagination.pageSize,
    search: string = searchText,
    status: boolean | null | undefined = statusFilter
  ) => {
    setLoading(true);

    try {
      // Only add "status" to the query string when a filter is actually
      // selected. null / undefined means no status param at all.
      let url = ENTITY_ENDPOINT + `?page=${page}&limit=${limit}&search=${search}`;
      if (status !== null && status !== undefined) {
        url += `&status=${status}`; // sends true or false
      }

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

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

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

  // Initial load: statuses once + first page of records.
  useEffect(() => {
    fetchStatuses();
    fetchData(1, pagination.pageSize, '');
  }, []);

  // -----------------------------
  // Search — simple & easy to follow:
  // 1. onChange just updates the input's text (what you see typed).
  // 2. onSearch (Enter key or the search icon) actually triggers the API call,
  //    and resets pagination back to page 1 since it's a new result set.
  // No debounce, no extra state — one function does the work.
  // -----------------------------
  const handleSearch = (value: string) => {
    setSearchText(value);
    fetchData(1, pagination.pageSize, value, statusFilter);
  };

  // Status dropdown — same idea as search: pick a value, refetch from
  // page 1, using the current search text so both filters combine.
  const handleStatusFilterChange = (value: boolean | null | undefined) => {
    console.log("Changed:", value);
    const status = value ?? null;

    setStatusFilter(status);
    fetchData(1, pagination.pageSize, searchText, status);
  };

  // Delete — actual API call happens only after the user confirms
  // in the Popconfirm popup (see the Actions column below).
  const handleDelete = async (id: string) => {
    setLoading(true);
    try {
      const res = await jwtAxios.delete(`${ENTITY_ENDPOINT}/${id}`);
      message.success(res.data?.message || `${ENTITY_LABEL} deleted successfully`);
      fetchData(pagination.current, pagination.pageSize, searchText, statusFilter);
    } catch (err: any) {
      message.error(err.response?.data?.message || `Failed to delete ${ENTITY_LABEL.toLowerCase()}`);
    } finally {
      setLoading(false);
    }
  };

  const handleSubmit = async (values: any) => {
    setLoading(true);

    try {
      const payload = {
        ...values,
        hindiName: values.hindiName ?? '',
        kannadaName: values.kannadaName ?? '',
        malayalamName: values.malayalamName ?? '',
        teluguName: values.teluguName ?? '',
        hsnCode: values.hsnCode ?? '',
      };
      const response = editingId
        ? await jwtAxios.put(`${ENTITY_ENDPOINT}/${editingId}`, payload)
        : await jwtAxios.post(ENTITY_ENDPOINT, payload);

      message.success(
        response.data?.message ||
        `${ENTITY_LABEL} ${editingId ? 'updated' : 'added'} successfully`
      );
      setOpen(false);
      setEditingId(null);
      form.resetFields();
      fetchData(pagination.current, pagination.pageSize, searchText, statusFilter); // refresh current view only
    } catch (err: any) {
      const responseData = err.response?.data;
      if (responseData && responseData.errors) {
        const formFields = Object.entries(responseData.errors).map(([key, value]) => ({
          name: key,
          errors: [value as string],
        }));
        form.setFields(formFields);
      }
      message.error(
        responseData?.message ||
        `Failed to ${editingId ? 'update' : 'add'} ${ENTITY_LABEL.toLowerCase()}`
      );
    } finally {
      setLoading(false);
    }
  };

  const columns = [
    {
      title: 'ID',
      dataIndex: 'id',
    },
    {
      title: 'Name',
      dataIndex: 'name',
    },
    {
      title: 'Tamil Name',
      dataIndex: 'tamilName',
    },
    {
      title: 'Hindi Name',
      dataIndex: 'hindiName',
      render: (value: string) => value || '-', // if null show - 
    },
    {
      title: 'Kannada Name',
      dataIndex: 'kannadaName',
      render: (value: string) => value || '-', // if null show - 
    },
    {
      title: 'Malayalam Name',
      dataIndex: 'malayalamName',
      render: (value: string) => value || '-', // if null show - 
    },
    {
      title: 'Telugu Name',
      dataIndex: 'teluguName',
      render: (value: string) => value || '-', // if null show - 
    },
    {
      title: 'HSN Code',
      dataIndex: 'hsnCode',
      render: (value: string) => <Tag color="blue">{value || '-'}</Tag>, // if null show - displayed in Tag
    },
    {
      title: 'Type',
      dataIndex: 'isFlexible',
      render: (isFlexible: boolean) => (
        <Tag color={isFlexible ? 'purple' : 'default'}>
          {isFlexible ? 'Flexible / Pieces' : 'Standard'}
        </Tag>
      ),
    },
    {
      title: 'Status',
      dataIndex: 'status',
      render: (status: boolean) => (
        <Tag color={status ? 'green' : 'red'}>{status ? 'Active' : 'Inactive'}</Tag>
      ),
    },
    {
      title: 'Actions',
      render: (_: any, record: any) => (
        <Space>
          <Popover content={"Edit"}>
            <Button type="link" icon={<EditOutlined />} onClick={() => handleEdit(record.id)} />
          </Popover>
          <Popover content={"Delete"}>
            <Popconfirm
              title={`Delete ${ENTITY_LABEL.toLowerCase()}`}
              description={`Are you sure you want to delete "${record.name}"?`}
              okText="Delete"
              cancelText="Cancel"
              okButtonProps={{ danger: true }}
              onConfirm={() => handleDelete(record.id)} // API call fires only after confirm
            >
              <Button danger type="link" icon={<DeleteOutlined />} />
            </Popconfirm>
          </Popover>
        </Space>
      ),
    },
  ];

  return (
    <div>
      <Spin spinning={loading}>
        <AppContainer
          title={`${ENTITY_LABEL}`}
          headerAction={
            <Space>
              <Button
                icon={<UploadOutlined />}
                onClick={handleOpenImport}
              >
                Import
              </Button>
              <Button
                type="primary"
                icon={<PlusOutlined />}
                onClick={handleAdd}
                className="bg-green-600"
              >
                Add {ENTITY_LABEL}
              </Button>
            </Space>
          }
        >
          {/* Toolbar Section */}
          <div className="flex justify-between items-center mb-4 pb-4 border-b border-gray-200">
            <Space>
              <Select
                placeholder="Status"
                allowClear
                style={{ width: 150 }}
                value={statusFilter}
                onChange={handleStatusFilterChange}
                options={Object.entries(statuses).map(([label, value]) => ({
                  label,
                  value,
                }))}
              />
              <Input.Search
                placeholder="Search..."
                value={searchText}
                onChange={(e) => {
                  const val = e.target.value;
                  setSearchText(val);
                  if (!val) {
                    handleSearch('');
                  }
                }}
                onSearch={handleSearch}
                allowClear
                style={{ width: 200 }}
              />
            </Space>
          </div>

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

        <Modal
          title={editingId ? `Edit ${ENTITY_LABEL}` : `Add ${ENTITY_LABEL}`}
          open={open}
          onCancel={() => {
            setOpen(false);
            setEditingId(null);
          }}
          onOk={() => form.submit()}
          confirmLoading={loading}
          okText="Submit"
        >
          <Form form={form} layout="vertical" onFinish={handleSubmit}>
            <Form.Item label="Name" name="name" rules={[{ required: true }]}>
              <Input />
            </Form.Item>

            <Form.Item label="Tamil Name" name="tamilName" rules={[{ required: true, message: "Tamil Name is required", max: 150 }]}>
              <Input />
            </Form.Item>

            <Form.Item label="Hindi Name" name="hindiName" rules={[{ required: true, message: "Hindi Name is required", max: 150 }]}>
              <Input />
            </Form.Item>

            <Form.Item label="Kannada Name" name="kannadaName" rules={[{ max: 150 }]}>
              <Input />
            </Form.Item>

            <Form.Item label="Malayalam Name" name="malayalamName" rules={[{ max: 150 }]}>
              <Input />
            </Form.Item>

            <Form.Item label="Telugu Name" name="teluguName" rules={[{ max: 150 }]}>
              <Input />
            </Form.Item>

            <Form.Item
              label="HSN Code"
              name="hsnCode"
              rules={[
                { required: true, message: "HSN Code is required" },
                { pattern: /^\d+$/, message: "HSN Code must contain digits only" },
                {
                  validator: (_, value) => {
                    if (value && /^0+$/.test(value)) {
                      return Promise.reject(new Error("HSN Code cannot be 0"));
                    }
                    return Promise.resolve();
                  },
                },
              ]}
            >
              <Input
                maxLength={15}
                placeholder="Ex.07099300"
                onKeyPress={(e) => {
                  if (!/[0-9]/.test(e.key)) {
                    e.preventDefault();
                  }
                }}
                onChange={(e) => {
                  const val = e.target.value.replace(/\D/g, '');
                  form.setFieldValue('hsnCode', val);
                }}
              />
            </Form.Item>

            <Form.Item
              label="Status"
              name="status"
              initialValue={true}
              rules={[{ required: true }]}
            >
              <Select
                options={Object.entries(statuses).map(([label, value]) => ({
                  label,
                  value, // boolean
                }))}
              />
            </Form.Item>

            <Form.Item
              label="Lot & Sale Behavior"
              name="isFlexible"
              initialValue={false}
              tooltip={
                editingId
                  ? "Lot & sale behavior cannot be changed once created."
                  : "Flexible produce allows selling in Pieces/Thaar and lots are closed manually."
              }
            >
              <Select
                disabled={Boolean(editingId)}
                options={[
                  { label: 'Standard Produce (Strict auto-depletion by KG/Bag)', value: false },
                  { label: 'Flexible Produce (Sold in Pieces/Thaar, Manual Close)', value: true },
                ]}
              />
            </Form.Item>
          </Form>
        </Modal>

        {/* ── Bulk Import Modal ── */}
        <Modal
          title="Vegetable Bulk Import"
          open={importOpen}
          onCancel={() => setImportOpen(false)}
          footer={null}
          width={780}
          destroyOnHidden
        >
          <div style={{ display: 'flex', gap: 24 }}>
            {/* Left panel */}
            <div style={{ flex: 1 }}>
              <div style={{ marginBottom: 16 }}>
                <Text strong>Upload File <span style={{ color: 'red' }}>*</span></Text>
                <div style={{ marginTop: 8, display: 'flex', alignItems: 'center', gap: 8 }}>
                  <Button
                    icon={<UploadOutlined />}
                    onClick={() => fileInputRef.current?.click()}
                    style={{ background: '#1d1b4b', color: '#fff', border: 'none' }}
                  >
                    CHOOSE FILE
                  </Button>
                  <Text type={importFile ? 'success' : 'secondary'}>
                    {importFile ? importFile.name : 'No file chosen'}
                  </Text>
                  <input
                    ref={fileInputRef}
                    type="file"
                    accept=".xlsx"
                    style={{ display: 'none' }}
                    onChange={(e) => {
                      const file = e.target.files?.[0] ?? null;
                      setImportFile(file);
                      setImportResults(null);
                      e.target.value = '';
                    }}
                  />
                </div>
              </div>

              <Button
                icon={<DownloadOutlined />}
                type="link"
                style={{ paddingLeft: 0, marginBottom: 16 }}
                onClick={handleDownloadTemplate}
              >
                Download Template
              </Button>

              {/* Import results summary */}
              {importResults && (
                <div style={{ marginBottom: 12 }}>
                  <Alert
                    type={importResults.skippedCount > 0 ? 'warning' : 'success'}
                    title={`${importResults.importedCount} imported, ${importResults.skippedCount} skipped`}
                    style={{ marginBottom: 8 }}
                  />
                  {importResults.results.filter(r => r.status === 'skipped').length > 0 && (
                    <div style={{ maxHeight: 160, overflowY: 'auto', fontSize: 12 }}>
                      {importResults.results.filter(r => r.status === 'skipped').map(r => (
                        <div key={r.row} style={{ color: '#cf1322', marginBottom: 4 }}>
                          Row {r.row} — <strong>{r.name}</strong>: {r.reason}
                        </div>
                      ))}
                    </div>
                  )}
                </div>
              )}

              <div style={{ display: 'flex', gap: 12, marginTop: 8 }}>
                <Button danger onClick={() => setImportOpen(false)} style={{ flex: 1 }}>
                  Cancel
                </Button>
                <Button
                  type="primary"
                  loading={importLoading}
                  onClick={handleImportSave}
                  style={{ flex: 1, background: '#1d1b4b', border: 'none' }}
                >
                  Save
                </Button>
              </div>
            </div>

            {/* Right panel — instructions */}
            <div
              className="
                flex-1
                bg-[#fafafa]
                border border-[#e8e8e8]
                rounded-lg
                p-4
                text-[13px]
              "
            >
              <Text strong>Important Instructions:</Text>
              <ul style={{ marginTop: 10, paddingLeft: 18, lineHeight: 2 }}>
                <li>Upload only Excel (.xlsx) files.</li>
                <li>All required columns must be present in the sheet.</li>
                <li>Maximum file size: 5 MB.</li>
                <li style={{ color: '#cf1322' }}>
                  You can upload / import only <strong>new vegetables</strong> — they must not already exist in this software.
                </li>
                <li><strong>Name</strong> is required and must be unique.</li>
                <li><strong>HSN Code</strong> must be numeric only (max 15 digits).</li>
                <li>All imported vegetables are set to <strong>Active</strong> by default.</li>
                <li><strong>Tamil Name</strong> and <strong>Hindi Name</strong> are required.</li>
              </ul>
            </div>
          </div>
        </Modal>
      </Spin>
    </div>
  );
};

export default Vegetables;