'use client';

import { useMutation, useQuery } from '@tanstack/react-query';
import { keepPreviousData } from '@tanstack/react-query';
import { parseAsInteger, parseAsString, useQueryStates } from 'nuqs';
import { useRouter } from 'next/navigation';
import { toast } from 'sonner';
import { Icons } from '@/components/icons';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue
} from '@/components/ui/select';
import { NotificationCard, type NotificationAction } from '@/components/ui/notification-card';
import {
  Pagination,
  PaginationContent,
  PaginationItem,
  PaginationNext,
  PaginationPrevious
} from '@/components/ui/pagination';
import { markAllNotificationsAsReadMutation, markNotificationAsReadMutation } from '../api/mutations';
import { notificationsQueryOptions } from '../api/queries';
import { NOTIFICATION_TYPE_OPTIONS } from '../constants/notification-options';

function getNotificationAction(href: string | null): NotificationAction[] {
  if (!href) return [];

  return [
    {
      id: 'open',
      label: 'เปิดรายการ',
      type: 'redirect',
      style: 'primary'
    }
  ];
}

export default function NotificationsPage() {
  const router = useRouter();
  const [params, setParams] = useQueryStates({
    page: parseAsInteger.withDefault(1),
    perPage: parseAsInteger.withDefault(10),
    search: parseAsString,
    status: parseAsString.withDefault('all'),
    type: parseAsString
  });

  const filters = {
    page: params.page,
    limit: params.perPage,
    ...(params.search && { search: params.search }),
    ...(params.status && { status: params.status as 'all' | 'unread' | 'read' }),
    ...(params.type && { type: params.type as (typeof NOTIFICATION_TYPE_OPTIONS)[number]['value'] })
  };

  const { data, error, isFetching, isPending } = useQuery({
    ...notificationsQueryOptions(filters),
    placeholderData: keepPreviousData
  });

  const markRead = useMutation({
    ...markNotificationAsReadMutation,
    onSuccess: () => {
      toast.success('อ่านการแจ้งเตือนแล้ว');
    },
    onError: (mutationError) => {
      toast.error(mutationError.message || 'ไม่สามารถอัปเดตการแจ้งเตือนได้');
    }
  });

  const markAllRead = useMutation({
    ...markAllNotificationsAsReadMutation,
    onSuccess: (response) => {
      toast.success(response.message);
    },
    onError: (mutationError) => {
      toast.error(mutationError.message || 'ไม่สามารถอัปเดตการแจ้งเตือนได้');
    }
  });

  const updateParams = (updates: Partial<typeof params>) => {
    void setParams({
      ...updates,
      page: 1
    });
  };

  if (error) {
    return (
      <Card className='border-dashed'>
        <CardContent className='flex flex-col items-center justify-center gap-4 py-12 text-center'>
          <div className='bg-muted flex h-12 w-12 items-center justify-center rounded-full'>
            <Icons.warning className='text-muted-foreground h-6 w-6' />
          </div>
          <div className='space-y-1'>
            <h3 className='text-lg font-semibold'>ไม่สามารถโหลดการแจ้งเตือนได้</h3>
            <p className='text-muted-foreground text-sm'>{error.message}</p>
          </div>
        </CardContent>
      </Card>
    );
  }

  if ((isPending && !data) || !data) {
    return (
      <Card className='border-dashed'>
        <CardContent className='flex flex-col items-center justify-center gap-4 py-12 text-center'>
          <Icons.spinner className='text-muted-foreground h-6 w-6 animate-spin' />
          <p className='text-muted-foreground text-sm'>กำลังโหลดการแจ้งเตือน</p>
        </CardContent>
      </Card>
    );
  }

  const hasActiveFilters = Boolean(
    (params.search && params.search.trim()) ||
      params.status === 'unread' ||
      params.status === 'read' ||
      params.type
  );
  const totalPages = Math.max(1, Math.ceil(data.total_notifications / params.perPage));

  return (
    <div className='space-y-4'>
      <div className='flex flex-col gap-3 rounded-lg border p-3'>
        <div className='flex flex-col gap-2 lg:flex-row lg:items-center lg:justify-between'>
          <div className='flex min-w-0 flex-1 flex-col gap-2 md:flex-row'>
            <Input
              value={params.search ?? ''}
              onChange={(event) => updateParams({ search: event.target.value || null })}
              placeholder='ค้นหาจากหัวข้อหรือรายละเอียด'
              className='w-full min-w-0 md:max-w-md'
            />
            <Select
              value={params.status}
              onValueChange={(value) => updateParams({ status: value })}
            >
              <SelectTrigger className='w-full md:w-[180px]'>
                <SelectValue placeholder='สถานะ' />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value='all'>ทั้งหมด</SelectItem>
                <SelectItem value='unread'>ยังไม่อ่าน</SelectItem>
                <SelectItem value='read'>อ่านแล้ว</SelectItem>
              </SelectContent>
            </Select>
            <Select
              value={params.type ?? 'all'}
              onValueChange={(value) => updateParams({ type: value === 'all' ? null : value })}
            >
              <SelectTrigger className='w-full md:w-[220px]'>
                <SelectValue placeholder='ประเภท' />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value='all'>ทุกประเภท</SelectItem>
                {NOTIFICATION_TYPE_OPTIONS.map((option) => (
                  <SelectItem key={option.value} value={option.value}>
                    {option.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          <div className='flex flex-wrap items-center gap-2'>
            <div className='text-muted-foreground text-sm'>
              ยังไม่อ่าน <span className='font-semibold text-foreground'>{data.unread_count}</span>
            </div>
            {isFetching ? (
              <span className='text-muted-foreground inline-flex items-center gap-2 text-sm'>
                <Icons.spinner className='h-4 w-4 animate-spin' />
                กำลังโหลด
              </span>
            ) : null}
            <Button
              variant='outline'
              size='sm'
              onClick={() => markAllRead.mutate()}
              disabled={markAllRead.isPending || data.unread_count === 0}
            >
              อ่านทั้งหมด
            </Button>
            {hasActiveFilters ? (
              <Button
                variant='outline'
                size='sm'
                onClick={() =>
                  void setParams({
                    page: 1,
                    search: null,
                    status: 'all',
                    type: null
                  })
                }
              >
                ล้างตัวกรอง
              </Button>
            ) : null}
          </div>
        </div>
      </div>

      {data.notifications.length === 0 ? (
        <Card className='border-dashed'>
          <CardContent className='flex flex-col items-center justify-center gap-4 py-12 text-center'>
            <div className='bg-muted flex h-12 w-12 items-center justify-center rounded-full'>
              <Icons.notification className='text-muted-foreground h-6 w-6' />
            </div>
            <div className='space-y-1'>
              <h3 className='text-lg font-semibold'>
                {hasActiveFilters ? 'ไม่พบการแจ้งเตือนที่ตรงกับตัวกรอง' : 'ยังไม่มีการแจ้งเตือน'}
              </h3>
              <p className='text-muted-foreground max-w-md text-sm'>
                {hasActiveFilters
                  ? 'ลองปรับคำค้นหา สถานะ หรือประเภท แล้วค้นหาอีกครั้ง'
                  : 'เมื่อมีการอนุมัติ ปฏิเสธ หรืองานสำคัญในระบบ การแจ้งเตือนจะแสดงที่หน้านี้'}
              </p>
            </div>
          </CardContent>
        </Card>
      ) : (
        <div className='space-y-3'>
          {data.notifications.map((notification) => (
            <NotificationCard
              key={notification.id}
              id={notification.id}
              title={notification.title}
              body={notification.message}
              status={notification.is_read ? 'read' : 'unread'}
              createdAt={notification.created_at}
              actions={getNotificationAction(notification.href)}
              onMarkAsRead={(id) => markRead.mutate(id)}
              onAction={(notificationId) => {
                const target = data.notifications.find((item) => item.id === notificationId);
                if (!target?.href) return;

                if (!target.is_read) {
                  markRead.mutate(notificationId, {
                    onSuccess: () => {
                      router.push(target.href!);
                    }
                  });
                  return;
                }

                router.push(target.href);
              }}
            />
          ))}
        </div>
      )}

      {totalPages > 1 ? (
        <Pagination>
          <PaginationContent>
            <PaginationItem>
              <PaginationPrevious
                href='#'
                onClick={(event) => {
                  event.preventDefault();
                  if (params.page > 1) {
                    void setParams({ page: params.page - 1 });
                  }
                }}
                aria-disabled={params.page <= 1}
                className={params.page <= 1 ? 'pointer-events-none opacity-50' : ''}
              />
            </PaginationItem>
            <PaginationItem>
              <span className='text-muted-foreground px-3 text-sm'>
                หน้า {params.page} / {totalPages}
              </span>
            </PaginationItem>
            <PaginationItem>
              <PaginationNext
                href='#'
                onClick={(event) => {
                  event.preventDefault();
                  if (params.page < totalPages) {
                    void setParams({ page: params.page + 1 });
                  }
                }}
                aria-disabled={params.page >= totalPages}
                className={params.page >= totalPages ? 'pointer-events-none opacity-50' : ''}
              />
            </PaginationItem>
          </PaginationContent>
        </Pagination>
      ) : null}
    </div>
  );
}
