import React, { useEffect, useRef, useState } from 'react';
import { Table, Card, Input, Button, Row, Col, Form, Select, DatePicker } from 'antd';
import { AlertMessages } from '@gtpl/shared-utils/alert-messages';
import { ColumnProps } from 'antd/lib/table';
import { SearchOutlined } from '@ant-design/icons';
import Highlighter from 'react-highlight-words';
import moment from 'moment';
import { Excel } from 'antd-table-saveas-excel';
import { DepartmentService, HrmsEmpDetService } from '@gtpl/shared-services/masters';
import './emp-monthwise-attendance-report.css';
import { DepartmentDto, HrmsEmployeeDetailsDto } from '@gtpl/shared-models/masters';
import { AttendanceService } from '@gtpl/shared-services/hrms';
import { AttendanceModel, EmployeeAttDateRequest } from '@gtpl/shared-models/hrms';
/* eslint-disable-next-line */
export interface EmpMonthwiseAttendanceReportProps {
  viewReport: (Report: AttendanceModel, viewOnly: boolean) => void;
}

export function EmpMonthwiseAttendanceReport(
  props: EmpMonthwiseAttendanceReportProps
) {
  const [page, setPage] = React.useState(1);
  const searchInput = useRef(null);
  const [searchText, setSearchText] = useState('');
  const [searchedColumn, setSearchedColumn] = useState('');
  const [disable, setDisable] = useState<boolean>(false);
  const [loading, setLoading] = useState(false);
  const [form] = Form.useForm();
  const { Option } = Select;
  const [selectedunit, setUnit] = useState<number>(0)
  const { RangePicker } = DatePicker;
  const [empData, setEmpData] = useState<HrmsEmployeeDetailsDto[]>([]);
  const [reportData, setReportData] = useState<any[]>([]);
  const [selectedEstimatedFromDate, setSelectedEstimatedFromDate] = useState(undefined);
  const [selectedEstimatedToDate, setSelectedEstimatedToDate] = useState(undefined);
  const [departmentData, setDepartmentData] = useState<DepartmentDto[]>([]);
  const [unitDrop, setUnitDrop] = useState<any[]>([]);
  const [shiftDrop, setShiftDrop] = useState<any[]>([]);
  const service = new HrmsEmpDetService();
  const attendanceService = new AttendanceService();
  const departmentService = new DepartmentService();

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

  useEffect(() => {
    getAllActiveEmployees();
    getAllEmpDateAtten();
    getAllDepartments();
    getUnitDropForAttReport();
    getShiftDropForAttReport();
  }, []);

  const getAllEmpDateAtten = (onReset?: boolean) => {
    setDisable(true);
    setLoading(true);
    let employeeCode = form.getFieldValue('employeeCode');
    let deptId = form.getFieldValue('department');
    let shift = form.getFieldValue('shift');
    let unitId = form.getFieldValue('unitId');
    let startDate = onReset ? undefined : selectedEstimatedFromDate;
    let endDate = onReset ? undefined : selectedEstimatedToDate;

    const req = new EmployeeAttDateRequest(employeeCode, startDate, endDate, deptId, shift, unitId);
    attendanceService.getAllEmpDateAtten(req).then(res => {
      setDisable(false)
      if (res.status) {
        setReportData(res.data);
        setLoading(false);
        AlertMessages.getSuccessMessage(res.internalMessage);
      } else {
        if (res.intlCode) {
          setLoading(false);
          setDisable(false);
          setReportData([]);
        } else {
          setLoading(false);
        }
      }
    }).catch(err => {
      setReportData([]);
      AlertMessages.getErrorMessage(err.message);
    })
  }

  const getAllActiveEmployees = () => {
    service.getAllActiveEmployees().then((res) => {
      if (res.status) {
        setEmpData(res.data);
      } else {
        if (res.intlCode) {
          // AlertMessages.getErrorMessage(res.internalMessage);
        } else {
          // AlertMessages.getErrorMessage(res.internalMessage);
        }
        setEmpData([]);
      }
    }).catch(err => {
      AlertMessages.getErrorMessage(err.message);
      setEmpData([]);
    })
  }

  const getShiftDropForAttReport = () => {
    attendanceService.getShiftDropForAttReport().then((res) => {
      if (res.status) {
        setShiftDrop(res.data);
      } else {
        if (res.intlCode) {
          // AlertMessages.getErrorMessage(res.internalMessage);
        } else {
          // AlertMessages.getErrorMessage(res.internalMessage);
        }
        setShiftDrop([]);
      }
    }).catch(err => {
      AlertMessages.getErrorMessage(err.message);
      setShiftDrop([]);
    })
  }

  const getUnitDropForAttReport = () => {
    attendanceService.getUnitDropForAttReport().then((res) => {
      if (res.status) {
        setUnitDrop(res.data);
      } else {
        if (res.intlCode) {
          // AlertMessages.getErrorMessage(res.internalMessage);
        } else {
          // AlertMessages.getErrorMessage(res.internalMessage);
        }
        setUnitDrop([]);
      }
    }).catch(err => {
      AlertMessages.getErrorMessage(err.message);
      setUnitDrop([]);
    })
  }


  const onChange = (pagination, filters, sorter, extra) => {
    console.log('params', pagination, filters, sorter, extra);
  }

  const columnsSkelton: ColumnProps<any>[] = [
    {
      title: 'S No',
      dataIndex: 'sNo',
      width: '70px',
      fixed: 'left',
      align: 'center',
      render: (text, object, index) => (page - 1) * 10 + (index + 1)
    },
    {
      title: 'Employee Name',
      dataIndex: 'employeeName',
      width: '150px',
      fixed: 'left',
      align: 'left',
      sorter: (a, b) => a.employeeName.localeCompare(b.employeeName),
      sortDirections: ['descend', 'ascend'],
      ...getColumnSearchProps('employeeName'),
    },
    {
      title: 'Employee Code',
      dataIndex: 'employeeCode',
      width: '150px',
      fixed: 'left',
      align: 'center',
      sorter: (a, b) => a.employeeCode?.localeCompare(b.employeeCode),
      sortDirections: ['descend', 'ascend'],
      ...getColumnSearchProps('employeeCode')
    },
    {
      title: 'Date',
      dataIndex: 'date',
      width: '120px',
      fixed: 'left',
      // sorter: (a, b) => a.date.localeCompare(b.date),
      // sortDirections: ['descend', 'ascend'],
      render: (value, record) => {
        return <span>
          {record.date ? moment(record.date).format('YYYY-MM-DD') : '-'}
        </span>
      }
    },
    {
      title: 'Day',
      dataIndex: 'day',
      width: '120px',
      fixed: 'left',
      render: (text, record) => { return moment(record.date).format('dddd') },
      // sorter: (a, b) => a.day.localeCompare(b.targetday),
      // sortDirections: ['descend', 'ascend'],
    },
    {
      title: 'Attendence Status',
      dataIndex: 'presentStatus',
      width: '130px',
      filters: [
        { text: 'PRESENT', value: 'P' },
        { text: 'WORKFROMHOME', value: 'WFH' },
        { text: 'ABSENT', value: 'A' },
        { text: 'LEAVE', value: 'L' },
      ],
      filterMultiple: false,
      onFilter: (value, record) => {
        // === is not work
        return record.presentStatus === value;
      },
      sorter: (a, b) => a.presentStatus.localeCompare(b.presentStatus),
      sortDirections: ['descend', 'ascend'],
    },
    {
      title: 'Contractor Name',
      dataIndex: 'contractorName',
      width: '150px',
      align: 'center',
      sorter: (a, b) => a.contractorName?.localeCompare(b.contractorName),
      sortDirections: ['descend', 'ascend'],
      ...getColumnSearchProps('contractorName'),
      render: (value, record) => {
        return record.contractorName ? record.contractorName : '-';
      }
    },
    {
      title: 'Designation ',
      dataIndex: 'designation',
      width: '120px',
      ...getColumnSearchProps('designation'),
    },
    {
      title: 'Reporting Manager ',
      dataIndex: 'reportingManager',
      width: '120px',
      ...getColumnSearchProps('reportingManager'),
    },
    {
      title: 'Unit',
      dataIndex: 'unitId',
      width: '100px',
      ...getColumnSearchProps('unitId'),
    },
    {
      title: 'Department',
      dataIndex: 'departmentCode',
      width: '120px',
      ...getColumnSearchProps('departmentCode'),
    },
    {
      title: 'Shift',
      dataIndex: 'shift',
      width: '100px',
      // sorter: (a, b) => a.shift.localeCompare(b.shift),
      // sortDirections: ['descend', 'ascend'],
    },
    {
      title: 'In Time',
      dataIndex: 'inTime',
      width: '100px',
      render: (text, record) => {
        return <span>
          {record.inTime ? moment(record.inTime).format('HH:mm') : '-'}
        </span>
      },
      // sorter: (a, b) => a.inTime.localeCompare(b.inTime),
      // sortDirections: ['descend', 'ascend'],
    },
    {
      title: 'Out time',
      dataIndex: 'outTime',
      width: '100px',
      render: (text, record) => {
        return <span>
          {record.outTime ? moment(record.outTime).format('HH:mm') : '-'}
        </span>
      },
      // sorter: (a, b) => a.outTime.localeCompare(b.outTime),
      // sortDirections: ['descend', 'ascend'],
    },
    {
      title: 'Working Hours',
      dataIndex: 'workingHours',
      width: '150px',
      render: (text, record) => {
        return <span>
          {record.workingHours ? record.workingHours : '-'}
        </span>
      },
      sorter: (a, b) => moment(a.workingHours).hours() - moment(b.workingHours).hours(),
      sortDirections: ['descend', 'ascend'],
      // filters: [
      //   { text: 'Greater 8 hrs ', value: '<8hrs' },
      //   { text: 'Less 8 hrs', value: '>8hrs' },
      // ],
      // filterMultiple: false,
      // onFilter: (value, record) => {
      //   let workingHours: number = 0;
      //   if (record.outTime) {
      //     workingHours = Number(moment.utc(moment(record.outTime).diff(moment(record.inTime))).format("HH"));
      //   }
      //   // 6
      //   if (value == '>8hrs') {
      //     if (workingHours > 8) {
      //       return record.workingHours
      //     }
      //   } else {
      //     return record;
      //   }
      // },
    },
  ];

  const exportedData = [];
  const excelData = empData
  let i = 1;
  const data = [
    { title: 'S No', dataIndex: 'sNo', render: (text, object, index) => { return i++; } },
    { title: 'Employee Code', dataIndex: 'employeeCode' },
    { title: 'Employee Name', dataIndex: 'employeeName' },
    { title: 'Contractor Name', dataIndex: 'contractorName', render: (text, record) => { return record.contractorName ? record.contractorName : '-' } },
    { title: 'Date', dataIndex: 'date', render: (text, record) => { return moment(record.date).format('DD-MM-YYYY') } },
    { title: 'Day', dataIndex: 'day', render: (text, record) => { return moment(record.date).format('dddd') } },
    { title: 'Attendence Status', dataIndex: 'presentStatus' },
    { title: 'Designation', dataIndex: 'designation' },
    { title: 'Unit', dataIndex: 'unitId' },
    { title: 'Department', dataIndex: 'departmentCode' },
    { title: 'Shift', dataIndex: 'shift' },
    { title: 'In Time', dataIndex: 'inTime', render: (text, record) => { return record.inTime ? moment(record.inTime).format('HH:mm') : '-' } },
    { title: 'Out time', dataIndex: 'outTime', render: (text, record) => { return record.outTime ? moment(record.outTime).format('HH:mm') : '-' } },
    { title: 'Working Hours', dataIndex: 'workingHours', render: (text, record) => { return record.workingHours ? record.workingHours : '-' } },
  ];

  const exportExcel = () => {
    const excel = new Excel();
    excel
      .addSheet('attendance-report')
      .addColumns(data)
      .addDataSource(reportData, { str2num: true })
      .saveAs('Attendance-Report.xlsx');
  }

  const handleUnit = (value) => {
    setUnit(value)
  }

  const EstimatedETDDate = (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 getAllDepartments = () => {
    departmentService.getAllActiveDepartment().then(res => {
      if (res.status) {
        setDepartmentData(res.data);
      } else {
        if (res.intlCode) {
          setDepartmentData([]);
          AlertMessages.getErrorMessage(res.internalMessage);
        } else {
          AlertMessages.getErrorMessage(res.internalMessage);
        }
      }
    }).catch(err => {
      setDepartmentData([]);
      AlertMessages.getErrorMessage(err.message);
    })
  }


  const onReset = () => {
    form.resetFields();
    setSelectedEstimatedFromDate(undefined);
    setSelectedEstimatedToDate(undefined);
    setReportData([]);
  }

  return (
    <Card
      title={<span style={{ color: 'white' }}>Employee Attendance Scorecard</span>} extra={<Button onClick={() => { exportExcel(); }}>Get Excel</Button>}
      style={{ textAlign: 'center' }}
      headStyle={{ backgroundColor: '#69c0ff', border: 0 }}
    >
      <Form layout={"vertical"} form={form} >
        <Row gutter={[24, 24]}>
          <Col xs={{ span: 24 }} sm={{ span: 24 }} md={{ span: 6 }} lg={{ span: 6 }} xl={{ span: 4 }}>
            <Form.Item name="fromDate"
              label="Date Range"
              initialValue={undefined}
              rules={[
                {
                  required: true,
                  message: "select date range"
                },
              ]}>
              <RangePicker onChange={EstimatedETDDate} />
            </Form.Item>
          </Col>

          <Col xs={{ span: 24 }} sm={{ span: 24 }} md={{ span: 6 }} lg={{ span: 6 }} xl={{ span: 6 }}>
            <Form.Item
              name="employeeCode"
              label="Employee Name"
              rules={[
                {
                  required: false,
                  message: "Select valid Employee Name"
                }
              ]}>
              <Select
                showSearch
                optionFilterProp="children"
                filterOption={(input, option) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                placeholder="Select Employee Name"
                // onChange={}
                allowClear
                style={{ width: '100%' }}
              >
                {empData?.map(dropData => {
                  return <Option key={dropData.employeeId} value={dropData.employeeCode}>{dropData.employeeName + ' ' + dropData.employeeLastName + '-' + dropData.employeeCode}</Option>;
                })}
              </Select>
            </Form.Item>
          </Col>

          <Col xs={{ span: 24 }} sm={{ span: 24 }} md={{ span: 6 }} lg={{ span: 6 }} xl={{ span: 4 }}>
            <Form.Item
              name="department"
              label="Department"
              rules={[
                {
                  required: false,
                  message: "Select valid department"
                }
              ]}>
              <Select
                showSearch
                optionFilterProp="children"
                filterOption={(input, option) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                placeholder="Select Department"
                // onChange={}
                allowClear
                style={{ width: '100%' }}
              >
                {departmentData?.map(dropData => {
                  return <Option key={dropData.deptId} value={dropData.deptId}>{dropData.deptName}</Option>;
                })}
              </Select>
            </Form.Item>
          </Col>

          <Col xs={{ span: 24 }} sm={{ span: 24 }} md={{ span: 6 }} lg={{ span: 6 }} xl={{ span: 3 }}>
            <Form.Item
              name="shift"
              label="Shift"
              rules={[
                {
                  required: false,
                  message: "Select valid shift"
                }
              ]}>
              <Select
                showSearch
                optionFilterProp="children"
                filterOption={(input, option) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                placeholder="Select Shift"
                // onChange={}
                allowClear
                style={{ width: '100%' }}
              >
                {shiftDrop?.map(dropData => {
                  return <Option key={dropData.shift} value={dropData.shift}>{dropData.shift}</Option>;
                })}
              </Select>
            </Form.Item>
          </Col>

          <Col xs={{ span: 24 }} sm={{ span: 24 }} md={{ span: 6 }} lg={{ span: 6 }} xl={{ span: 3 }}>
            <Form.Item
              name="unitId"
              label="Unit"
              rules={[
                {
                  required: false,
                  message: "Select valid unit"
                }
              ]}>
              <Select
                showSearch
                optionFilterProp="children"
                filterOption={(input, option) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                placeholder="Select Unit"
                // onChange={}
                allowClear
                style={{ width: '100%' }}
              >
                {unitDrop?.map(dropData => {
                  return <Option key={dropData.unitId} value={dropData.unitId}>{dropData.unitName}</Option>;
                })}
              </Select>
            </Form.Item>
          </Col>

          <Col style={{ padding: '20px', marginTop: '30px' }}>
            <Button type="primary" style={{ marginRight: '4px' }} disabled={disable} onClick={() => getAllEmpDateAtten()}>
              Get Report
            </Button>
            <Button style={{ marginLeft: '5px' }} type="primary" htmlType="submit" onClick={onReset}> Reset </Button>
          </Col>
        </Row>
      </Form>
      <Table
        columns={columnsSkelton}
        dataSource={reportData}
        scroll={{ x: 1500, y: 500 }}
        bordered
        pagination={{
          onChange(current) {
            setPage(current);
          }
        }}
        onChange={onChange}
      />
    </Card>
  )
}
export default EmpMonthwiseAttendanceReport;
