'use client';

import { useState, useCallback, useEffect, useMemo } from 'react';
import Stack from '@mui/material/Stack';
import Container from '@mui/material/Container';
import Typography from '@mui/material/Typography';
import { CircularProgress, Breadcrumbs, Link, Chip, Divider, Tooltip } from '@mui/material';
import ToggleButton from '@mui/material/ToggleButton';
import ToggleButtonGroup from '@mui/material/ToggleButtonGroup';
import { useSnackbar } from '@/shared/components/snackbar';
import { useSettingsContext } from '@/shared/components/settings';
import { useTable, getComparator } from '@/shared/components/table';
import EmptyContent from '@/shared/components/empty-content';
import { IFile, IFileFilters } from '@/shared/types/file';
import { fileManagerApi } from '@/shared/api/file-manager';
import FileManagerTable from '../file-manager-table';
import FileManagerGridView from '../file-manager-grid-view';
import FileManagerFilters from '../file-manager-filters';
import Iconify from '@/shared/components/iconify';
import { useBoolean } from '@/hooks/use-boolean';
import { useDocuments } from '@/hooks/use-list-document';
import CustomPopover, { usePopover } from '@/shared/components/custom-popover';
import MenuItem from '@mui/material/MenuItem';
import Button from '@mui/material/Button';
import { ConfirmDialog } from '@/shared/components/custom-dialog';
import FileManagerNewFolderDialog from '../file-manager-new-folder-dialog';
import { AccessLevel } from '@/shared/api/file-manager';
import { FILE_TYPE_OPTIONS } from '@/shared/_mock';
import { useCopyToClipboard } from '@/hooks';

interface FolderContentsViewProps {
  folderId: number;
  folderName: string;
  onBack: () => void;
  onOpenFolder?: (folderId: number, folderName: string) => void;
  section: 'PERSONAL' | 'SHARED' | 'SHARED_WITH_ME';
}

const defaultFilters: IFileFilters = {
  name: '',
  type: [],
  startDate: null,
  endDate: null,
};

export default function FolderContentsView({ 
  folderId, 
  folderName, 
  onBack,
  onOpenFolder ,
  section
}: FolderContentsViewProps) {
  const { enqueueSnackbar } = useSnackbar();
  const settings = useSettingsContext();
  const table = useTable({ defaultRowsPerPage: 10 });
  const [view, setView] = useState('list');
  const [loading, setLoading] = useState(true);
  const [contents, setContents] = useState<IFile[]>([]);
  const [error, setError] = useState<string | null>(null);
  const [showFavorites, setShowFavorites] = useState(false);
  const [filters, setFilters] = useState(defaultFilters);
  const confirm = useBoolean();
  const { copy } = useCopyToClipboard();
  const upload = useBoolean();
  const newFolder = useBoolean();
  const openDateRange = useBoolean();
  const [folderNameInput, setFolderNameInput] = useState('');
  const popover = usePopover();
  const { toggleFavorite, refetch } = useDocuments(section);
  const availableFolders = useMemo(() => {
   const folders = contents
      .filter(doc => 
        doc.type === 'folder' && 
        Number(doc.id) !== folderId
      )
      .map(folder => ({ 
        name: folder.name.trim(), 
        path: folder.path?.trim() || '' 
      }));
    return folders;
  }, [contents, folderId]);
  
  const loadFolderContents = useCallback(async () => {
    try {
      setLoading(true);
      const response = await fileManagerApi.getFolderContents(folderId);
      
      const formattedData: IFile[] = response.map((doc: any) => ({
        id: doc.id,
        name: doc.name,
        size: doc.size || null,
        type: doc.type || 'file',
        url: doc.url || '',
        tags: doc.tags || [],
        isFavorited: doc.isFavorited || false,
        shared: doc.shared || null,
        createdAt: doc.createdAt || null,
        modifiedAt: doc.modifiedAt || doc.updatedAt || new Date().toISOString(),
        visibility: doc.visibility || 'PRIVATE',
        permissions: doc.permissions || 'READ',
        path: doc.path || '',
        ownerFullName: doc.ownerFullName || 'Unknown User',
        userOwner: doc.userOwner || 0,
        uniqueId: doc.uniqueId || doc.id,
        agency: doc.agency || 0,
        childrenFiles: doc.childrenFiles || [],
        childrenFolders: doc.childrenFolders || [],
        parentFolder: doc.parentFolder || null,
        ...(doc.type === 'folder' && { totalFiles: doc.totalFiles || 0 }),
      }));

      setContents(formattedData);
      setError(null);
    } catch (err) {
      console.error('Error loading folder contents:', err);
      setError('Failed to load folder contents');
      enqueueSnackbar('Error loading folder contents', { variant: 'error' });
    } finally {
      setLoading(false);
    }
  }, [folderId, enqueueSnackbar]);

  useEffect(() => {
    loadFolderContents();
  }, [loadFolderContents]);

  const handleChangeView = useCallback(
    (event: React.MouseEvent<HTMLElement>, newView: string | null) => {
      if (newView !== null) {
        setView(newView);
      }
    },
    []
  );

  const handleFilters = useCallback(
    (name: string, value: any) => {
      table.onResetPage();
      setFilters((prevState) => ({
        ...prevState,
        [name]: value,
      }));
    },
    [table]
  );

  const handleResetFilters = useCallback(() => {
    setFilters(defaultFilters);
  }, []);

  const handleToggleFavorite = useCallback(() => {
    setShowFavorites((prev) => !prev);
  }, []);

  const handleCreateFolder = useCallback(async () => {
    try {
      const email = localStorage.getItem('email');
      const agencyId = Number(localStorage.getItem('selectedAgency'));

      if (!email) {
        enqueueSnackbar('User email not found', { variant: 'error' });
        return;
      }

      if (!folderNameInput.trim()) {
        enqueueSnackbar('Folder name cannot be empty', { variant: 'error' });
        return;
      }

      switch (section) {
        case 'PERSONAL':
          await fileManagerApi.createPrivateFolder(
            folderNameInput,
            folderId || null
          );
          break;

        case 'SHARED':
          if (!agencyId) {
            enqueueSnackbar('Agency not selected', { variant: 'error' });
            return;
          }
          await fileManagerApi.createSharedFolder(
            folderNameInput,
            folderId || null
          );
          break;

        case 'SHARED_WITH_ME':
          enqueueSnackbar('You cannot create folders in shared with me section', { variant: 'error' });
          return;
      }

      enqueueSnackbar('Folder created successfully');
      newFolder.onFalse();
      setFolderNameInput('');
      await loadFolderContents();
    } catch (error) {
      console.error('Error creating folder:', error);
      enqueueSnackbar('Error creating folder', { variant: 'error' });
    }
  }, [folderId, folderNameInput, section, enqueueSnackbar, newFolder, loadFolderContents]);
  const handleCreateCopy = useCallback(async (uniqueId: string, destinationPath: string) => {
    try {
      await fileManagerApi.createCopy(uniqueId, destinationPath);
      enqueueSnackbar('Copy created successfully', { variant: 'success' });
      refetch(); 
    } catch (error) {
      console.error('Error creating copy:', error);
      enqueueSnackbar('Error creating copy', { variant: 'error' });
    }
  }, [enqueueSnackbar, refetch]);

  const handleDeleteItem = useCallback(async (id: string) => {
    try {
      const itemToDelete = contents.find(item => item.id === id);
      if (!itemToDelete?.path) {
        throw new Error('Document path is missing');
      }
      
      await fileManagerApi.deleteDocuments(itemToDelete.userOwner, [itemToDelete.path]);
      enqueueSnackbar('Document deleted successfully');
      loadFolderContents();
    } catch (error) {
      console.error(error);
      enqueueSnackbar('Error deleting document', { variant: 'error' });
    }
  }, [contents, enqueueSnackbar, loadFolderContents]);

  const handleDownload = useCallback(async (uniqueId: string, name: string) => {
    try {
      await fileManagerApi.downloadElement(uniqueId, name);
      enqueueSnackbar('Download started successfully', { variant: 'success' });
    } catch (error) {
      console.error('Error downloading file:', error);
      enqueueSnackbar('Error downloading file', { variant: 'error' });
    }
  }, [enqueueSnackbar]);

  const handleDeleteItems = useCallback(async () => {
    try {
      const itemsToDelete = contents.filter(item => table.selected.includes(item.id));
      const paths = itemsToDelete
        .filter(item => item.path)
        .map(item => item.path as string);
      
      if (paths.length === 0) {
        throw new Error('No valid paths to delete');
      }

      await fileManagerApi.deleteDocuments(itemsToDelete[0].userOwner, paths);
      enqueueSnackbar('Documents deleted successfully');
      loadFolderContents();
      confirm.onFalse();
    } catch (error) {
      console.error(error);
      enqueueSnackbar('Error deleting documents', { variant: 'error' });
    }
  }, [contents, table.selected, enqueueSnackbar, loadFolderContents, confirm]);

  const handleChangeFolderName = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
    setFolderNameInput(event.target.value);
  }, []);
  const handleCopy = useCallback(async (uniqueId: string) => {
    try {
      const shareLink = await fileManagerApi.generateShareLink(uniqueId);
      await copy(shareLink);
      enqueueSnackbar('Link copied to clipboard!', { variant: 'success' });
    } catch (error) {
      console.error('Error generating share link:', error);
      enqueueSnackbar('Error generating share link', { variant: 'error' });
    }
  }, [copy, enqueueSnackbar]);
  const dataFiltered = applyFilter({
    inputData: showFavorites ? contents.filter((file) => file.isFavorited) : contents,
    comparator: getComparator(table.order, table.orderBy),
    filters,
  });

  const renderBreadcrumbs = (
    <Stack 
      direction="row" 
      alignItems="center" 
      spacing={2}
      sx={{ mb: 3 }}
    >
      <Button
        variant="text"
        color="inherit"
        startIcon={<Iconify icon="eva:arrow-ios-back-fill" />}
        onClick={onBack}
      >
        Back
      </Button>
      <Breadcrumbs separator={<Iconify icon="eva:arrow-ios-forward-fill" />}>
        <Link
          component="button"
          variant="subtitle2"
          onClick={onBack}
          sx={{ 
            color: 'text.primary',
            '&:hover': { textDecoration: 'underline' }
          }}
        >
          File Manager
        </Link>
        <Typography variant="subtitle2" color="primary">
          {folderName}
        </Typography>
      </Breadcrumbs>
    </Stack>
  );

  const renderFilters = (
    <Stack
      spacing={2.5}
      direction={{ xs: 'column', md: 'row' }}
      alignItems={{ xs: 'flex-end', md: 'center' }}
    >
      <FileManagerFilters
        openDateRange={openDateRange.value}
        onCloseDateRange={openDateRange.onFalse}
        onOpenDateRange={openDateRange.onTrue}
        filters={filters}
        onFilters={handleFilters}
        dateError={false}
        typeOptions={FILE_TYPE_OPTIONS}
      />

      <ToggleButtonGroup size="small" value={view} exclusive onChange={handleChangeView}>
        <Tooltip title="List view" arrow>
          <ToggleButton value="list">
            <Iconify icon="solar:list-bold" />
          </ToggleButton>
        </Tooltip>
        <Tooltip title="Grid view" arrow>
          <ToggleButton value="grid">
            <Iconify icon="mingcute:dot-grid-fill" />
          </ToggleButton>
        </Tooltip>
      </ToggleButtonGroup>
    </Stack>
  );

  const renderContent = () => {
    if (loading) {
      return (
        <Stack alignItems="center" justifyContent="center" sx={{ py: 10 }}>
          <CircularProgress />
        </Stack>
      );
    }

    if (error) {
      return (
        <EmptyContent         
          title="Error"
          description={error}
          filled
          sx={{ py: 10 }}
        />
      );
    }

    if (!dataFiltered.length) {
      return (
        <EmptyContent
          title="No data found"
          description={showFavorites ? "No favorites found" : "This folder is empty"}
          filled
          sx={{ py: 10 }}
        />
      );
    }

    return (
      <>
        {view === 'list' ? (
          <FileManagerTable
            availableFolders={availableFolders}
            table={table}
            dataFiltered={dataFiltered}
            onDeleteRow={handleDeleteItem}
            onRefresh={loadFolderContents}
            notFound={!dataFiltered.length}
            onOpenConfirm={confirm.onTrue}
            onToggleFavorite={toggleFavorite}
            onOpenFolder={onOpenFolder}
            onCopyLink={handleCopy}
            onCreateCopy={handleCreateCopy} 
            section={section}          />
        ) : (
          <FileManagerGridView
            table={table}
            dataFiltered={dataFiltered}
            onDeleteItem={handleDeleteItem}
            onRefresh={loadFolderContents}
            onToggleFavorite={toggleFavorite}
            onOpenConfirm={confirm.onTrue}
            notFound={!dataFiltered.length}
            onOpenFolder={onOpenFolder}
            onCopyLink={handleCopy}
          />
        )}
      </>
    );
  };

  return (
    <Container maxWidth={settings.themeStretch ? false : 'lg'}>
      <Stack spacing={2.5}>
        {renderBreadcrumbs}
        
        <Stack direction="row" alignItems="center" justifyContent="space-between">
          <Typography variant="h4">Folder Contents</Typography>

          <Stack direction="row" spacing={1} justifyContent="flex-end">
            <Chip
              label="New"
              icon={<Iconify icon="typcn:plus" sx={{ width: 25, height: 25 }} />}
              onClick={popover.onOpen}
            />
            <Divider orientation="vertical" flexItem />
            <Tooltip title="Favorites" arrow>
              <Iconify
                icon={showFavorites ? 'mdi:favorite-box' : 'mdi:favorite-box-outline'}
                color={'#FFAB00'}
                sx={{ width: 35, height: 35, cursor: 'pointer' }}
                onClick={handleToggleFavorite}
              />
            </Tooltip>
          </Stack>
        </Stack>

        {renderFilters}

        {renderContent()}

        <CustomPopover
          open={popover.open}
          onClose={popover.onClose}
          arrow="top-right"
          sx={{ width: 160 }}
        >
          <MenuItem onClick={() => {
            newFolder.onTrue();
            popover.onClose();
          }}>
            <Iconify icon="solar:folder-with-files-bold" sx={{ mr: 1 }} />
            New Folder
          </MenuItem>
          <MenuItem onClick={() => {
            upload.onTrue();
            popover.onClose();
          }}>
            <Iconify icon="solar:upload-bold" sx={{ mr: 1 }} />
            Upload
          </MenuItem>
        </CustomPopover>

        <FileManagerNewFolderDialog 
          open={upload.value} 
          onClose={upload.onFalse} 
        />

        <FileManagerNewFolderDialog
          open={newFolder.value}
          onClose={newFolder.onFalse}
          title="New Folder"
          onCreate={handleCreateFolder}
          folderName={folderNameInput}
          onChangeFolderName={handleChangeFolderName}
        />

        <ConfirmDialog
          open={confirm.value}
          onClose={confirm.onFalse}
          title="Delete"
          content={
            <>
              Are you sure want to delete <strong> {table.selected.length} </strong> items?
            </>
          }
          action={
            <Button
              variant="contained"
              color="error"
              onClick={handleDeleteItems}
            >
              Delete
            </Button>
          }
        />
      </Stack>
    </Container>
  );
}

function applyFilter({
  inputData,
  comparator,
  filters,
}: {
  inputData: IFile[];
  comparator: (a: any, b: any) => number;
  filters: IFileFilters;
}) {
  const { name, type, startDate, endDate } = filters;

  const stabilizedThis = inputData.map((el, index) => [el, index] as const);

  stabilizedThis.sort((a, b) => {
    const order = comparator(a[0], b[0]);
    if (order !== 0) return order;
    return a[1] - b[1];
  });

  inputData = stabilizedThis.map((el) => el[0]);

  if (name) {
    inputData = inputData.filter(
      (file) => file.name.toLowerCase().indexOf(name.toLowerCase()) !== -1
    );
  }

  if (type.length) {
    inputData = inputData.filter((file) => type.includes(file.type));
  }

  if (startDate && endDate) {
    inputData = inputData.filter(
      (file) =>
        new Date(file.createdAt || 0) >= new Date(startDate) &&
        new Date(file.createdAt || 0) <= new Date(endDate)
    );
  }

  return inputData;
}