import { Box, Typography } from '@mui/material';
import React, { useEffect, useRef, useState } from 'react';
import { ListingLayout } from '@components1/ds/ListingLayout';
import FilterDropdown from '@components1/ds/FilterDropdown';
import { Button as DsButton } from '@components1/ds/Button';
import DownloadButton from '@common-new/DownloadButton';
import Datetime from '@common-new/format/Datetime';
import CustomTable2 from '@common-new/tables/CustomTable2';
import NotificationRuleModal from './NotificationRuleModal';
import apiNotifications from '@api1/notification';
import apiDashboard from '@api1/home';
import apiKubernetes from '@api1/kubernetes';
import SafeIcon from '@components1/common/SafeIcon';
import { DeleteIconRed as deleteIcon, writeIconLight } from '@assets';
import { hasWriteAccess } from '@lib/auth';
import DeleteNotificationRuleModal from './DeleteNotificationRuleModal';
import Text from '@common-new/format/Text';
import apiUser from '@api1/user';
import { ds } from 'src/utils/colors';
import { safeJSONParse, snakeToTitleCase } from 'src/utils/common';
import { PlatformChannelBadge } from '@components1/common/IconTextBadge';
import StatusBadge from '@components1/common/StatusBadge';

const Notifications = () => {
  const [rowsPerPage, setRowsPerPage] = useState(apiUser.getUserPreferencesTablePageSize());
  const notificationId = 'Notifications';

  const [totalRows, setTotalRows] = useState(0);
  const [loading, setLoading] = useState(false);
  const [currentPage, setCurrentPage] = useState<number>(0);
  const [allNameSpaces, setAllNameSpaces] = useState([]);
  const [namespaceOption, setNamespaceOption] = useState([]);
  const [notificationTableData, setNotificationTableData] = useState([]);
  const [openNotificationRule, setOpenNotificationRule] = useState(false);
  const [clusterOption, setClusterOption] = useState<any[]>([]);
  const [selectedCluster, setSelectedCluster] = useState<string>('');
  const [selectedClusterId, setSelectedClusterId] = useState<string>('');
  const [selectedNamespace, setSelectedNamespace] = useState<string>('');
  const [nsWorkloadOptions, setNSWorkloadOptions] = useState<any>([]);
  const [selectedWorkload, setSelectedWorkload] = useState<string>('');
  const [activeEditRuleData, setActiveEditRuleData] = useState<any>({});
  const [deleteRuleModalVisible, setDeleteRuleModalVisible] = useState<boolean>(false);
  const [editingSource, setEditingSource] = useState('');
  const [clusterMap, setClusterMap] = useState<Map<string, string>>(new Map());

  const [isFetchCluster, setIsFetchCluster] = useState(false);
  const rawRulesRef = useRef<any[]>([]);

  const getClustersData = async () => {
    try {
      const response = await apiDashboard.getCloudAccounts();
      if (response && response.length > 0) {
        const clusters = response.map((item: any) => ({
          id: item.id,
          label: item.account_name,
          value: item.account_name,
        }));
        const map = new Map<string, string>();
        response.forEach((item: any) => {
          map.set(item.id, item.account_name);
        });
        setClusterMap(map);
        setClusterOption(clusters);
      } else {
        setClusterOption([]);
        setClusterMap(new Map());
      }
      setIsFetchCluster(true);
    } catch (error) {
      console.error(error);
    }
  };

  useEffect(() => {
    getClustersData();
    getAllNameSpacesData();
  }, []);

  const getAllNameSpacesData = async () => {
    try {
      const response: any = await apiKubernetes.getAllK8sNamespaces();
      setAllNameSpaces(response?.data);
    } catch (error) {
      console.error(error);
    }
  };

  const getAllWorkloadsData = async () => {
    try {
      if (selectedNamespace) {
        const query: any = {};
        query['namespace'] = selectedNamespace;
        query['kind'] = 'Deployment';
        const response: any = await apiKubernetes.getAllK8sWorkload(query);
        const workloadNameArray: string[] = response?.data.map((item: any) => item.name);
        const uniqueWorkloadNames = Array.from(new Set(workloadNameArray));
        setNSWorkloadOptions(uniqueWorkloadNames);
      }
    } catch (error) {
      console.error(error);
    }
  };

  useEffect(() => {
    getAllWorkloadsData();
  }, [selectedNamespace]);

  const BEST_PRACTICES_HEADER = [
    { name: 'Name', width: '15%' },
    { name: 'Source', width: '10%' },
    { name: 'Cluster', width: '12%' },
    { name: 'Application', width: '18%' },
    { name: 'Channels', width: '18%' },
    { name: 'Status', width: '8%' },
    { name: 'Created By', width: '10%' },
    { name: 'Created At', width: '12%' },
    '',
  ];

  const handleEditRuleModal = (e: any, item: any) => {
    // Look up fresh data from ref to avoid stale closure data
    const freshItem = rawRulesRef.current.find((r: any) => r.id === item.id) || item;
    setActiveEditRuleData(freshItem);
    setEditingSource(freshItem.source.toLowerCase());
    setOpenNotificationRule(true);
  };

  const handleDeleteRuleModal = (e: any, item: any) => {
    setActiveEditRuleData(item);
    setDeleteRuleModalVisible(true);
  };

  const filterNamespaces = (allNameSpaces: any, clusterName: string) => {
    const clusterId: any = clusterOption.filter((item: any) => {
      if (item.label == clusterName) {
        return item;
      }
    });
    const accountSpecificNamespaces = allNameSpaces
      ?.filter((e: any) => e.cloud_account_id == clusterId[0]?.id)
      .map((item: any) => {
        return {
          value: item.namespace_name,
          label: item.namespace_name,
        };
      });
    setNamespaceOption(accountSpecificNamespaces);
  };

  useEffect(() => {
    filterNamespaces(allNameSpaces, selectedCluster);
  }, [selectedCluster, allNameSpaces]);

  useEffect(() => {
    if (isFetchCluster) {
      listNotificationRules();
    }
  }, [currentPage, rowsPerPage, selectedCluster, selectedNamespace, selectedWorkload, isFetchCluster]);

  const listNotificationRules = () => {
    const limit = rowsPerPage;
    const offset = rowsPerPage * currentPage;
    setLoading(true);
    const query: any = {};
    if (selectedClusterId) {
      query.accountId = selectedClusterId;
    }
    if (selectedNamespace) {
      query.namespace = selectedNamespace;
    }
    if (selectedWorkload) {
      query.workload = selectedWorkload;
    }

    apiNotifications.getNotificationRules(query, limit, offset).then((res: any) => {
      const notificationRulesList: any = [];
      const rawRows = res?.data?.notifications_list_rules?.rows || [];
      rawRows.forEach((item: any) => {
        item.notification_rule_mappings = safeJSONParse(item?.notification_rule_mappings) || [];
        const data = [];
        data.push({
          component: <Text value={item.name} />,
        });
        data.push({ component: <Text value={snakeToTitleCase(item.source)} /> });
        data.push({
          component: <Text value={clusterMap.get(item?.account_id) || '-'} />,
        });
        data.push({
          component: (
            <Box>
              <Typography sx={{ fontSize: 'var(--ds-text-body)', fontWeight: 'var(--ds-font-weight-medium)', color: ds.gray[700] }}>
                {item.workload || '-'}
              </Typography>
              {item.namespace && <Typography sx={{ fontSize: 'var(--ds-text-caption)', color: ds.gray[600] }}>ns: {item.namespace}</Typography>}
            </Box>
          ),
        });
        data.push({
          component: (() => {
            if (!item.notification_rule_mappings || item.notification_rule_mappings.length === 0) {
              return <Text value='-' />;
            }
            return (
              <Box sx={{ display: 'flex', flexDirection: 'column', gap: 'var(--ds-space-1)' }}>
                {item.notification_rule_mappings.map((mapping: any, index: number) => {
                  let channelName = '-';
                  if (mapping.platform === 'slack') {
                    channelName = mapping.channels?.name || '-';
                  } else if (mapping.platform === 'ms_teams') {
                    channelName = mapping.channels?.channels?.[0]?.name || mapping.channels?.name || '-';
                  } else if (mapping.platform === 'email') {
                    if (mapping.channels?.emails?.[0]) {
                      channelName = mapping.channels.emails[0];
                    } else if (Array.isArray(mapping.channels) && mapping.channels[0]) {
                      channelName = mapping.channels[0];
                    } else if (mapping.channels?.exclusion_emails?.length > 0) {
                      const count = mapping.channels.exclusion_emails.length;
                      channelName = `${count} user${count > 1 ? 's' : ''} excluded`;
                    } else {
                      return null;
                    }
                  } else {
                    channelName = mapping.channels?.name || '-';
                  }
                  return (
                    <PlatformChannelBadge key={`${mapping.platform}-${index}`} platform={mapping.platform} channelName={channelName} size='medium' />
                  );
                })}
              </Box>
            );
          })(),
        });
        data.push({
          component: (
            <StatusBadge label={item.is_suppressed ? 'Suppressed' : 'Active'} variant={item.is_suppressed ? 'grey' : 'success'} size='medium' />
          ),
        });
        data.push({ text: <Text value={item.created_by_display_name || '-'} /> });
        data.push({ component: <Datetime value={item.created_at} baseDate={new Date()} /> });
        data.push({
          component: (
            <Box display={'flex'} flexDirection={'row'} alignItems={'center'} justifyContent={'flex-end'}>
              {hasWriteAccess() ? (
                <>
                  <Box sx={{ mr: 'var(--ds-space-2)' }}>
                    <DsButton
                      tone='ghost'
                      composition='icon-only'
                      aria-label='Delete'
                      id={`${item.name}-delete`}
                      onClick={(e) => {
                        handleDeleteRuleModal(e, item);
                      }}
                      icon={<SafeIcon src={deleteIcon} alt='delete' width={18} height={18} />}
                    />
                  </Box>
                  <DsButton
                    tone='ghost'
                    composition='icon-only'
                    aria-label='Edit'
                    onClick={(e) => {
                      handleEditRuleModal(e, item);
                    }}
                    icon={<SafeIcon src={writeIconLight} alt='edit' width={18} height={18} />}
                  />
                </>
              ) : (
                <></>
              )}
            </Box>
          ),
        });
        notificationRulesList.push(data);
      });
      rawRulesRef.current = rawRows;
      setNotificationTableData(notificationRulesList);
      setTotalRows(res?.data?.notifications_aggregate_rules?.rows?.[0]?.count || 0);
      setLoading(false);
    });
  };

  const handleButtonAction = () => {
    setOpenNotificationRule(true);
  };

  return (
    <Box position={'relative'}>
      <NotificationRuleModal
        open={openNotificationRule}
        handleClose={() => {
          setOpenNotificationRule(false);
          setActiveEditRuleData({});
          setEditingSource('');
        }}
        listNotificationRules={listNotificationRules}
        notificationRuleObject={activeEditRuleData}
        editingSource={editingSource}
      />
      <DeleteNotificationRuleModal
        open={deleteRuleModalVisible}
        handleClose={() => {
          setDeleteRuleModalVisible(false);
          setActiveEditRuleData({});
        }}
        ruleData={activeEditRuleData}
        listNotificationRules={listNotificationRules}
      />
      <ListingLayout id='notification-container'>
        <ListingLayout.Toolbar
          actions={
            <>
              <DownloadButton onClick={() => ({ tableId: notificationId })} />
              {hasWriteAccess() && (
                <DsButton id='notification-rule' tone='primary' size='md' onClick={() => handleButtonAction()}>
                  Create Rule
                </DsButton>
              )}
            </>
          }
        >
          <FilterDropdown
            id='notification-filter-cluster'
            label='Cluster'
            options={clusterOption}
            value={selectedCluster ? clusterOption.find((o) => o.value === selectedCluster) ?? null : null}
            onSelect={(_e: any, item: any) => {
              const value = item?.value || '';
              setSelectedCluster(value);
              setSelectedClusterId(clusterOption.find((option) => option.value === value)?.id || '');
              setSelectedNamespace('');
              setSelectedWorkload('');
            }}
          />
          <FilterDropdown
            id='notification-filter-namespace'
            label='Namespace'
            options={namespaceOption || []}
            value={selectedNamespace ? { label: selectedNamespace, value: selectedNamespace } : null}
            disabled={!(selectedCluster?.length > 0)}
            onSelect={(_e: any, item: any) => {
              setSelectedNamespace(item?.value || '');
              setSelectedWorkload('');
            }}
          />
          <FilterDropdown
            id='notification-filter-application'
            label='Application'
            options={nsWorkloadOptions || []}
            value={selectedWorkload ? { label: selectedWorkload, value: selectedWorkload } : null}
            disabled={!(selectedNamespace?.length > 0)}
            onSelect={(_e: any, item: any) => {
              setSelectedWorkload(item?.value || '');
            }}
          />
        </ListingLayout.Toolbar>

        <ListingLayout.Body>
          <CustomTable2
            headers={BEST_PRACTICES_HEADER}
            tableData={notificationTableData as any}
            rowsPerPage={rowsPerPage}
            totalRows={totalRows}
            onPageChange={(page: number, limit: number) => {
              setCurrentPage(page - 1);
              setRowsPerPage(limit);
            }}
            id={notificationId}
            loading={loading}
            showExpandable={false}
            upperHeaders={[]}
            onSortChange={() => undefined}
            stickyColumnIndex='10'
            pageNumber={currentPage + 1}
          />
        </ListingLayout.Body>
      </ListingLayout>
    </Box>
  );
};

export default Notifications;
