'use client';

import { createClient } from '@/utils/supabase';
import { useState, useEffect, useCallback, useRef } from 'react';
import { useAuth, useTVMode } from '@/components/context';
import {
  getRecentUsersWithStatuses,
  updateStatuses,
  updateUserStatus,
  type UserWithStatus,
} from '@/lib/hooks/status';
import { Drawer, DrawerTrigger, Loading } from '@/components/ui';
import { toast } from 'sonner';
import { HistoryDrawer } from '@/components/status';
import type { Profile } from '@/utils/supabase';
import type { RealtimeChannel } from '@supabase/supabase-js';

type TechTableProps = {
  initialStatuses: UserWithStatus[];
  className?: string;
};

export const TechTable = ({
  initialStatuses = [],
  className = 'w-full max-w-7xl mx-auto px-4',
}: TechTableProps) => {
  const { isAuthenticated } = useAuth();
  const { tvMode } = useTVMode();
  const [loading, setLoading] = useState(true);
  const [selectedIds, setSelectedIds] = useState<string[]>([]);
  const [selectAll, setSelectAll] = useState(false);
  const [statusInput, setStatusInput] = useState('');
  const [usersWithStatuses, setUsersWithStatuses] =
    useState<UserWithStatus[]>(initialStatuses);
  const [selectedHistoryUser, setSelectedHistoryUser] =
    useState<Profile | null>(null);
  const channelRef = useRef<RealtimeChannel | null>(null);

  const fetchRecentUsersWithStatuses = useCallback(async () => {
    try {
      const response = await getRecentUsersWithStatuses();
      if (!response.success) throw new Error(response.error);
      return response.data;
    } catch (error) {
      toast.error(`Error fetching technicians: ${error as Error}`);
      return [];
    }
  }, []);

  // Initial load
  useEffect(() => {
    const loadData = async () => {
      const data = await fetchRecentUsersWithStatuses();
      setUsersWithStatuses(data);
      setLoading(false);
    };
    loadData().catch((error) => {
      console.error('Error loading data:', error);
    });
  }, [fetchRecentUsersWithStatuses, isAuthenticated]);

  const updateStatus = useCallback(async () => {
    if (!isAuthenticated) {
      toast.error('You must be signed in to update statuses.');
      return;
    }
    if (!statusInput.trim()) {
      toast.error('Please enter a valid status.');
      return;
    }
    try {
      if (selectedIds.length === 0) {
        const result = await updateUserStatus(statusInput);
        if (!result.success) throw new Error(result.error);
        toast.success(`Status updated for signed in user.`);
      } else {
        const result = await updateStatuses(selectedIds, statusInput);
        if (!result.success) throw new Error(result.error);
        toast.success(
          `Status updated for ${selectedIds.length} selected users.`,
        );
      }
      setSelectedIds([]);
      setStatusInput('');
    } catch (error) {
      const errorMessage =
        error instanceof Error ? error.message : String(error);
      toast.error(`Failed to update status: ${errorMessage}`);
    }
  }, [isAuthenticated, statusInput, selectedIds]);

  const handleCheckboxChange = (id: string) => {
    setSelectedIds((prev) =>
      prev.includes(id)
        ? prev.filter((prevId) => prevId !== id)
        : [...prev, id],
    );
  };

  const handleSelectAllChange = () => {
    if (selectAll) {
      setSelectedIds([]);
    } else {
      setSelectedIds(usersWithStatuses.map((tech) => tech.user.id));
    }
    setSelectAll(!selectAll);
  };

  useEffect(() => {
    setSelectAll(
      selectedIds.length === usersWithStatuses.length &&
        usersWithStatuses.length > 0,
    );
  }, [selectedIds.length, usersWithStatuses.length]);

  useEffect(() => {
    if (!isAuthenticated) return;
    const supabase = createClient();

    const channel = supabase
      .channel('status_updates', {
        config: { broadcast: { self: true }}
      })
      .on('broadcast', { event: 'status_updated' }, (payload) => {
        const { user_status } = payload.payload as {
        user_status: UserWithStatus;
        timestamp: string;
      };
      console.log('Received status update:', user_status);

      setUsersWithStatuses((prevUsers) => {
        const existingUserIndex = prevUsers.findIndex((u) =>
          u.user.id === user_status.user.id,
        );

        if (existingUserIndex !== -1) {
          const updatedUsers = [...prevUsers];
          updatedUsers[existingUserIndex] = {
            user: user_status.user, // Use the user from the broadcast
            status: user_status.status,
            created_at: user_status.created_at,
            updated_by: user_status.updated_by,
          };
          return updatedUsers;
        } else {
          // Add new user to list!
          return [user_status, ...prevUsers];
        }
      });
    })
    .subscribe((status) => {
      // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
      if (status === 'SUBSCRIBED') {
        console.log('Successfully subscribed to status updates!');
      // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
      } else if (status === 'CHANNEL_ERROR') {
        console.error('Error subscribing to status updates.')
      }
    });

    channelRef.current = channel;

    return () => {
      if (channelRef.current) {
        supabase.removeChannel(channelRef.current).catch((error) => {
          console.error(`Error unsubscribing from status updates: ${error}`);
        });
        channelRef.current = null;
      }
    };
  }, [isAuthenticated]);

  const formatTime = (timestamp: string) => {
    const date = new Date(timestamp);
    const time = date.toLocaleTimeString('en-US', {
      hour: 'numeric',
      minute: 'numeric',
    });
    const day = date.getDate();
    const month = date.toLocaleString('default', { month: 'long' });
    return `${time} - ${month} ${day}`;
  };

  if (loading) {
    return (
      <div className='flex justify-center items-center min-h-[400px]'>
        <Loading className='w-full' alpha={0.5} />
      </div>
    );
  }

  return (
    <div className={className}>
      <table
        className={`w-full text-center border-collapse \
          ${tvMode ? 'text-4xl lg:text-5xl' : 'text-base lg:text-lg'}`}
      >
        <thead>
          <tr className='bg-muted'>
            {!tvMode && (
              <th className='py-3 px-3 border'>
                <input
                  type='checkbox'
                  className='scale-125 cursor-pointer'
                  checked={selectAll}
                  onChange={handleSelectAllChange}
                />
              </th>
            )}
            <th className='py-3 px-4 border font-semibold'>Name</th>
            <th className='py-3 px-4 border font-semibold'>
              <Drawer>
                <DrawerTrigger className='hover:underline'>
                  Status
                </DrawerTrigger>
                <HistoryDrawer />
              </Drawer>
            </th>
            <th className='py-3 px-4 border font-semibold'>Updated At</th>
          </tr>
        </thead>
        <tbody>
          {usersWithStatuses.map((userWithStatus, index) => (
            <tr
              key={userWithStatus.user.id}
              className={`
                ${index % 2 === 0 ? 'bg-muted/50' : 'bg-background'}
                hover:bg-muted/75 transition-all duration-300
              `}
            >
              {!tvMode && (
                <td className='py-2 px-3 border'>
                  <input
                    type='checkbox'
                    className='scale-125 cursor-pointer'
                    checked={selectedIds.includes(userWithStatus.user.id)}
                    onChange={() =>
                      handleCheckboxChange(userWithStatus.user.id)
                    }
                  />
                </td>
              )}
              <td className='py-3 px-4 border font-medium'>
                {userWithStatus.user.full_name ?? 'Unknown User'}
              </td>
              <td className='py-3 px-4 border'>
                <Drawer>
                  <DrawerTrigger
                    className='text-left w-full p-2 rounded hover:bg-muted transition-colors'
                    onClick={() => setSelectedHistoryUser(userWithStatus.user)}
                  >
                    {userWithStatus.status}
                  </DrawerTrigger>
                  {selectedHistoryUser === userWithStatus.user && (
                    <HistoryDrawer user={selectedHistoryUser} />
                  )}
                </Drawer>
              </td>
              <td className='py-3 px-4 border text-muted-foreground'>
                {formatTime(userWithStatus.created_at)}
              </td>
            </tr>
          ))}
        </tbody>
      </table>
      {!tvMode && (
        <div className='mx-auto flex flex-row items-center justify-center py-5 gap-4'>
          <input
            autoFocus
            type='text'
            placeholder='New Status'
            className={
              'min-w-[120px] lg:min-w-[400px] py-2 px-3 rounded-xl \
                border bg-background lg:text-2xl focus:outline-none \
                focus:ring-2 focus:ring-primary'
            }
            value={statusInput}
            onChange={(e) => setStatusInput(e.target.value)}
            onKeyDown={(e) => {
              if (e.key === 'Enter') {
                updateStatus().catch((error) => {
                  toast.error(`Failed to update status: ${error as Error}`);
                });
              }
            }}
          />
          <button
            type='submit'
            className={
              'min-w-[100px] lg:min-w-[160px] py-2 px-4 rounded-xl \
                text-center font-semibold lg:text-2xl bg-primary \
                text-primary-foreground hover:bg-primary/90 \
                transition-colors disabled:opacity-50 \
                disabled:cursor-not-allowed'
            }
            onClick={() => void updateStatus()}
            disabled={!statusInput.trim()}
          >
            Update
          </button>
        </div>
      )}
    </div>
  );
};
