import React from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { RefreshCcw } from 'lucide-react';
import { YStack, XStack } from '@tamagui/stacks';
import { SizableText as Text } from '@tamagui/text';
import { MobileShell, HeaderActionButton } from './components/MobileShell';
import { MobileCard, CTAButton, PillBadge, SkeletonCard } from './components/Primitives';
import { MobileSelect, MobileField } from './components/FormControls';
import { useEventContext } from '../context/EventContext';
import {
  approveAndLiveShowPhoto,
  approveLiveShowPhoto,
  clearLiveShowPhoto,
  getEvents,
  getLiveShowQueue,
  LiveShowQueueStatus,
  rejectLiveShowPhoto,
  TenantEvent,
  TenantPhoto,
} from '../api';
import { isAuthError } from '../auth/tokens';
import { getApiErrorMessage } from '../lib/apiError';
import { adminPath } from '../constants';
import toast from 'react-hot-toast';
import { useBackNavigation } from './hooks/useBackNavigation';
import { useAdminTheme } from './theme';
import { useOnlineStatus } from './hooks/useOnlineStatus';

const STATUS_OPTIONS: Array<{ value: LiveShowQueueStatus; labelKey: string; fallback: string }> = [
  { value: 'pending', labelKey: 'liveShowQueue.statusPending', fallback: 'Pending' },
  { value: 'approved', labelKey: 'liveShowQueue.statusApproved', fallback: 'Approved' },
  { value: 'rejected', labelKey: 'liveShowQueue.statusRejected', fallback: 'Rejected' },
  { value: 'none', labelKey: 'liveShowQueue.statusNone', fallback: 'Not queued' },
];

export default function MobileEventLiveShowQueuePage() {
  const { slug: slugParam } = useParams<{ slug?: string }>();
  const navigate = useNavigate();
  const { t } = useTranslation('management');
  const { activeEvent, selectEvent } = useEventContext();
  const slug = slugParam ?? activeEvent?.slug ?? null;
  const online = useOnlineStatus();
  const { textStrong, text, muted, border, danger } = useAdminTheme();
  const [photos, setPhotos] = React.useState<TenantPhoto[]>([]);
  const [statusFilter, setStatusFilter] = React.useState<LiveShowQueueStatus>('pending');
  const [page, setPage] = React.useState(1);
  const [hasMore, setHasMore] = React.useState(false);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState<string | null>(null);
  const [busyId, setBusyId] = React.useState<number | null>(null);
  const [fallbackAttempted, setFallbackAttempted] = React.useState(false);
  const back = useBackNavigation(slug ? adminPath(`/mobile/events/${slug}`) : adminPath('/mobile/events'));

  React.useEffect(() => {
    if (slugParam && activeEvent?.slug !== slugParam) {
      selectEvent(slugParam);
    }
  }, [slugParam, activeEvent?.slug, selectEvent]);

  const loadQueue = React.useCallback(async () => {
    if (!slug) {
      if (!fallbackAttempted) {
        setFallbackAttempted(true);
        try {
          const events = await getEvents({ force: true });
          const first = events[0] as TenantEvent | undefined;
          if (first?.slug) {
            selectEvent(first.slug);
            navigate(adminPath(`/mobile/events/${first.slug}/live-show`), { replace: true });
          }
        } catch {
          // ignore
        }
      }
      setLoading(false);
      setError(t('events.errors.missingSlug', 'No event selected.'));
      return;
    }

    setLoading(true);
    setError(null);
    try {
      const result = await getLiveShowQueue(slug, {
        page,
        perPage: 20,
        liveStatus: statusFilter,
      });
      setPhotos((prev) => (page === 1 ? result.photos : [...prev, ...result.photos]));
      const lastPage = result.meta?.last_page ?? 1;
      setHasMore(page < lastPage);
    } catch (err) {
      if (!isAuthError(err)) {
        const message = getApiErrorMessage(err, t('liveShowQueue.loadFailed', 'Live Show queue could not be loaded.'));
        setError(message);
        toast.error(message);
      }
    } finally {
      setLoading(false);
    }
  }, [slug, page, statusFilter, fallbackAttempted, navigate, selectEvent, t]);

  React.useEffect(() => {
    setPage(1);
  }, [statusFilter]);

  React.useEffect(() => {
    void loadQueue();
  }, [loadQueue]);

  async function handleApprove(photo: TenantPhoto) {
    if (!slug || busyId) return;
    setBusyId(photo.id);
    try {
      const updated = await approveLiveShowPhoto(slug, photo.id);
      setPhotos((prev) => prev.map((item) => (item.id === photo.id ? updated : item)));
      toast.success(t('liveShowQueue.approveSuccess', 'Photo approved for Live Show'));
    } catch (err) {
      if (!isAuthError(err)) {
        toast.error(t('liveShowQueue.actionFailed', 'Live Show update failed.'));
      }
    } finally {
      setBusyId(null);
    }
  }

  async function handleApproveAndLive(photo: TenantPhoto) {
    if (!slug || busyId) return;
    setBusyId(photo.id);
    try {
      const updated = await approveAndLiveShowPhoto(slug, photo.id);
      setPhotos((prev) => prev.map((item) => (item.id === photo.id ? updated : item)));
      toast.success(t('liveShowQueue.approveAndLiveSuccess', 'Photo approved and added to Live Show'));
    } catch (err) {
      if (!isAuthError(err)) {
        toast.error(t('liveShowQueue.actionFailed', 'Live Show update failed.'));
      }
    } finally {
      setBusyId(null);
    }
  }

  async function handleReject(photo: TenantPhoto) {
    if (!slug || busyId) return;
    setBusyId(photo.id);
    try {
      const updated = await rejectLiveShowPhoto(slug, photo.id);
      setPhotos((prev) => prev.map((item) => (item.id === photo.id ? updated : item)));
      toast.success(t('liveShowQueue.rejectSuccess', 'Photo removed from Live Show'));
    } catch (err) {
      if (!isAuthError(err)) {
        toast.error(t('liveShowQueue.actionFailed', 'Live Show update failed.'));
      }
    } finally {
      setBusyId(null);
    }
  }

  async function handleClear(photo: TenantPhoto) {
    if (!slug || busyId) return;
    setBusyId(photo.id);
    try {
      const updated = await clearLiveShowPhoto(slug, photo.id);
      setPhotos((prev) => prev.map((item) => (item.id === photo.id ? updated : item)));
      toast.success(t('liveShowQueue.clearSuccess', 'Live Show approval removed'));
    } catch (err) {
      if (!isAuthError(err)) {
        toast.error(t('liveShowQueue.actionFailed', 'Live Show update failed.'));
      }
    } finally {
      setBusyId(null);
    }
  }

  function resolveStatusTone(status?: string | null): 'success' | 'warning' | 'muted' {
    if (status === 'approved') return 'success';
    if (status === 'pending') return 'warning';
    return 'muted';
  }

  function resolveGalleryLabel(status?: string | null): string {
    const fallbackMap: Record<string, string> = {
      approved: 'Gallery approved',
      pending: 'Gallery pending',
      rejected: 'Gallery rejected',
      hidden: 'Hidden',
    };
    const key = status ?? 'pending';
    return t(`liveShowQueue.galleryStatus.${key}`, fallbackMap[key] ?? key);
  }

  return (
    <MobileShell
      activeTab="home"
      title={t('liveShowQueue.title', 'Live Show queue')}
      subtitle={t('liveShowQueue.subtitle', 'Approve photos for the live slideshow')}
      onBack={back}
      headerActions={
        <HeaderActionButton onPress={() => loadQueue()} ariaLabel={t('common.refresh', 'Refresh')}>
          <RefreshCcw size={18} color={textStrong} />
        </HeaderActionButton>
      }
    >
      <MobileCard borderColor={border} backgroundColor="transparent">
        <Text fontSize="$sm" color={muted}>
          {t(
            'liveShowQueue.galleryApprovedOnly',
            'Gallery and Live Show approvals are separate. Pending photos can be approved here.'
          )}
        </Text>
        {!online ? (
          <Text fontSize="$sm" color={danger}>
            {t('liveShowQueue.offlineNotice', 'You are offline. Live Show actions are disabled.')}
          </Text>
        ) : null}
      </MobileCard>

      <MobileCard>
        <MobileField label={t('liveShowQueue.filterLabel', 'Live status')}>
          <MobileSelect
            value={statusFilter}
            onChange={(event) => setStatusFilter(event.target.value as LiveShowQueueStatus)}
          >
            {STATUS_OPTIONS.map((option) => (
              <option key={option.value} value={option.value}>
                {t(option.labelKey, option.fallback)}
              </option>
            ))}
          </MobileSelect>
        </MobileField>
      </MobileCard>

      {error ? (
        <MobileCard>
          <Text fontWeight="700" color={danger}>
            {error}
          </Text>
        </MobileCard>
      ) : null}

      {loading && page === 1 ? (
        <YStack space="$2">
          {Array.from({ length: 4 }).map((_, idx) => (
            <SkeletonCard key={`skeleton-${idx}`} height={120} />
          ))}
        </YStack>
      ) : photos.length === 0 ? (
        <MobileCard>
          <Text fontWeight="700" color={text}>
            {t('liveShowQueue.empty', 'No photos waiting for Live Show.')}
          </Text>
        </MobileCard>
      ) : (
        <YStack space="$2">
          {photos.map((photo) => {
            const isBusy = busyId === photo.id;
            const liveStatus = photo.live_status ?? 'pending';
            const galleryStatus = photo.status ?? 'pending';
            const canApproveGallery = galleryStatus === 'pending';
            const canApproveLiveOnly = galleryStatus === 'approved';
            const canApproveLive = canApproveGallery || canApproveLiveOnly;
            const showApproveAction = liveStatus !== 'approved';
            return (
              <MobileCard key={photo.id}>
                <XStack space="$3" alignItems="center">
                  {photo.thumbnail_url ? (
                    <img
                      src={photo.thumbnail_url}
                      alt={photo.original_name ?? 'Photo'}
                      style={{
                        width: 86,
                        height: 86,
                        borderRadius: 14,
                        objectFit: 'cover',
                        border: `1px solid ${border}`,
                      }}
                    />
                  ) : null}
                  <YStack flex={1} space="$2">
                    <XStack alignItems="center" space="$2">
                      <PillBadge tone={resolveStatusTone(galleryStatus)}>
                        {resolveGalleryLabel(galleryStatus)}
                      </PillBadge>
                      <PillBadge tone={resolveStatusTone(liveStatus)}>
                        {t(`liveShowQueue.status.${liveStatus}`, liveStatus)}
                      </PillBadge>
                    </XStack>
                    <Text fontSize="$sm" color={muted}>
                      {photo.uploaded_at}
                    </Text>
                  </YStack>
                </XStack>
                <XStack space="$2" marginTop="$2">
                  {showApproveAction ? (
                    <CTAButton
                      label={
                        canApproveGallery
                          ? t('liveShowQueue.approveAndLive', 'Approve + Live')
                          : canApproveLiveOnly
                            ? t('liveShowQueue.approve', 'Approve for Live Show')
                            : t('liveShowQueue.notEligible', 'Not eligible')
                      }
                      onPress={() => {
                        if (canApproveGallery) {
                          void handleApproveAndLive(photo);
                          return;
                        }
                        if (canApproveLiveOnly) {
                          void handleApprove(photo);
                        }
                      }}
                      disabled={!online || !canApproveLive}
                      loading={isBusy}
                      tone="primary"
                    />
                  ) : (
                    <CTAButton
                      label={t('liveShowQueue.clear', 'Remove from Live Show')}
                      onPress={() => handleClear(photo)}
                      disabled={!online}
                      loading={isBusy}
                      tone="ghost"
                    />
                  )}
                  {liveStatus !== 'rejected' ? (
                    <CTAButton
                      label={t('liveShowQueue.reject', 'Reject')}
                      onPress={() => handleReject(photo)}
                      disabled={!online}
                      loading={isBusy}
                      tone="danger"
                    />
                  ) : (
                    <CTAButton
                      label={t('liveShowQueue.clear', 'Remove from Live Show')}
                      onPress={() => handleClear(photo)}
                      disabled={!online}
                      loading={isBusy}
                      tone="ghost"
                    />
                  )}
                </XStack>
              </MobileCard>
            );
          })}
        </YStack>
      )}

      {hasMore ? (
        <MobileCard>
          <CTAButton
            label={t('common.loadMore', 'Load more')}
            onPress={() => setPage((prev) => prev + 1)}
            disabled={loading}
          />
        </MobileCard>
      ) : null}
    </MobileShell>
  );
}
