'use client';
import Link from 'next/link';
import { useState } from 'react';
import { type Preloaded, usePreloadedQuery, useMutation } from 'convex/react';
import { api } from '~/convex/_generated/api';
import { type Id } from '~/convex/_generated/dataModel';
import { useTVMode } from '@/components/providers';
import {
  BasedAvatar,
  Button,
  Drawer,
  DrawerTrigger,
  Input,
  SubmitButton,
} from '@/components/ui';
import { toast } from 'sonner';
import { ccn, formatTime, formatDate } from '@/lib/utils';
import { Clock, Calendar } from 'lucide-react';
import { StatusHistory } from '@/components/layout/status';

type StatusTableProps = {
  preloadedUser: Preloaded<typeof api.auth.getUser>;
  preloadedStatuses: Preloaded<typeof api.statuses.getCurrentForAll>;
};

export const StatusTable = ({
  preloadedUser,
  preloadedStatuses,
}: StatusTableProps) => {
  const user = usePreloadedQuery(preloadedUser);
  const statuses = usePreloadedQuery(preloadedStatuses);

  const { tvMode } = useTVMode();
  const [selectedUserIds, setSelectedUserIds] = useState<Id<'users'>[]>([]);
  const [selectAll, setSelectAll] = useState(false);
  const [statusInput, setStatusInput] = useState('');
  const [updatingStatus, setUpdatingStatus] = useState(false);

  const bulkCreate = useMutation(api.statuses.bulkCreate);

  const handleSelectUser = (id: Id<'users'>) => {
    setSelectedUserIds((prev) =>
      prev.some((i) => i === id)
        ? prev.filter((prevId) => prevId !== id)
        : [...prev, id],
    );
  };

  const handleSelectAll = () => {
    if (selectAll) setSelectedUserIds([]);
    else setSelectedUserIds(statuses.map((s) => s.user.id));
    setSelectAll(!selectAll);
  };

  const handleUpdateStatus = async () => {
    const message = statusInput.trim();
    setUpdatingStatus(true);
    try {
      if (message.length < 3 || message.length > 80)
        throw new Error('Status must be between 3 & 80 characters');
      if (selectedUserIds.length === 0 && user?.id)
        await bulkCreate({ message, userIds: [user.id] });
      await bulkCreate({ message, userIds: selectedUserIds });
      toast.success('Status updated.');
      setSelectedUserIds([]);
      setSelectAll(false);
      setStatusInput('');
    } catch (error) {
      toast.error(`Update failed. ${error as Error}`);
    } finally {
      setUpdatingStatus(false);
    }
  };

  const containerCn = ccn({
    context: tvMode,
    className: 'mx-auto',
    on: 'lg:w-11/12 w-full',
    off: 'w-5/6',
  });
  const headerCn = ccn({
    context: tvMode,
    className: 'w-full mb-2 flex justify-between',
    on: '',
    off: 'mb-2',
  });
  const thCn = ccn({
    context: tvMode,
    className: 'py-4 px-4 border font-semibold ',
    on: 'lg:text-6xl xl:min-w-[420px]',
    off: 'lg:text-5xl xl:min-w-[320px]',
  });
  const tdCn = ccn({
    context: tvMode,
    className: 'py-2 px-2 border',
    on: 'lg:text-5xl',
    off: 'lg:text-4xl',
  });
  const tCheckboxCn = `py-3 px-4 border`;
  const checkBoxCn = `lg:scale-200 cursor-pointer`;

  return (
    <div className={containerCn}>
      <div className={headerCn}>
        <div className='flex items-center gap-2'>
          {!tvMode && (
            <div className='flex flex-row gap-2 text-xs'>
              <p className='text-muted-foreground'>Tired of the old table? </p>
              <Link
                href='/'
                className='italic font-semibold hover:text-primary/80'
              >
                Try the new status list!
              </Link>
            </div>
          )}
        </div>
      </div>
      <table className='w-full text-center rounded-md'>
        <thead>
          <tr className='bg-muted'>
            {!tvMode && (
              <th className={tCheckboxCn}>
                <input
                  type='checkbox'
                  className={checkBoxCn}
                  checked={selectAll}
                  onChange={handleSelectAll}
                />
              </th>
            )}
            <th className={thCn}>Technician</th>
            <th className={thCn}>
              <Drawer>
                <DrawerTrigger className='hover:text-foreground/60 cursor-pointer'>
                  Status
                </DrawerTrigger>
                <StatusHistory />
              </Drawer>
            </th>
            <th className={thCn}>Updated At</th>
          </tr>
        </thead>
        <tbody>
          {statuses.map((status, i) => {
            const { user: u, status: s } = status;
            const isSelected = selectedUserIds.includes(u.id);
            return (
              <tr
                key={u.id}
                className={`
                  ${i % 2 === 0 ? 'bg-muted/50' : 'bg-background'}
                  ${isSelected ? 'ring-2 ring-primary' : ''}
                  hover:bg-muted/75 transition-all duration-300
                `}
              >
                {!tvMode && (
                  <td className={tCheckboxCn}>
                    <input
                      type='checkbox'
                      className={checkBoxCn}
                      checked={isSelected}
                      onChange={() => handleSelectUser(u.id)}
                    />
                  </td>
                )}
                <td className={tdCn}>
                  <div className='flex items-center gap-3'>
                    <BasedAvatar
                      src={u.imageUrl}
                      fullName={u.name}
                      className={tvMode ? 'w-16 h-16' : 'w-12 h-12'}
                    />
                    <div>
                      <p> {u.name ?? 'Technician #' + (i + 1)} </p>
                      {s?.updatedBy && s.updatedBy.id !== u.id && (
                        <div className='flex items-center gap-1 text-muted-foreground'>
                          <BasedAvatar
                            src={s.updatedBy.imageUrl}
                            fullName={s.updatedBy.name}
                            className='w-5 h-5'
                          />
                          <span className={tvMode ? 'text-xl' : 'text-base'}>
                            Updated by {s.updatedBy.name}
                          </span>
                        </div>
                      )}
                    </div>
                  </div>
                </td>
                <td className={tdCn}>
                  <Drawer>
                    <DrawerTrigger>{s?.message}</DrawerTrigger>
                    <StatusHistory user={u} />
                  </Drawer>
                </td>
                <td className={tdCn}>
                  <Drawer>
                    <DrawerTrigger>
                      <div className='flex w-full'>
                        <div className='flex flex-col my-auto items-start'>
                          <div className='flex gap-4 my-1'>
                            <Clock
                              className={`${tvMode ? 'lg:w-11 lg:h-11' : 'lg:w-9 lg:h-9'}`}
                            />
                            <p
                              className={`${tvMode ? 'text-4xl' : 'text-3xl'}`}
                            >
                              {s ? formatTime(s.updatedAt) : '--:--'}
                            </p>
                          </div>
                          <div className='flex gap-4 my-1'>
                            <Calendar
                              className={`${tvMode ? 'lg:w-11 lg:h-11' : 'lg:w-9 lg:h-9'}`}
                            />
                            <p
                              className={`${tvMode ? 'text-4xl' : 'text-3xl'}`}
                            >
                              {s ? formatDate(s.updatedAt) : '--:--'}
                            </p>
                          </div>
                        </div>
                      </div>
                    </DrawerTrigger>
                    <StatusHistory user={u} />
                  </Drawer>
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
      {statuses.length === 0 && (
        <div className='p-8 text-center'>
          <p
            className={`text-muted-foreground ${tvMode ? 'text-4xl' : 'text-lg'}`}
          >
            No status updates yet
          </p>
        </div>
      )}
      {!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:max-w-[400px] py-6 px-3 rounded-xl \
                border bg-background lg:text-2xl focus:outline-none \
                focus:ring-2 focus:ring-primary'
            }
            value={statusInput}
            disabled={updatingStatus}
            onChange={(e) => setStatusInput(e.target.value)}
            onKeyDown={(e) => {
              if (e.key === 'Enter' && !e.shiftKey && !updatingStatus) {
                e.preventDefault();
                void handleUpdateStatus();
              }
            }}
          />
          <SubmitButton
            className={
              'px-8 rounded-xl font-semibold lg:text-2xl \
              disabled:opacity-50 disabled:cursor-not-allowed \
              cursor-pointer'
            }
            onClick={handleUpdateStatus}
            disabled={updatingStatus}
            pendingText='Updating...'
          >
            {selectedUserIds.length > 0
              ? `Update status for ${selectedUserIds.length}
                ${selectedUserIds.length > 1 ? 'users' : 'user'}`
              : 'Update status'}
          </SubmitButton>
        </div>
      )}

      {/* Global Status History Drawer */}
      {!tvMode && (
        <div className='flex justify-center mt-6'>
          <Drawer>
            <DrawerTrigger asChild>
              <Button
                variant='outline'
                className={tvMode ? 'text-3xl p-6' : ''}
              >
                View All Status History
              </Button>
            </DrawerTrigger>
            <StatusHistory />
          </Drawer>
        </div>
      )}
    </div>
  );
};
