'use client';

import { useCallback, useEffect, useMemo, useState } from 'react';
import { Box, Stack, Typography } from '@mui/material';
import { HEADER } from '@/layouts/config-layout';
import TableControlBar from '@/shared/components/table/table-control-bar';
import { TableType } from '@/shared/types/common';
import TabsCustom from '@/shared/components/tabs/tabs-custom';
import TableManager from '@/shared/components/table/table-manager';
import EstablishmentForm from './establishment-form-view';
import ScheduleTable, { ScheduleHoursDTO } from '@/shared/components/form/schedule-table';
import { ScrollBox } from '@/shared/theme/css';
import { UnsavedChangesDialog } from '@/shared/components/dialog/UnsavedChangesDialog';
import { DayOfWeek, EstablishmentHoursResponse, EstablishmentTableItem } from '@/shared/types/establishment';
import { useEstablishmentTabs } from '../hooks/use-establishment-tabs';
import { useEstablishmentTable } from '../hooks/use-establishment-table';
import EstablishmentTableRow from './establishment-table-row';
import { DaysOfWeek } from '@/shared/types/passenger';
import { useSnackbar } from 'notistack';
import ConditionalComponent from '@/shared/components/table/ConditionalComponent';


export default function EstablishmentListView() {

  const { enqueueSnackbar } = useSnackbar();

  const [scheduleState, setScheduleState] = useState({
    showScheduleTable: false,
    selectedEtablissement: null as EstablishmentTableItem | null,
    defaultTime: "08:00 AM",
  })

  const {
    tabs,
    activeTab,
    handleTabClose,
    handleTabChange,
    handleTabAdd,
    handleEdit,
    handleView,
    handleCancel,
    handleCopy,
    showConfirmDialog,
    setShowConfirmDialog,
    handleConfirmDialogAction,
    updateTabContent,
  } = useEstablishmentTabs();

  const {
    error,
    clearError,
    loading,
    table,
    filteredData,
    filters,
    tableHead,
    notFound,
    handleFilterChange,
    handleResetFilters,
    handleResetColumns,
    handleColumnsChange,
    handleSave,
    dataToExport,
    totalEstablishments,
    onPageChange,
    page,
    onRowsPerPageChange,
    rowsPerPage,
    sortBy,
    sortDirection,
    handleStartExportEstablishments,
    onResetFilters
  } = useEstablishmentTable();

  const activeTabData = useMemo(() => {
    return tabs.find((tab) => tab.id === activeTab);
  }, [tabs, activeTab]);

  const handleHoraireClick = useCallback((etablissement: EstablishmentTableItem) => {
    setScheduleState((prevState) => {
      if (prevState.selectedEtablissement?.id === etablissement.id) {
        return {
          ...prevState,
          showScheduleTable: !prevState.showScheduleTable,
          selectedEtablissement: etablissement,
          scheduleData: transformEstablishmentHours(etablissement.hours),
        }
      } else {
        const randomHour = Math.floor(Math.random() * 12) + 1
        const amPm = Math.random() < 0.5 ? "AM" : "PM"
        const newTime = `${randomHour.toString().padStart(2, "0")}:00 ${amPm}`
        return {
          showScheduleTable: true,
          selectedEtablissement: etablissement,
          defaultTime: newTime,
        }
      }
    })
  }, [])

  const renderRow = (row: EstablishmentTableItem) => (
    <EstablishmentTableRow
      key={row.id}
      dense={table.dense}
      row={row}
      handleHoraireClick={handleHoraireClick}
      handleEdit={handleEdit}
      handleCopy={handleCopy}
      handleDetails={handleView}
      selected={table.selected.includes(row.id)}
      selectedHoraire={row.id === scheduleState.selectedEtablissement?.id}
      onSelectRow={() => table.onSelectRow(row.id)}
      columns={tableHead.slice(0, -1)}
    />
  );

  const isList = activeTab === 'list';
  const CustomBox = isList && scheduleState.showScheduleTable ? ScrollBox : Box;

  const exportOptions = useMemo(() => [
    {
      label: "Exporter en CSV",
      action: () => handleStartExportEstablishments()
    }
  ], [handleStartExportEstablishments]);

  const mapDay = (day: DayOfWeek): DaysOfWeek => {
    switch (day) {
      case DayOfWeek.MONDAY:
        return DaysOfWeek.MONDAY;
      case DayOfWeek.TUESDAY:
        return DaysOfWeek.TUESDAY;
      case DayOfWeek.WEDNESDAY:
        return DaysOfWeek.WEDNESDAY;
      case DayOfWeek.THURSDAY:
        return DaysOfWeek.THURSDAY;
      case DayOfWeek.FRIDAY:
        return DaysOfWeek.FRIDAY;
      case DayOfWeek.SATURDAY:
        return DaysOfWeek.SATURDAY;
      case DayOfWeek.SUNDAY:
        return DaysOfWeek.SUNDAY;
      default:
        throw new Error(`Jour de la semaine non pris en charge: ${day}`);
    }
  };

  const transformEstablishmentHours = (
    hoursList: EstablishmentHoursResponse[]
  ): ScheduleHoursDTO[] => {
    return hoursList.map((hour) => {
      return {
        id: hour.id,
        dayOfWeek: mapDay(hour.dayOfWeek),
        morningOpeningTime: hour.morningOpeningTime,
        eveningClosingTime: hour.eveningClosingTime,
      };
    });
  }

  useEffect(() => {
    if (error) {
      enqueueSnackbar(error, { variant: 'error' });
      clearError();
    }
  }, [error, enqueueSnackbar, clearError]);

  return (
    <CustomBox
      sx={
        isList && scheduleState.showScheduleTable
          ? { pb: 0, height: `calc(100vh - ${HEADER.H_DESKTOP + 20}px)` }
          : {
            display: 'flex',
            flexDirection: 'column',
            height: `calc(100vh - ${HEADER.H_DESKTOP + 8}px)`,
          }
      }
    >
      <Stack
        flexGrow={0}
        direction="row"
        alignItems="center"
        justifyContent="flex-end"
        spacing={{ xs: 0.5, sm: 1 }}
      >
        <TableControlBar
          type={TableType.Etablissement}
          handleTabAdd={handleTabAdd}
          activeTab={activeTab}
          onResetFilters={onResetFilters}
          onResetColumns={handleResetColumns}
          onColumnsChange={handleColumnsChange}
          initialColumns={tableHead.slice(0, -1)}
          onFilters={handleFilterChange}
          filteredData={dataToExport}
          useBackendExport={true}
          exportOptions={exportOptions}
        />
      </Stack>

      <ConditionalComponent isValid={scheduleState.showScheduleTable}>
        <Typography
          variant="h5"
          sx={{
            mb: 2,
            color: 'primary.main',
            fontWeight: 'bold',
          }}
        >
          Liste Établissements
        </Typography>
      </ConditionalComponent>

      <TabsCustom
        type={TableType.Etablissement}
        tabs={tabs}
        activeTab={activeTab}
        handleTabChange={handleTabChange}
        handleTabClose={handleTabClose}
      />

      <ConditionalComponent isValid={isList}>
        <TableManager
          loading={loading}
          filteredData={filteredData}
          table={table}
          tableHead={tableHead}
          notFound={notFound}
          filters={filters}
          onFilterChange={handleFilterChange}
          renderRow={renderRow}
          fixedHeight={scheduleState.showScheduleTable ? `calc(100vh - ${HEADER.H_DESKTOP + 195}px)` : undefined}
          onPageChange={onPageChange}
          page={page || 0}
          onRowsPerPageChange={onRowsPerPageChange}
          rowsPerPage={rowsPerPage || 20}
          sortBy={sortBy || 'id'}
          sortDirection={sortDirection || 'desc'}
          count={totalEstablishments || 0}
        />
        <ConditionalComponent isValid={scheduleState.showScheduleTable}>
          <ScheduleTable
            title={`${scheduleState.selectedEtablissement?.establishmentName} (Horaire)`}
            defaultTime={scheduleState.defaultTime}
            mode="time"
            isInEstablishment
            scheduleData={transformEstablishmentHours(scheduleState.selectedEtablissement?.hours || [])}
          />
        </ConditionalComponent>
      </ConditionalComponent>

      <ConditionalComponent isValid={!isList}>
        <EstablishmentForm
          key={activeTab}
          etablissement={activeTabData?.content as EstablishmentTableItem}
          mode={activeTabData?.mode || 'view'}
          onSave={handleSave}
          onClose={(force) => handleCancel(activeTab, force)}
          onEdit={handleEdit}
          tableHead={tableHead.slice(0, -1)}
          updateTabContent={updateTabContent}
          tabId={activeTab}
        />
      </ConditionalComponent>

      <UnsavedChangesDialog
        open={showConfirmDialog}
        onClose={() => setShowConfirmDialog(false)}
        onConfirm={() => handleConfirmDialogAction()}
        onCancel={() => setShowConfirmDialog(false)}
      />
    </CustomBox>
  );
}