'use client';
import Link from 'next/link';
import { useState, useEffect } 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,
  Card,
  CardContent,
  Drawer,
  DrawerTrigger,
  Input,
  SubmitButton,
  Tabs,
  TabsContent,
  TabsList,
  TabsTrigger,
} from '@/components/ui';
import { toast } from 'sonner';
import { ccn, formatTime, formatDate } from '@/lib/utils';
import {
  Activity,
  Clock,
  Calendar,
  CheckCircle2,
  History,
  Users,
  Zap,
} from 'lucide-react';
import { StatusHistory } from '@/components/layout/status';
import { HistoryTable } from '@/components/layout/status/list/history';

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

export const StatusList = ({
  preloadedUser,
  preloadedStatuses,
}: StatusListProps) => {
  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 [animatingIds, setAnimatingIds] = useState<Set<string>>(new Set());
  const [previousStatuses, setPreviousStatuses] = useState(statuses);

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

  useEffect(() => {
    const newAnimatingIds = new Set<string>();
    statuses.forEach((curr) => {
      const previous = previousStatuses.find((p) => p.user.id === curr.user.id);
      if (previous?.status?.updatedAt !== curr.status?.updatedAt) {
        newAnimatingIds.add(curr.user.id);
      }
    });
    if (newAnimatingIds.size > 0) {
      setAnimatingIds(newAnimatingIds);
      setTimeout(() => setAnimatingIds(new Set()), 800);
    }
    setPreviousStatuses(
      statuses
        .slice()
        .sort(
          (a, b) => (b.status?.updatedAt ?? 0) - (a.status?.updatedAt ?? 0),
        ),
    );
  }, [statuses]);

  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] });
      } else {
        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 getStatusAge = (updatedAt: number) => {
    const diff = Date.now() - updatedAt;
    const hours = Math.floor(diff / (1000 * 60 * 60));
    const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
    if (hours > 0) return `${hours}h ${minutes}m ago`;
    if (minutes > 0) return `${minutes}m ago`;
    return 'Just now';
  };

  const containerCn = ccn({
    context: tvMode,
    className: 'max-w-4xl mx-auto',
    on: 'px-6',
    off: 'px-4 sm:px-6',
  });

  const tabsCn = ccn({
    context: tvMode,
    className: 'w-full py-4 sm:py-8',
    on: 'hidden',
    off: '',
  });

  const headerCn = ccn({
    context: tvMode,
    className: 'w-full mb-2',
    on: 'hidden',
    off: 'hidden sm:flex justify-end items-center',
  });

  return (
    <div className={containerCn}>
      <Tabs defaultValue='status'>
        <TabsList className={tabsCn}>
          <TabsTrigger value='status' className='py-3 sm:py-8'>
            <div className='flex items-center gap-2 sm:gap-3'>
              <Activity className='text-primary w-4 h-4 sm:w-5 sm:h-5' />
              <h1 className='text-base sm:text-2xl font-bold'>Team Status</h1>
            </div>
          </TabsTrigger>
          <TabsTrigger value='history' className='py-3 sm:py-8'>
            <div className='flex items-center gap-2 sm:gap-3'>
              <History className='text-primary w-4 h-4 sm:w-5 sm:h-5' />
              <h1 className='text-base sm:text-2xl font-bold'>
                Status History
              </h1>
            </div>
          </TabsTrigger>
        </TabsList>

        <TabsContent value='status'>
          {/* Mobile toolbar */}
          <div className='sm:hidden mb-3 flex items-center justify-between'>
            <div className='flex items-center gap-2 text-muted-foreground'>
              <Users className='w-4 h-4' />
              <span className='text-sm'>{statuses.length} members</span>
            </div>
            <div className='flex items-center gap-2'>
              <Button variant='outline' size='sm' onClick={handleSelectAll}>
                {selectAll ? 'Clear' : 'Select all'}
              </Button>
              <Link
                href='/table'
                className='text-sm font-medium hover:underline'
              >
                Table
              </Link>
            </div>
          </div>

          {/* Desktop header */}
          <div className={headerCn}>
            <div className='flex items-center gap-4 text-xs sm:text-base'>
              <div className='flex items-center gap-2 text-muted-foreground'>
                <Users className='sm:w-4 sm:h-4 w-3 h-3' />
                <span>{statuses.length} members</span>
              </div>
              <div className='flex items-center gap-2 text-xs'>
                <Link href='/table' className='font-medium hover:underline'>
                  Miss the old table?
                </Link>
              </div>
            </div>
          </div>

          {/* Card list */}
          <div className='space-y-2 sm:space-y-3 pb-24 sm:pb-0'>
            {statuses.map((statusData) => {
              const { user: u, status: s } = statusData;
              const isSelected = selectedUserIds.includes(u.id);
              const isAnimating = animatingIds.has(u.id);
              const isUpdatedByOther = s?.updatedBy?.id !== u.id;

              return (
                <div
                  key={u.id}
                  className={`
                    relative rounded-xl border transition-all
                    ${isAnimating ? 'bg-primary/5 border-primary/30' : ''}
                    ${
                      isSelected
                        ? 'border-primary bg-primary/5'
                        : 'border-border'
                    }
                    ${tvMode ? 'p-5' : 'p-3 sm:p-4'}
                    ${!tvMode ? 'active:scale-[0.99]' : ''}
                  `}
                  onClick={!tvMode ? () => handleSelectUser(u.id) : undefined}
                  role='button'
                  aria-pressed={isSelected}
                >
                  {isSelected && !tvMode && (
                    <div className='absolute top-3 right-3'>
                      <CheckCircle2 className='w-5 h-5 text-primary' />
                    </div>
                  )}

                  <div className='flex items-start gap-3 sm:gap-4'>
                    {/* Avatar */}
                    <div className='flex-shrink-0'>
                      <BasedAvatar
                        src={u.imageUrl}
                        fullName={u.name ?? 'User'}
                        className={`
                          transition-all duration-300
                          ${tvMode ? 'w-18 h-18' : 'w-10 h-10 sm:w-12 sm:h-12'}
                          ${isAnimating ? 'ring-primary/30 ring-4' : ''}
                        `}
                      />
                    </div>

                    {/* Content */}
                    <div className='flex-1 min-w-0'>
                      <div className='flex items-center gap-2 sm:gap-3 mb-1'>
                        <h3
                          className={`
                            font-semibold truncate
                            ${tvMode ? 'text-3xl' : 'text-base sm:text-xl'}
                          `}
                          title={u.name ?? u.email ?? 'User'}
                        >
                          {u.name ?? u.email ?? 'User'}
                        </h3>

                        {isUpdatedByOther && s?.updatedBy && (
                          <div
                            className='hidden sm:flex items-center gap-2
                            text-muted-foreground min-w-0'
                          >
                            <span className='text-sm'>via</span>
                            <BasedAvatar
                              src={s.updatedBy.imageUrl}
                              fullName={s.updatedBy.name ?? 'User'}
                              className='w-4 h-4'
                            />
                            <span className='text-sm truncate'>
                              {s.updatedBy.name ??
                                s.updatedBy.email ??
                                'another user'}
                            </span>
                          </div>
                        )}
                      </div>

                      <div
                        className={`
                          mb-2 sm:mb-3 leading-relaxed break-words
                          ${tvMode ? 'text-2xl' : 'text-[0.95rem] sm:text-lg'}
                          ${
                            s
                              ? 'text-foreground'
                              : 'text-muted-foreground italic'
                          }
                          line-clamp-2
                        `}
                        title={s?.message ?? undefined}
                      >
                        {s?.message ?? 'No status yet.'}
                      </div>

                      {/* Meta */}
                      <div
                        className='flex items-center gap-3 sm:gap-4
                        text-muted-foreground'
                      >
                        <div className='flex items-center gap-1.5'>
                          <Clock className='w-4 h-4 sm:w-4 sm:h-4' />
                          <span className='text-xs sm:text-sm'>
                            {s ? formatTime(s.updatedAt) : '--:--'}
                          </span>
                        </div>
                        <div className='hidden xs:flex items-center gap-1.5'>
                          <Calendar className='w-4 h-4' />
                          <span className='text-xs sm:text-sm'>
                            {s ? formatDate(s.updatedAt) : '--/--'}
                          </span>
                        </div>
                        {s && (
                          <div className='flex items-center gap-1.5'>
                            <Activity className='w-4 h-4' />
                            <span className='text-xs sm:text-sm'>
                              {getStatusAge(s.updatedAt)}
                            </span>
                          </div>
                        )}
                      </div>
                    </div>

                    {/* Actions */}
                    {!tvMode && (
                      <div className='flex flex-col items-end gap-2'>
                        <Drawer>
                          <DrawerTrigger asChild>
                            <Button
                              variant='ghost'
                              size='sm'
                              className='h-8 px-2 sm:px-3'
                              onClick={(e) => e.stopPropagation()}
                            >
                              <History className='w-4 h-4 sm:mr-2' />
                              <span className='hidden sm:inline'>History</span>
                            </Button>
                          </DrawerTrigger>
                          <StatusHistory user={u} />
                        </Drawer>
                      </div>
                    )}
                  </div>

                  {/* Mobile "via user" line */}
                  {isUpdatedByOther && s?.updatedBy && (
                    <div
                      className='sm:hidden mt-2 flex items-center gap-2
                      text-muted-foreground'
                    >
                      <span className='text-xs'>via</span>
                      <BasedAvatar
                        src={s.updatedBy.imageUrl}
                        fullName={s.updatedBy.name ?? 'User'}
                        className='w-4 h-4'
                      />
                      <span className='text-xs truncate'>
                        {s.updatedBy.name ??
                          s.updatedBy.email ??
                          'another user'}
                      </span>
                    </div>
                  )}
                </div>
              );
            })}
          </div>

          {/* Desktop composer */}
          {!tvMode && (
            <Card
              className='mt-5 hidden md:block border-2 border-dashed
              border-muted-foreground/20 hover:border-primary/50
              transition-colors'
            >
              <CardContent className='p-6'>
                <div className='flex flex-col gap-4'>
                  <div className='flex items-center gap-3'>
                    <Zap className='w-5 h-5 text-primary' />
                    <h3 className='text-lg font-semibold'>Update Status</h3>
                    {selectedUserIds.length > 0 && (
                      <span
                        className='px-2 py-1 bg-primary/10 text-primary
                        text-sm rounded-full'
                      >
                        {selectedUserIds.length} selected
                      </span>
                    )}
                  </div>
                  <div className='flex gap-3'>
                    <Input
                      autoFocus
                      type='text'
                      placeholder="What's happening?"
                      className='flex-1 text-lg h-12'
                      value={statusInput}
                      disabled={updatingStatus}
                      onChange={(e) => setStatusInput(e.target.value)}
                      onKeyDown={(e) => {
                        if (
                          e.key === 'Enter' &&
                          !e.shiftKey &&
                          !updatingStatus
                        ) {
                          e.preventDefault();
                          void handleUpdateStatus();
                        }
                      }}
                    />
                    <SubmitButton
                      onClick={handleUpdateStatus}
                      disabled={updatingStatus}
                      className='px-6 h-12'
                    >
                      {selectedUserIds.length > 0
                        ? `Update ${selectedUserIds.length} ${
                            selectedUserIds.length > 1 ? 'users' : 'user'
                          }`
                        : 'Update Status'}
                    </SubmitButton>
                  </div>
                  <div className='flex justify-between items-center'>
                    <div className='flex gap-2'>
                      <Button
                        variant='outline'
                        size='sm'
                        onClick={handleSelectAll}
                      >
                        {selectAll ? 'Deselect All' : 'Select All'}
                      </Button>
                    </div>
                    <div className='text-sm text-muted-foreground'>
                      {statusInput.length}/80 characters
                    </div>
                  </div>
                </div>
              </CardContent>
            </Card>
          )}

          {/* Mobile sticky composer */}
          {!tvMode && (
            <div
              className='md:hidden fixed bottom-0 left-0 right-0 z-50
                border-t bg-background/95 backdrop-blur
                supports-[backdrop-filter]:bg-background/60 p-3
                pb-[calc(0.75rem+env(safe-area-inset-bottom))]'
            >
              <div className='flex items-center justify-between mb-2'>
                {selectedUserIds.length > 0 ? (
                  <span className='text-xs text-muted-foreground'>
                    {selectedUserIds.length} selected
                  </span>
                ) : (
                  <span className='text-xs text-muted-foreground'>
                    Update your status
                  </span>
                )}
                <Button variant='outline' size='sm' onClick={handleSelectAll}>
                  {selectAll ? 'Clear' : 'Select all'}
                </Button>
              </div>
              <div className='flex gap-2'>
                <Input
                  type='text'
                  placeholder="What's happening?"
                  className='h-11 text-base'
                  value={statusInput}
                  disabled={updatingStatus}
                  onChange={(e) => setStatusInput(e.target.value)}
                  onKeyDown={(e) => {
                    if (e.key === 'Enter' && !e.shiftKey && !updatingStatus) {
                      e.preventDefault();
                      void handleUpdateStatus();
                    }
                  }}
                />
                <SubmitButton
                  onClick={handleUpdateStatus}
                  disabled={updatingStatus}
                  className='h-11 px-4'
                >
                  Update
                </SubmitButton>
              </div>
            </div>
          )}
        </TabsContent>

        <TabsContent value='history'>
          <HistoryTable />
        </TabsContent>
      </Tabs>
    </div>
  );
};
