import React, { useState, useEffect, useRef } from 'react';
import { Table, DatePicker, Card, Form, Select, Input, Button, Row, Col, Spin } from 'antd';
import { ColumnProps } from 'antd/lib/table';
import Highlighter from 'react-highlight-words';
import { SearchOutlined,DownloadOutlined } from '@ant-design/icons';
import { SoPackingStatusDto } from '@gtpl/shared-models/procurement-management';
import { SaleOrderDropDownDto, SoPackingStatusRequest } from '@gtpl/shared-models/sale-management';
import { SaleOrderService } from '@gtpl/shared-services/sale-management';
import { AlertMessages } from '@gtpl/shared-utils/alert-messages';
import { ItemsDropDownDto, ItemSubCategoryDropDownDto, PlantsDropDown, SubCatReqForCategoryId } from '@gtpl/shared-models/masters';
import { ItemsService, ItemSubCategoryService, UnitcodeService } from '@gtpl/shared-services/masters';
import { Excel } from 'antd-table-saveas-excel';
import moment from 'moment';

export interface SoPackingStatusProps {
  isUpdate: boolean;
}

export function SoPackingStatus(
  props: SoPackingStatusProps) {
  const [page, setPage] = React.useState(1);
  const { RangePicker } = DatePicker;
  const [loading, setLoading] = useState(true)
  const searchInput = useRef(null);
  const [searchText, setSearchText] = useState('');
  const [searchedColumn, setSearchedColumn] = useState('');
  const [soPackingStatusData, setSoPackingStatusData] = useState<SoPackingStatusDto[]>([])
  const [soDropFilter, setSoDropFilter] = useState<SoPackingStatusDto[]>([])
  const [itemSubDrop, setItemSubDrop] = useState<SoPackingStatusDto[]>([])
  const [itemDrop, setItemDrop] = useState<SoPackingStatusDto[]>([])
  const [form] = Form.useForm();
  const { Option } = Select;
  
  const [subCategoryData, setSubCategoryData] = useState<ItemSubCategoryDropDownDto[]>([]);
  const [plantData, setPlantData] = useState<PlantsDropDown[]>([]);
  const [selectedEstimatedFromDate, setSelectedEstimatedFromDate] = useState(undefined);
  const [selectedEstimatedToDate, setSelectedEstimatedToDate] = useState(undefined);
  const [soItemData, setSoItemData] = useState<SaleOrderDropDownDto[]>([]);
  const [filtersData, setFiltersData] = useState<any[]>([]);
  const [display, setDisplay] = useState<string>('none');
  const [pageSize, setPageSize] = useState<number>(null);
  const [disable,setDisable]=useState<boolean>(false);
  const [items, setItems] = useState<ItemsDropDownDto[]>([]);


  const subCategoryService = new ItemSubCategoryService();
  const unitsService = new UnitcodeService()
  const service = new SaleOrderService();
  const itemService = new ItemsService();


  useEffect(() => {
    getItemSubDropForSoPackStatusReport()
    getItemDropForSoPackStatusReport();
    getSoDropForSoPackStatusReport();
    getAllPlants();

    setTimeout(() => setLoading(false), 1000);
    if (Number(localStorage.getItem('unit_id')) != 5) {
      form.setFieldsValue({ unitId: Number(localStorage.getItem('unit_id')) })
    }
    form.setFieldsValue({
      fromDate: [(moment(moment().format("YYYY-MM-DD")).subtract(1,'months')),moment(moment().format("YYYY-MM-DD"))] 
    })
    setSelectedEstimatedFromDate((moment(moment().format("YYYY-MM-DD")).subtract(1,'months')))
      setSelectedEstimatedToDate(moment(moment().format("YYYY-MM-DD")))
  }, []);

  const exportExcel = () => {
    const excel = new Excel();
    excel
      .addSheet('SoPackingStatus')
      .addColumns(data)
      .addDataSource(soPackingStatusData,{str2num:true})
      .saveAs('sopacking-status-report.xlsx');
  }
  const data = [
    { title: "Customer PO", dataIndex: "saleOrderNo" },
    { title: "ETD", dataIndex: "etd" , render: (value, record) => (record.etd ? moment(record.etd).format('YYYY-MM-DD') : '-') },
    { title: "Packing Sub category", dataIndex: "packingSubCategory" },
    { title: "Item Name", dataIndex: "item" },
    { title: "BOM Quantity", dataIndex: "requiredQty" , render: (value,record) =>  {return Math.round(value);} },
    { title: "PO Quantity", dataIndex: "poQty" , render: (value,record) =>  {return Math.round(value);}},
    { title: "Received Quantity", dataIndex: "receivedQty" , render: (value,record) =>  {return Math.round(value);} },
    { title: "Assigned Quantity", dataIndex: "assignedQty" , render: (value,record) =>  {return Math.round(value);} },
    { title: "Issued Quantity", dataIndex: "issuedQty" , render: (value,record) =>  {return Math.round(value);}},
    { title: "Returned Quantity", dataIndex: "returnedQty" , render: (value,record) =>  {return Math.round(value);}},
    { title: "Actual Issued Quantity", dataIndex: "actualIssuedQty" , render: (value,record) =>  {return Math.round(value);} },
    { title: "FG Quantity", dataIndex: "fgQty" , render: (value,record) =>  {return Math.round(value);} },
    // { title: "Excess(+)/Shortage Quantity(-)", dataIndex: "exceeOrShortageQty" },
    { title: "Production Quantity", dataIndex: "productionQty" , render: (value,record) =>  {return Math.round(value);}},
    { title: "Available Quantity", dataIndex: "availableQty" , render: (value,record) =>  {return Math.round(value);}},
    { title: "Balance", dataIndex: "Balance" , render: (value,record) =>  {return Math.round(value);}},
  ];




  const EstimatedETDDate = (value) => {
    console.log(value, 'value')
    if (value) {
      const fromDate = new Date(value[0].format('YYYY-MM-DD'));
      const toDate = new Date(value[1].format('YYYY-MM-DD'));
      setSelectedEstimatedFromDate(fromDate)
      setSelectedEstimatedToDate(toDate)
    }
  }

  const getSoPackingStatus = (onReset?: boolean) => {
    setDisable(true);
    setLoading(true);
    const req = new SoPackingStatusRequest();
    let unitId = form.getFieldValue('unitId');
    let saleOrderId = form.getFieldValue('saleOrderId');
    let itemSubCategoryId = form.getFieldValue('itemSubCategoryId');
    let itemNameId = form.getFieldValue('item');
    let selectedData = filtersData;
    req.unitId = unitId;
    req.itemSubCategoryId = itemSubCategoryId
    req.fromDate = onReset ? undefined : selectedEstimatedFromDate;
    req.toDate = onReset ? undefined : selectedEstimatedToDate;
    req.saleOrderId = saleOrderId;
    req.itemNameId = itemNameId;
    service.getSoPackingStatus(req).then((res) => {
      setDisable(false);
      if (Number(localStorage.getItem('unit_id')) != 5) {
        req.unitId = Number(localStorage.getItem('unit_id'));
      } else {
        if (form.getFieldValue('unitId') != undefined) {
          req.unitId = form.getFieldValue('unitId')
        }};
      if (res.status) {
        setLoading(false);
        setSoPackingStatusData(res.data)
        setDisable(false);
        setFiltersData(res.data)
        setDisplay('block');
        AlertMessages.getSuccessMessage(res.internalMessage);
      } else {
        if (res.intlCode) {
          setSoPackingStatusData([]);
          setLoading(false);
          setDisable(false);
          AlertMessages.getErrorMessage(res.internalMessage);
        }
      }
    }).catch(err => {
      setSoPackingStatusData([]);
      setLoading(false);
      setDisable(false);
    })
    setSoPackingStatusData(selectedData);
  }



  const getSoDropForSoPackStatusReport = () => {
    service.getSoDropForSoPackStatusReport({unitId:Number(localStorage.getItem('unit_id'))}).then((res) => {
      if (res.status) {
        setSoDropFilter(res.data);
      } else {
        setSoDropFilter([]);
      }
    }).catch(err => {
      AlertMessages.getErrorMessage(err.message);
      setSoDropFilter([]);
    })
  }
  const getItemSubDropForSoPackStatusReport = () => {
    service.getItemSubDropForSoPackStatusReport({unitId:Number(localStorage.getItem('unit_id'))}).then((res) => {
      if (res.status) {
        setItemSubDrop(res.data);
      } else {
        setItemSubDrop([]);
      }
    }).catch(err => {
      AlertMessages.getErrorMessage(err.message);
      setItemSubDrop([]);
    })
  }
  const getItemDropForSoPackStatusReport = () => {
    service.getItemDropForSoPackStatusReport({unitId:Number(localStorage.getItem('unit_id'))}).then((res) => {
      if (res.status) {
        setItemDrop(res.data);
      } else {
        setItemDrop([]);
      }
    }).catch(err => {
      AlertMessages.getErrorMessage(err.message);
      setItemDrop([]);
    })
  }
  




  const getColumnSearchProps = (dataIndex: string) => ({
    filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
      <div style={{ padding: 8 }}>
        <Input
          ref={searchInput}
          placeholder={`Search ${dataIndex}`}
          value={selectedKeys[0]}
          onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
          onPressEnter={() => handleSearch(selectedKeys, confirm, dataIndex)}
          style={{ width: 188, marginBottom: 8, display: 'block' }}
        />
        <Button
          type="primary"
          onClick={() => handleSearch(selectedKeys, confirm, dataIndex)}
          icon={<SearchOutlined />}
          size="small"
          style={{ width: 90, marginRight: 8 }}
        >
          Search
        </Button>
        <Button onClick={() => handleReset(clearFilters)} size="small" style={{ width: 90 }}>
          Reset
        </Button>
      </div>
    ),
    filterIcon: filtered => (
      <SearchOutlined type="search" style={{ color: filtered ? '#1890ff' : undefined }} />
    ),
    onFilter: (value, record) =>
      record[dataIndex]
        ? record[dataIndex]
          .toString()
          .toLowerCase()
          .includes(value.toLowerCase())
        : false,
    onFilterDropdownVisibleChange: visible => {
      if (visible) { setTimeout(() => searchInput.current.select()); }
    },
    render: text =>
      text ? (
        searchedColumn === dataIndex ? (
          <Highlighter
            highlightStyle={{ backgroundColor: '#ffc069', padding: 0 }}
            searchWords={[searchText]}
            autoEscape
            textToHighlight={text.toString()}
          />
        ) : text
      )
        : null

  });


  const getAllPlants = () => {
    unitsService.getAllMainPlants().then((res) => {
      if (res.status) {
        setPlantData(res.data);
      } else {
        setPlantData([]);
      }
    }).catch(err => {
      AlertMessages.getErrorMessage(err.message);
      setPlantData([]);
    })
  }

  // const handleSaleOrder=(value, item)=>{
  //   const newStockData = stockData.filter(stock =>
  //     stock.saleOrderId == value
  //   )
  //   setStockData(newStockData);

  // }


  function handleSearch(selectedKeys, confirm, dataIndex) {
    confirm();
    setSearchText(selectedKeys[0]);
    setSearchedColumn(dataIndex);
  };

  function handleReset(clearFilters) {
    clearFilters();
    setSearchText('');
  };

  const onReset = () => {
    form.resetFields();
    setSelectedEstimatedFromDate(undefined);
    setSelectedEstimatedToDate(undefined);
    getSoPackingStatus(true);
    if (Number(localStorage.getItem('unit_id')) != 5) {
      form.setFieldsValue({ unitId: Number(localStorage.getItem('unit_id')) })
    }
  }

  // const resetFields = () => {
  //   setSelectedEstimatedFromDate(undefined);
  //   setSelectedEstimatedToDate(undefined);
  // }
  const onFocus = () => {
  }

  const onSearch = (val) => {
  }
  const onBlur = () => {
  }
  /**
  * 
  * @param pagination 
  * @param filters 
  * @param sorter 
  * @param extra 
  */
  const onChange = (pagination, filters, sorter, extra) => {
    console.log('params', pagination, filters, sorter, extra);
  }

  const columnsSkelton: ColumnProps<any>[] = [
    {
      title: 'S No',
      key: 'sno',
      fixed: 'left',
      width: '70px',
      render: (text, object, index) => (page - 1) * pageSize + (index + 1)
    },
    {
      title: 'Unit',
      dataIndex: 'unitName',
      fixed: 'left',
      width:'100px',
      ...getColumnSearchProps('unitName'),
    },
    {
      title: 'Customer PO',
      width: '130px',
      dataIndex: 'saleOrderNo',
      fixed: 'left',
      sorter: (a, b) => a.saleOrderNo.localeCompare(b.saleOrderNo),
      ...getColumnSearchProps('saleOrderNo'),
    },
    {
      title: 'ETD',
      dataIndex: 'etd',
      width: '150px',
      align: 'left',
      sortDirections: ['descend', 'ascend'],
      sorter: (a, b) => moment(a.etd).unix() - moment(b.etd).unix(),
      render: (value, record) => {
        return <span>
          {record.etd ? moment(record.etd).format('YYYY-MM-DD') : '-'}
        </span>
      }
    },
    {
      title: 'Item Sub Category',
      dataIndex: 'packingSubCategory',
      width: '130px',
      sorter: (a, b) => a.packingSubCategory.localeCompare(b.packingSubCategory),
       ...getColumnSearchProps('packingSubCategory'),
    },
    {
      title: 'Item',
      dataIndex: 'item',
      width: '200px',
      sorter: (a, b) => a.item?.localeCompare(b.item),
      ...getColumnSearchProps('item'),
    },
    {
      title: 'BOM Quantity',
      dataIndex: 'requiredQty',
      width:'90px',
      align: 'right',
      // sorter: (a, b) => a.requiredQty.localeCompare(b.requiredQty),
      //...getColumnSearchProps('requiredQty'),
      render: (index, record) => {
        return <>
          {Math.round(record.requiredQty)}</>
      }
    },


    {
      title: 'Received Qty',
      dataIndex: 'receivedQty',
      align: 'right',
      width:'90px',
      // sorter: (a, b) => a.receivedQty.localeCompare(b.receivedQty),
      //...getColumnSearchProps('receivedQty'),
      render: (index, record) => {
        return <>
          {Math.round(record.receivedQty)}</>
      }
    },
    {
      title: 'Assigned Qty',
      dataIndex: 'assignedQty',
      align: 'right',
      width:'90px',
      // sorter: (a, b) => a.assignedQty.localeCompare(b.assignedQty),
      //...getColumnSearchProps('assignedQty'),
      render: (index, record) => {
        return <>
          {Math.round(record.assignedQty)}</>
      }
    },
    {
      title: 'Issued Qty',
      dataIndex: 'issuedQty',
      align: 'right',
      width:'90px',
      // sorter: (a, b) => a.issuedQty?.localeCompare(b.issuedQty),
      //...getColumnSearchProps('issuedQty'),
      render: (index, record) => {
        return <>
          {Math.round(record.issuedQty)}</>
      }
    },
    {
      title: 'Returned Qty',
      dataIndex: 'returnedQty',
      align: 'right',
      width:'90px',
      // sorter: (a, b) => a.returnedQty?.localeCompare(b.returnedQty),
      // sortDirections:['ascend' , 'descend'],
      //...getColumnSearchProps('returnedQty'),
      render: (index, record) => {
        return <>
          {Math.round(record.returnedQty)}</>
      }
    },
    {
      title: 'Actual Isuued Qty',
      dataIndex: 'returnedQty',
      align: 'right',
      width:'90px',
      // sorter: (a, b) => a.returnedQty?.localeCompare(b.returnedQty),
      sortDirections: ['ascend', 'descend'],
      //...getColumnSearchProps('returnedQty'),
      render: (index, record) => {
        return <>
          {Number(record.issuedQty) - Number(record.returnedQty)}</>
      }
    },
    {
      title: 'FG Qty',
      dataIndex: 'fgQty',
      align: 'right',
      width:'90px',
      // sorter: (a, b) => a.fgQty?.localeCompare(b.fgQty),
      //...getColumnSearchProps('fgQty'),
      render: (index, record) => {
        return <>
          {Math.round(record.fgQty)}</>
      }
    },
    {
      title: 'PO Qty',
      dataIndex: 'poQty',
      align: 'right',
      width:'90px',
      // sorter: (a, b) => a.poQty.localeCompare(b.poQty),
      // ...getColumnSearchProps('poQty'),
      render: (index, record) => {
        return <>
          {Math.round(record.poQty)}</>
      }
    },

    {
      title: 'Production Qty',
      dataIndex: 'ProductionQty',
      align: 'right',
      width:'90px',
      // sorter: (a, b) => a.ProductionQty?.localeCompare(b.ProductionQty),
      //...getColumnSearchProps('fgQty'),
      render: (index, record) => {
        return <>
          {Number(record.issuedQty - record.fgQty - record.returnedQty)}</>
      }
    },

    {
      title: 'Available Qty',
      dataIndex: 'availableQty',
      align: 'right',
      width:'90px',
      // sorter: (a, b) => a.availableQty?.localeCompare(b.availableQty),
      //...getColumnSearchProps('fgQty'),
      render: (index, record) => {
        return <>
          {Math.round(record.availableQty)}</>
      }
    },
    {
      title: 'Balance',
      dataIndex: 'balance',
      align: 'right',
      width:'90px',
      render: (index, record) => {
        return <>
          {Math.round(record.balance)}</>
      }
    },


  ]
  

  return (
    <>
      <Card title={<span style={{ color: 'white' }} >SO Packing Status</span>} 
        style={{ textAlign: 'center' }} headStyle={{ backgroundColor: '#69c0ff', border: 0 }}>
        <Form form={form} layout={'vertical'} style={{ padding: '0px' }}  >
          <Row gutter={[24, 24]}>
            <Col xs={{ span: 24 }} sm={{ span: 24 }} md={{ span: 4 }} lg={{ span: 4 }} xl={{ span: 4 }}>
              <Form.Item
                name="unitId"
                label=" Unit"
                
              >
                <Select
                  showSearch
                  optionFilterProp="children"
                  filterOption={(input, option) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  placeholder="Select Unit"
                  disabled={Number(localStorage.getItem('unit_id')) != 5 ? true : false}
                  allowClear
                  style={{ width: '100%' }}
                >
                  {plantData.map(dropData => {
                    return <Option value={dropData.plantId}>{dropData.plantName}</Option>
                  })}
                </Select>
              </Form.Item>
            </Col>
            <Col xs={{ span: 24 }} sm={{ span: 24 }} md={{ span: 4 }} lg={{ span: 4 }} xl={{ span: 4 }}>
              <Form.Item
                name="saleOrderId"
                label="Customer PO"
              >
                <Select
                  showSearch
                  placeholder="Select Customer PO"
                  optionFilterProp="children"
                  mode='multiple'
                  allowClear
                // filterOption={(input, option) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                // onSelect={handleSaleOrder}
                >
                  {soDropFilter.map((data) => {
                    return <Option key={data.saleOrderId} value={data.saleOrderId}> {data.saleOrderNo}</Option>
                  })}
                </Select>
              </Form.Item>
            </Col>
            <Col xs={{ span: 24 }} sm={{ span: 24 }} md={{ span: 5 }} lg={{ span: 5 }} xl={{ span: 6 }}>
              <Form.Item
                name="itemSubCategoryId"
                label="Item Sub Category"
                rules={[
                  {
                    required: false,
                    message: 'Item Sub Category is required'
                  },
                  {
                    pattern: /^[^-\s][a-zA-Z0-9_\s-]*$/,
                    message: `Enter valid Item Sub Category `,
                  },
                ]}
              >
                <Select
                  showSearch
                  // style={{ width: 260 }}
                  placeholder="Select Item Sub Category"
                  optionFilterProp="children"
                  allowClear
                  onFocus={onFocus}
                  onBlur={onBlur}
                  onSearch={onSearch}
                  filterOption={(input, option) =>
                    option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
                  }
                >
                  <Option key={0} value={null}>Select Sub Category</Option>
                  {itemSubDrop.map((subCategory) => {
                    return <Option key={subCategory.itemSubCategoryId} value={subCategory.itemSubCategoryId}>{subCategory.itemSubCategory}</Option>
                  })}
                </Select>
              </Form.Item>
            </Col>
            <Col xs={{ span: 24 }} sm={{ span: 24 }} md={{ span: 5 }} lg={{ span: 6 }} xl={{ span: 9 }}>
            <Form.Item label="Item Name"
              name='item'
            >
              <Select showSearch
                allowClear
                placeholder="Select Item Name"
                filterOption={(input, option) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
                }>
                {itemDrop === undefined ? '' : itemDrop.map(dropData => {
                  return <Option key={dropData.itemNameId} value={dropData.itemNameId}>{dropData.item}</Option>
                })}
              </Select>
            </Form.Item>
          </Col>
            <Col xs={{ span: 24 }} sm={{ span: 24 }} md={{ span: 6 }} lg={{ span: 6 }} xl={{ span: 6 }}>
              <Form.Item name="fromDate"
                label="ETD Date"
                initialValue={undefined}

                rules={[
                  {
                    required: false,
                    message: " ETD Date"
                  },
                ]}>
                <RangePicker onChange={EstimatedETDDate} />
              </Form.Item>
            </Col>
            <Col style={{ marginTop: 30 }} xs={{ span: 24 }} sm={{ span: 24 }} md={{ span: 5 }} lg={{ span: 5 }} xl={{ span: 5 }}>
              <Button
                type="primary"
                block onClick={() => getSoPackingStatus()} disabled={disable} style={{ marginRight: 2, width: 100 }}>
                Get Report
              </Button>
              <Button type="primary" htmlType="submit" onClick={onReset}>
                Reset
              </Button>
            </Col>
          </Row>
        </Form>
        {soPackingStatusData.length > 0 && <>
          <Row justify="end"><Col style={{ marginBottom: '30px' }}>
          <Button icon={<DownloadOutlined />} onClick={() => { exportExcel(); }} > GET EXCEL </Button>
        </Col></Row>
          <Table
            columns={columnsSkelton}
            dataSource={soPackingStatusData}
            scroll={{ x: 1500, y: 500 }}
            pagination={{
              onChange(current, pageSize) {
                setPage(current);
                setPageSize(pageSize)
              }
            }}
            onChange={onChange}
            bordered />
            <Card title={"TOTAL Items's: " + soPackingStatusData.length} style={{ textAlign: 'left', height: 41, backgroundColor: 'none' }}>
        </Card>
        </>}
      </Card>
    </>
  )
};

export default SoPackingStatus;