import React, { useRef, useState, useEffect } from 'react';
import { Table, Card, Input, Button, Tooltip, Form, Col, Row, Select, Modal, Empty, Popconfirm, message, Tabs, Tag, DatePicker, Typography, Pagination, Statistic, Collapse } from 'antd';
import { ColumnProps } from 'antd/lib/table';
import Highlighter from 'react-highlight-words';
import { AlertMessages } from '@gtpl/shared-utils/alert-messages';
import moment from 'moment';
import { FGStockService } from '@gtpl/shared-services/warehouse-management';
import { PoDropDownDto } from '@gtpl/shared-models/procurement-management';
import { PurchaseOrderService } from '@gtpl/shared-services/procurement';
import { SearchOutlined, FilePdfOutlined, DownloadOutlined } from '@ant-design/icons';
import { Excel } from 'antd-table-saveas-excel';
import jsPDF from 'jspdf';
import { SaleOrderDropDownDto } from '@gtpl/shared-models/sale-management';
import { SaleOrderService } from '@gtpl/shared-services/sale-management';
import { ShipmentStatusRequest } from '@gtpl/shared-models/warehouse-management';
import { MasterBrandsDropDownDto, PlantsDropDown } from '@gtpl/shared-models/masters';
import { MasterBrandService, UnitcodeService } from '@gtpl/shared-services/masters';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faFileCsv, faFileExcel, faFilePdf } from '@fortawesome/free-solid-svg-icons';

const { Option } = Select;

export interface ShipmentStatusReportProps { }

export function ShipmentStatusReport(
    props: ShipmentStatusReportProps
) {
    const [form] = Form.useForm();
    const searchInput = useRef(null);
    const [searchText, setSearchText] = useState('');
    const [searchedColumn, setSearchedColumn] = useState('');
    const [page, setPage] = React.useState(1);
    const [reportData, setReportData] = useState<any[]>([]);
    const service = new FGStockService();
    const [disable, setDisable] = useState<boolean>(false);
    const [soItemData, setSoItemData] = useState<any[]>([]);
    const services = new SaleOrderService;
    const [loading, setLoading] = useState(false);
    const [filtersData, setFiltersData] = useState<any[]>([]);
    const [selectedunit, setUnit] = useState<number>(0)
    const [plantData, setPlantData] = useState<PlantsDropDown[]>([]);
    const unitsService = new UnitcodeService();
    const [empty, setEmpty] = useState<boolean>()
    const [po, setPo] = useState<number>(0);
    const [brandsDropDown, setBrandsDropDown] = useState<any[]>([]);
    const brandsService = new MasterBrandService()
    const { RangePicker } = DatePicker;
    const [selectedLoadingFromDate, setSelectedLoadingFromDate] = useState(undefined);
    const [selectedLoadingToDate, setSelectedLoadingToDate] = useState(undefined);
    let totalCount = 0;
    const [pagination, setPagination] = useState({
        current: 1,
        pageSize: 100,
    });
    


    useEffect(() => {
        getBrandData();
        getAllSaleOrderItems();
        getAllPlants();
        if (Number(localStorage.getItem('unit_id')) != 5) {
            form.setFieldsValue({ unitId: Number(localStorage.getItem('unit_id')) })
        }
        setEmpty(true);
        // form.setFieldsValue({
        //     dispatchedDate: [(moment(moment().format("YYYY-MM-DD")).subtract(1, 'days')), moment(moment().format("YYYY-MM-DD"))]
        // })
        setSelectedLoadingFromDate((moment(moment().format("YYYY-MM-DD")).subtract(1, 'days')))
        setSelectedLoadingToDate(moment(moment().format("YYYY-MM-DD")))
        form.setFieldsValue({
            dispatchedDate: [(moment(moment().startOf('month').format("YYYY-MM-DD"))), moment(moment().format("YYYY-MM-DD"))]
        })
    }, [])


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

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


    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 getShipmentStatusReport = () => {
        setDisable(true);
        setLoading(true);
        setEmpty(false);
        const req = new ShipmentStatusRequest;
        let saleOrderId = form.getFieldValue('saleOrderId')
        let masterBrandId = form.getFieldValue('masterBrandId')
        let selectedData = filtersData
        req.saleOrderId = saleOrderId;
        req.masterBrandId = masterBrandId;
        if (form.getFieldValue('dispatchedDate') != undefined) {
            const selectedFromDate = moment(form.getFieldValue('dispatchedDate')[0]).format('YYYY-MM-DD');
            const selectedToDate = moment(form.getFieldValue('dispatchedDate')[1]).format('YYYY-MM-DD');
            req.selectedLoadingFromDate = (selectedFromDate)
            req.selectedLoadingToDate = (selectedToDate)
        }
        if (Number(localStorage.getItem('unit_id')) != 5) {
            req.unitId = Number(localStorage.getItem('unit_id'));
        } else {
            req.unitId = selectedunit
        }
        service.getShipmentStatusReport(req).then(res => {
            setDisable(false)
            if (res.status) {
                setReportData(res.data);
                console.log(moment(res.data[0].dispatchDate).format('YYYY-MM-DD'))
                console.log(res.data.filter(i => moment(i.dispatchDate).format('YYYY-MM-DD') == moment().format('YYYY-MM-DD')).length)
                setFiltersData(res.data);
                console.log()
                setLoading(false);
                AlertMessages.getSuccessMessage(res.internalMessage);
            } else {
                if (res.intlCode) {
                    setLoading(false);
                    setDisable(false);
                    setReportData([]);
                    AlertMessages.getErrorMessage(res.internalMessage);
                } else {
                    setLoading(false);
                    setDisable(false);
                }
            }
        }).catch((err) => {
            setReportData([]);
            setDisable(false);
            AlertMessages.getErrorMessage(err.message);
        })
        setReportData(selectedData);
    }

    const getAllSaleOrderItems = () => {
        service.getSoDropForShipmentStatusReport({ unitId: Number(localStorage.getItem('unit_id')) }).then(res => {
            if (res.status) {
                setSoItemData(res.data);
            } else {
                if (res.intlCode) {
                    setSoItemData([]);
                    AlertMessages.getErrorMessage(res.internalMessage);
                } else {
                    AlertMessages.getErrorMessage(res.internalMessage);
                }
            }
        }).catch(err => {
            AlertMessages.getErrorMessage(err.message);
            setSoItemData([]);
        })
    }

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



    const getBrandData = () => {
        service.getbrandDropForShipmentStatusReport({ unitId: Number(localStorage.getItem('unit_id')) }).then(res => {
            if (res.status) {
                setBrandsDropDown(res.data);
            } else {
                if (res.intlCode) {
                    AlertMessages.getErrorMessage(res.internalMessage);
                } else {
                    AlertMessages.getErrorMessage(res.internalMessage);
                }
            }
        }).catch(err => {
            AlertMessages.getErrorMessage(err.message);
        })
    }
    const onReset = () => {
        form.resetFields();
        setReportData([]);
        setEmpty(true); setPo(0); setUnit(0);
        if (Number(localStorage.getItem('unit_id')) != 5) {
            form.setFieldsValue({ unitId: Number(localStorage.getItem('unit_id')) })
        }
    }

    const handlePo = (val) => {
        setPo(val);
    }

    const data = [
        { title: "PO No", dataIndex: "poNo" },
        { title: "Production Facility", dataIndex: "prodFacility" },
        { title: "Brand", dataIndex: "brand" },
        {
            title: 'Variety',
            dataIndex: 'variantCode',
            render: (value, record) => {
                return record.variantCode ? (record.variantCode).split('/')[1] : '-';
            }
        },
        { title: "Packing Style", dataIndex: "poches", render: (value, record) => {
            return record.poches ? `${record.poches} X ${Number(record.pouchwt)} ${record.uom_name}` : '-';
        } },
        { title: "Grade", dataIndex: "grade" },
        { title: "No. of Cases", dataIndex: "Nocases" },
        {
            title: 'Dispatched Date',
            dataIndex: 'dispatchDate',
            render: (value, record) => {
                return <span>
                    {record.dispatchDate ? moment(record.dispatchDate).format('YYYY-MM-DD') : '-'}
                </span>
            }
        },
        { title: "Vehicle No", dataIndex: "vehicleNo", render: (value, record) => {
            return <span>
                {record.vehicleNo ? record.vehicleNo : '-'}
            </span>
        } },
        { title: "Final Destination", dataIndex: "finalDestination" },
        { title: "Liner Seal", dataIndex: "linerSeal",render: (value, record) => {
            return record.linerSeal ? record.linerSeal : '-';
        } },
    ]

    const exportExcel = () => {
        const excel = new Excel();
        excel
            .addSheet('shipmentStatus')
            .addColumns(data)
            .addDataSource(reportData, { str2num: true })
            .saveAs('shipment-status-report.xlsx');
    }
    const exportToPdf = () => {
        var columns = [
            { title: "PO No", dataKey: "poNo" },
            { title: "Production Facility", dataKey: "prodFacility" },
            { title: "Brand", dataKey: "brand" },
            { title: "Variety", dataKey: "variantCode" },
            { title: "Packing Style", dataKey: "poches", render: (value, record) => {
                return record.poches ? `${record.poches} X ${Number(record.pouchwt)} ${record.uom_name}` : '-';
            } },
            { title: "Grade", dataKey: "grade" },
            { title: "No. of Cases", dataKey: "Nocases" },
            { title: "Dispatched Date", dataKey: "dispatchDate", render: (value, record) => { return <span> {record.dispatchDate ? moment(record.dispatchDate).format('YYYY-MM-DD') : '-'} </span> } },
            { title: "Invoice No.", dataKey: "invoiceNo" },
            { title: "Container Details", dataKey: "containerDetails" },
            { title: "Vehicle No", dataKey: "vehicleNo" },
            { title: "Final Destination", dataKey: "finalDestination" },
            { title: "Seal No.", dataKey: "sealNo" },
            { title: "Liner Seal", dataKey: "linerSeal" },
        ];
        const doc = new jsPDF()
        // @ts-ignore

        doc.autoTable(columns, grnReport, {
            columnStyles: {
                id: { fillColor: 255 }
            },

            margin: { top: 20 },
            addPageContent: function (data) {
                doc.text("SHIPMENT STATUS REPORT", 50, 15);
            }
        });
        doc.save('shipment-status-report.pdf')
    }
    const handleUnit = (value) => {
        setUnit(value)
    }

    const EstimatedDispatchedDate = (value) => {
        const fromDate = new Date(value[0].format('YYYY-MM-DD'));
        const toDate = new Date(value[1].format('YYYY-MM-DD'));
        setSelectedLoadingFromDate(fromDate);
        setSelectedLoadingToDate(toDate);
        console.log(value);
    }

    const commonColumns: ColumnProps<any>[] = [
        {
            title: 'S No',
            dataIndex: 'sNo',
            width: '70px',
            fixed: 'left',
            align: 'center',
            render: (_, __, index) => ((pagination.current - 1) * pagination.pageSize) + index + 1,

        },
        {
            title: 'PO No',
            dataIndex: 'poNo',
            width: '110px',
            sorter: (a, b) => a.poNo.length - b.poNo.length || a.poNo.localeCompare(b.poNo),
            sortDirections: ['descend', 'ascend'],
            ...getColumnSearchProps('poNo'),
            render: (value, record) => {
                return record.poNo ? record.poNo : '-';
            }
        },
        {
            title: 'Production Facility',
            dataIndex: 'prodFacility',
            width: '180px',
            sorter: (a, b) => a.prodFacility?.localeCompare(b.prodFacility),
            sortDirections: ['descend', 'ascend'],
            ...getColumnSearchProps('poNo'),
        },
        {
            title: 'Brand',
            dataIndex: 'brand',
            width: '110px',
            sorter: (a, b) => a.brand?.localeCompare(b.brand),
            sortDirections: ['descend', 'ascend'],
            ...getColumnSearchProps('brand'),
            render: (value, record) => {
                return record.brand ? record.brand : '-';
            }
        },
        {
            title: 'Variety',
            dataIndex: 'variantCode',
            width: '110px',
            sorter: (a, b) => a.variantCode?.localeCompare(b.variantCode),
            sortDirections: ['descend', 'ascend'],
            ...getColumnSearchProps('variantCode'),
            render: (value, record) => {
                return record.variantCode ? (record.variantCode).split('/')[1] : '-';
            }
        },
        {
            title: 'Packing Style',
            dataIndex: 'poches',
            width: '110px',
            sorter: (a, b) => {
                const valueA = a.poches ? parseFloat(a.poches) : 0;
                const valueB = b.poches ? parseFloat(b.poches) : 0;
                return valueA - valueB;
            },
            sortDirections: ['descend', 'ascend'],
            ...getColumnSearchProps('poches'),
            render: (value, record) => {
                return record.poches ? `${record.poches} X ${Number(record.pouchwt)} ${record.uom_name}` : '-';
            }
        },
        
        {
            title: 'Grade',
            dataIndex: 'grade',
            width: '100px',
            sorter: (a, b) => a.grade?.localeCompare(b.grade),
            sortDirections: ['descend', 'ascend'],
            ...getColumnSearchProps('grade'),
            render: (value, record) => {
                return record.grade ? record.grade : '-';
            }
        },
        {
            title: 'No. of Cases',
            dataIndex: 'Nocases',
            width: '70px',
            sorter: (a, b) => a.Nocases - b.Nocases,
            sortDirections: ['descend', 'ascend'],
            render: (value, record) => {
                return record.Nocases ? record.Nocases : '-';
            }
        },
        {
            title: 'Dispatched Date',
            dataIndex: 'dispatchDate',
            width: '120px',
            sorter: (a, b) => a.dispatchDate?.localeCompare(b.dispatchDate),
            sortDirections: ['descend', 'ascend'],
            render: (value, record) => {
                return <span>
                    {record.dispatchDate ? moment(record.dispatchDate).format('YYYY-MM-DD') : '-'}
                </span>
            }
        },
        {
            title: 'Invoice No.',
            dataIndex: 'invoiceNo',
            width: '120px',
            sorter: (a, b) => a.invoiceNo?.localeCompare(b.invoiceNo),
            sortDirections: ['descend', 'ascend'],
            ...getColumnSearchProps('invoiceNo'),
            render: (value, record) => {
                return record.invoiceNo ? record.invoiceNo : '-';
            }
        },
        {
            title: 'Container Details',
            dataIndex: 'containerDetails',
            width: '120px',
            sorter: (a, b) => a.containerDetails?.localeCompare(b.containerDetails),
            sortDirections: ['descend', 'ascend'],
            ...getColumnSearchProps('containerDetails'),
            render: (value, record) => {
                return record.containerDetails ? record.containerDetails : '-';
            }
        },
        {
            title: 'Vehicle No',
            dataIndex: 'vehicleNo',
            width: '130px',
            sorter: (a, b) => a.vehicleNo?.localeCompare(b.vehicleNo),
            sortDirections: ['descend', 'ascend'],
            ...getColumnSearchProps('vehicleNo'),
            render: (value, record) => {
                return record.vehicleNo ? record.vehicleNo : '-';
            }
        },
        {
            title: 'Final Destination',
            dataIndex: 'finalDestination',
            width: '150px',
            sorter: (a, b) => a.finalDestination?.localeCompare(b.finalDestination),
            sortDirections: ['descend', 'ascend'],
            ...getColumnSearchProps('finalDestination'),
            render: (value, record) => {
                return record.finalDestination ? record.finalDestination : '-';
            }
        },
        {
            title: 'Liner Seal',
            dataIndex: 'linerSeal',
            width: '130px',
            sorter: (a, b) => a.linerSeal?.localeCompare(b.linerSeal),
            sortDirections: ['descend', 'ascend'],
            ...getColumnSearchProps('linerSeal'),
            render: (value, record) => {
                return record.linerSeal ? record.linerSeal : '-';
            }
        },
    ]
    const onChange = (pagination, filters, sorter, extra) => {
        console.log('params', pagination, filters, sorter, extra);
    }
    function onBlur() {
        console.log('blur');
    }

    function onFocus() {
        console.log('focus');
    }

    function onSearch(val) {
        console.log('search:', val);
    }


    const groupedDataForSummary = reportData ? reportData.reduce((group, product) => {
        const { endCustomer } = product;
        group[endCustomer] = group[endCustomer] ?? [];
        group[endCustomer].push(product);
        return group;
    }, {}) : null

    const endCustomerSummary = () => {
        const keys = Object.keys(groupedDataForSummary);
        return keys.map((key: any) => {
            return (
                <Col span={4}>
                    <Statistic title={key} value={groupedDataForSummary[key].length} />
                </Col>);
        })
    }

    const handleTableChange = (pagination) => {
        setPagination(pagination);
    };




    return (
        <>
        <style>
            {
                `
                .ant-collapse > .ant-collapse-item > .ant-collapse-header .ant-collapse-arrow{
                display:none;
            }
                `
            }
      </style>
        <Card
            title={<span style={{ color: 'white' }}>Shipment Status Report</span>}
            style={{ textAlign: 'center' }}
            headStyle={{ backgroundColor: '#69c0ff', border: 0 }}
            extra={reportData.length > 0 && (
                <Button icon={<DownloadOutlined />} onClick={() => exportExcel()}>
                  GET EXCEL
                </Button> )}
            // extra={reportData.length ? <Tag style={{ color: "black", height: 30, width: 100, fontSize: 13 }}>{('Current day : ' + reportData[0]?.currentDay)}</Tag> : <></>}
        >
            <Form layout={"vertical"} form={form} >
                <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"
                            rules={[
                                {
                                    required: false, message: 'Select Unit',
                                },
                            ]}
                        >
                            <Select
                                showSearch
                                optionFilterProp="children"
                                filterOption={(input, option) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                                placeholder="Select Unit"
                                allowClear
                                style={{ width: '100%' }}
                                onChange={handleUnit}
                                disabled={Number(localStorage.getItem('unit_id')) != 5 ? true : false}
                            >
                                {plantData.map(dropData => {
                                    return <Option value={dropData.plantId}>{dropData.plantCode}</Option>
                                })}
                            </Select>
                        </Form.Item>
                    </Col>
                    <Col xs={{ span: 24 }} sm={{ span: 24 }} md={{ span: 5 }} lg={{ span: 4 }} xl={{ span: 4 }}>
                        <Form.Item name="saleOrderId"
                            label="Customer PO"
                            rules=
                            {[{ required: false, message: ' Select ' },]}>
                            <Select showSearch placeholder="Select Customer PO"
                                optionFilterProp="children"
                                onFocus={onFocus}
                                onBlur={onBlur}
                                onSearch={onSearch}
                                onChange={handlePo}
                                allowClear
                            >
                                <Option key={0} value={null}>Select Customer PO</Option>
                                {soItemData.map((data) => {
                                    return <Option key={data.saleOrderId} value={data.saleOrderId}> {data.poNo}</Option>
                                })}
                            </Select>
                        </Form.Item>
                    </Col>
                    <Col  xs={{ span: 24 }} sm={{ span: 24 }} md={{ span: 4 }} lg={{ span: 4 }} xl={{ span: 4 }}>
                        <Form.Item
                            label="Brand Name"
                            name='masterBrandId'
                            rules={[{ required: false }]}
                        >
                            <Select
                                showSearch
                                placeholder="Select Brand Name"
                                optionFilterProp="children"
                                allowClear
                                onSearch={onSearch}
                                filterOption={(input, option) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}

                            >
                                <Option key={0} value={null}>Select Brand Name</Option>
                                {brandsDropDown.map(branddropData => {
                                    return <Option key={branddropData.masterBrandId} value={branddropData.masterBrandId}>{branddropData.masterBrandName}</Option>
                                })}
                                |
                            </Select>
                        </Form.Item>
                    </Col>
                    <Col xs={{ span: 24 }} sm={{ span: 24 }} md={{ span: 3 }} lg={{ span: 6 }} xl={{ span: 6 }}>
                        <Form.Item name="dispatchedDate"
                            label="Dispatched Date"
                            rules={[
                                {
                                    required: false,
                                    message: "Missing Loading Date"
                                },
                            ]}>
                            <RangePicker onChange={EstimatedDispatchedDate} />
                        </Form.Item>
                    </Col>
                    <Col style={{ padding: '20px', marginTop: '30px' }}>
                        <Button type="primary" style={{ marginRight: '4px' }} disabled={disable} onClick={() => getShipmentStatusReport()}>
                            Get Report
                        </Button>
                        <Button style={{ marginLeft: '5px' }} type="primary" htmlType="submit" onClick={onReset}> Reset </Button>
                    </Col>
                </Row>
            </Form>
            <br /><br />
            {
                reportData.length > 0 ?
                    <>
                        {
                            reportData.forEach(item => {
                                totalCount += Number(item.poNo);
                            })

                        }
                        <Card size='small'>
                            <Collapse>
                                <Collapse.Panel
                                    key={1}
                                    header={<span style={{ color: "white",fontSize:'medium' }}>Report Summary</span>}
                                    style={{ backgroundColor: "#69c0ff", border: 0 }}

                                >
                                    <Row gutter={24}>
                                        <Col>
                                        <Statistic title="Total SO's" value={reportData.length} />
                                        
                                        </Col>
                                        {endCustomerSummary()}

                                    </Row>
                                    
                                </Collapse.Panel>
                            
                            </Collapse>
                     </Card>
                        <Table
                            // key={keyUpdate}
                            //  title={() => 'Report data' }
                            columns={commonColumns}
                            dataSource={reportData}
                            scroll={{ x: 1500, y: 500 }}
                            bordered
                            pagination={{
                                pageSize: pagination.pageSize,
                                current: pagination.current,
                                onChange: (page, pageSize) => handleTableChange({ current: page, pageSize }),
                            }}
                            onChange={handleTableChange}
                        />

                    </> : <></>
            }
        </Card>
        </>
    )
}