import { CalendarClock, Clapperboard, Filter, Gamepad2, Tv } from 'lucide-solid'
import { For, Show, createMemo, createResource, createSignal } from 'solid-js'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Card, CardContent } from '@/components/ui/card'
import { DataRow } from '@/components/ui/data-row'
import { EmptyState } from '@/components/ui/empty-state'
import { SectionHeading } from '@/components/ui/section-heading'
import { Skeleton } from '@/components/ui/skeleton'
import { dashboardService } from '@/services/dashboard-service'
import type { MediaItem, MediaType } from '@/types/domain'
import { formatDate } from '@/utils/format'
import { mediaBadgeVariant, mediaTypeLabel } from '@/utils/media'

const monthLabel = (date: string): string =>
  new Intl.DateTimeFormat('en-US', { month: 'long', year: 'numeric' }).format(new Date(date))

const typeIcon = (type: MediaType) => {
  if (type === 'movie') return Clapperboard
  if (type === 'show') return Tv
  return Gamepad2
}

export const CalendarPage = () => {
  const [activeType, setActiveType] = createSignal<MediaType | 'all'>('all')
  const [dashboardData, { refetch }] = createResource(() => dashboardService.getDashboard())
  const upcoming = createMemo(() => dashboardData()?.upcoming ?? [])

  const monthGroups = createMemo(() => {
    const filtered = upcoming().filter((item) => (activeType() === 'all' ? true : item.type === activeType()))

    const grouped = new Map<string, MediaItem[]>()
    for (const item of filtered) {
      const key = monthLabel(item.releaseDate)
      grouped.set(key, [...(grouped.get(key) ?? []), item])
    }

    return Array.from(grouped.entries()).map(([label, items]) => ({
      label,
      items: items.sort((a, b) => +new Date(a.releaseDate) - +new Date(b.releaseDate)),
    }))
  })

  const totals = createMemo(() => ({
    all: upcoming().length,
    movie: upcoming().filter((item) => item.type === 'movie').length,
    show: upcoming().filter((item) => item.type === 'show').length,
    game: upcoming().filter((item) => item.type === 'game').length,
  }))

  return (
    <section class="space-y-6" data-testid="calendar-page">
      <Card class="animate-stagger">
        <CardContent class="space-y-6 pt-6">
          <SectionHeading
            eyebrow="Release Calendar"
            title="Track upcoming movies, episodes, and game launches in one timeline."
            description="A calm scheduling surface tuned for planning your next week of watch and play sessions."
            badge={<Badge variant="neutral">{totals().all} upcoming releases</Badge>}
            action={
              <Button variant="subtle" size="sm" onClick={() => refetch()}>
                Refresh
              </Button>
            }
          />

          <div class="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
            <div class="rounded-2xl border border-border bg-muted/40 p-4">
              <p class="text-xs uppercase tracking-[0.2em] text-muted-fg">Movies</p>
              <p class="mt-2 text-2xl font-semibold text-fg">{totals().movie}</p>
            </div>
            <div class="rounded-2xl border border-border bg-muted/40 p-4">
              <p class="text-xs uppercase tracking-[0.2em] text-muted-fg">Shows</p>
              <p class="mt-2 text-2xl font-semibold text-fg">{totals().show}</p>
            </div>
            <div class="rounded-2xl border border-border bg-muted/40 p-4">
              <p class="text-xs uppercase tracking-[0.2em] text-muted-fg">Games</p>
              <p class="mt-2 text-2xl font-semibold text-fg">{totals().game}</p>
            </div>
            <div class="rounded-2xl border border-border bg-muted/40 p-4">
              <p class="text-xs uppercase tracking-[0.2em] text-muted-fg">Months</p>
              <p class="mt-2 text-2xl font-semibold text-fg">{monthGroups().length}</p>
            </div>
          </div>

          <div class="flex flex-wrap items-center gap-2">
            <Badge variant="neutral">
              <Filter class="mr-1 h-3.5 w-3.5" />
              Filter
            </Badge>
            <Button size="sm" variant={activeType() === 'all' ? 'primary' : 'ghost'} onClick={() => setActiveType('all')}>
              All
            </Button>
            <Button
              size="sm"
              variant={activeType() === 'movie' ? 'primary' : 'ghost'}
              onClick={() => setActiveType('movie')}
            >
              Movies
            </Button>
            <Button size="sm" variant={activeType() === 'show' ? 'primary' : 'ghost'} onClick={() => setActiveType('show')}>
              Shows
            </Button>
            <Button size="sm" variant={activeType() === 'game' ? 'primary' : 'ghost'} onClick={() => setActiveType('game')}>
              Games
            </Button>
          </div>
        </CardContent>
      </Card>

      <Show when={dashboardData.loading && upcoming().length === 0}>
        <div class="space-y-4">
          <For each={Array.from({ length: 3 }, (_, index) => index)}>{() => <Skeleton class="h-36" />}</For>
        </div>
      </Show>

      <Show
        when={monthGroups().length > 0}
        fallback={
          <Card>
            <CardContent class="pt-6">
              <EmptyState
                title="No upcoming releases"
                description="The release calendar will populate as upcoming content is synced."
              />
            </CardContent>
          </Card>
        }
      >
        <div class="space-y-5">
          <For each={monthGroups()}>
            {(group) => (
              <Card>
                <CardContent class="space-y-4 pt-6">
                  <div class="flex items-center justify-between">
                    <div>
                      <h3 class="text-base font-semibold text-fg">{group.label}</h3>
                      <p class="mt-1 text-sm text-muted-fg">{group.items.length} scheduled items</p>
                    </div>
                    <Badge variant="secondary">
                      <CalendarClock class="mr-1 h-3.5 w-3.5" />
                      Timeline
                    </Badge>
                  </div>

                  <div class="space-y-3">
                    <For each={group.items}>
                      {(item) => {
                        const Icon = typeIcon(item.type)
                        return (
                          <DataRow
                            tone={mediaBadgeVariant(item.type)}
                            eyebrow={mediaTypeLabel(item.type)}
                            title={item.title}
                            description={item.genres.slice(0, 2).join(' • ')}
                            meta={formatDate(item.releaseDate)}
                            badges={<Badge variant={mediaBadgeVariant(item.type)}>{mediaTypeLabel(item.type)}</Badge>}
                            trailing={
                              <div class="flex h-10 w-10 items-center justify-center rounded-2xl border border-border bg-muted text-fg">
                                <Icon class="h-4 w-4" />
                              </div>
                            }
                          />
                        )
                      }}
                    </For>
                  </div>
                </CardContent>
              </Card>
            )}
          </For>
        </div>
      </Show>

      <Show when={dashboardData.error}>
        <div class="rounded-[1.5rem] border border-secondary/24 bg-secondary/10 px-4 py-4 text-sm text-fg">
          {dashboardData.error instanceof Error ? dashboardData.error.message : 'Failed to load calendar'}
        </div>
      </Show>
    </section>
  )
}
