import React, { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import {
  Button,
  DataTable,
  DataTableSkeleton,
  Pagination,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableHeader,
  TableRow,
  TableToolbar,
  TableToolbarContent,
  TableToolbarSearch,
} from '@carbon/react';
import { Download } from '@carbon/react/icons';
import { ConfigurableLink, useConfig, usePagination } from '@openmrs/esm-framework';
import { useUnscheduledAppointments } from '../../hooks/useUnscheduledAppointments';
import { exportUnscheduledAppointmentsToSpreadsheet } from '../../helpers/excel';
import { EmptyState } from '../../empty-state/empty-state.component';
import { getPageSizes, useSearchResults, filterUnscheduledAppointmentsByServiceType } from '../utils';
import { type ConfigObject } from '../../config-schema';

interface UnscheduledAppointmentsProps {
  appointmentServiceTypes?: Array<string>;
}

const UnscheduledAppointments: React.FC<UnscheduledAppointmentsProps> = ({ appointmentServiceTypes }) => {
  const { t } = useTranslation();
  const [pageSize, setPageSize] = useState(25);

  const [searchString, setSearchString] = useState('');
  const { data: unscheduledAppointments, isLoading, error } = useUnscheduledAppointments();

  const filteredAppointments = filterUnscheduledAppointmentsByServiceType(
    unscheduledAppointments || [],
    appointmentServiceTypes || [],
  );

  const searchResults = useSearchResults(filteredAppointments, searchString);
  const { customPatientChartUrl } = useConfig<ConfigObject>();

  const headerData = [
    {
      header: t('patientName', 'Patient Name'),
      key: 'name',
    },
    {
      header: t('identifier', 'Identifier'),
      key: 'identifier',
    },
    {
      header: t('gender', 'Gender'),
      key: 'gender',
    },
    {
      header: t('phoneNumber', 'Phone Number'),
      key: 'phoneNumber',
    },
    {
      header: t('service', 'Service'),
      key: 'service',
    },
  ];

  const { results, currentPage, goTo } = usePagination(searchResults, pageSize);

  const rowData =
    results?.map((appointment) => {
      const patientDisplay = appointment.patient?.display || '';
      const [identifier, ...nameParts] = patientDisplay.split(' - ');
      const patientName = nameParts.join(' - ') || 'Unknown Patient';

      return {
        id: `${appointment.appointmentId}`,
        name: (
          <ConfigurableLink
            style={{ textDecoration: 'none' }}
            to={customPatientChartUrl}
            templateParams={{ patientUuid: appointment.patient?.uuid }}
          >
            {patientName}
          </ConfigurableLink>
        ),
        gender: 'Unknown',
        phoneNumber: '--',
        identifier: identifier || '--',
        service: appointment.service?.name || t('noService', 'No service assigned'),
      };
    }) || [];

  if (isLoading) {
    return <DataTableSkeleton />;
  }

  if (error) {
    return (
      <div style={{ padding: '20px', color: 'red' }}>
        <strong>Error loading appointments:</strong> {error.message || 'Unknown error'}
      </div>
    );
  }

  if (!unscheduledAppointments?.length) {
    return (
      <EmptyState
        displayText={t('unscheduledAppointments_lower', 'unscheduled appointments')}
        headerTitle={t('unscheduledAppointments', 'Unscheduled appointments')}
      />
    );
  }

  if (!filteredAppointments?.length && appointmentServiceTypes?.length) {
    return (
      <div>
        <div style={{ padding: '10px', backgroundColor: '#fff3cd', marginBottom: '10px', border: '1px solid #ffeaa7' }}>
          <strong>Filter Info:</strong>
          <br />
          Total unscheduled appointments: {unscheduledAppointments?.length || 0}
          <br />
          After service filtering: {filteredAppointments?.length || 0}
          <br />
          Selected filters: {appointmentServiceTypes?.join(', ') || 'None'}
          <br />
        </div>

        <EmptyState
          displayText={t('noMatchingAppointments', 'No matching appointments found')}
          headerTitle={t('noMatchingAppointments', 'No matching appointments found')}
        />
      </div>
    );
  }

  return (
    <div>
      <DataTable rows={rowData} headers={headerData} isSortable>
        {({ rows, headers, getHeaderProps, getTableProps }) => (
          <TableContainer
            title={`${t('unscheduledAppointments', 'Unscheduled appointments')} (${filteredAppointments.length})`}
            description={t('totalAppointments', `Total ${filteredAppointments.length ?? 0} appointments`)}
          >
            <TableToolbar>
              <TableToolbarContent>
                <TableToolbarSearch
                  style={{ backgroundColor: '#f4f4f4' }}
                  tabIndex={0}
                  onChange={(event) => setSearchString(event.target.value)}
                  placeholder={t('searchAppointments', 'Search appointments...')}
                />
                <Button
                  size="lg"
                  kind="tertiary"
                  renderIcon={Download}
                  onClick={() => exportUnscheduledAppointmentsToSpreadsheet(filteredAppointments)}
                  disabled={!filteredAppointments?.length}
                >
                  {t('download', 'Download')}
                </Button>
              </TableToolbarContent>
            </TableToolbar>
            <Table {...getTableProps()}>
              <TableHead>
                <TableRow>
                  {headers.map((header) => (
                    <TableHeader key={header.key} {...getHeaderProps({ header })}>
                      {header.header}
                    </TableHeader>
                  ))}
                </TableRow>
              </TableHead>
              <TableBody>
                {rows.map((row) => (
                  <TableRow key={row.id}>
                    {row.cells.map((cell) => (
                      <TableCell key={cell.id}>{cell.value}</TableCell>
                    ))}
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </TableContainer>
        )}
      </DataTable>

      <Pagination
        backwardText={t('previousPage', 'Previous page')}
        forwardText={t('nextPage', 'Next page')}
        page={currentPage}
        pageNumberText={t('pageNumber', 'Page Number')}
        pageSize={pageSize}
        onChange={({ page, pageSize: newPageSize }) => {
          goTo(page);
          setPageSize(newPageSize);
        }}
        pageSizes={getPageSizes(filteredAppointments, pageSize) ?? []}
        totalItems={filteredAppointments.length ?? 0}
      />
    </div>
  );
};

export default UnscheduledAppointments;
