'use client';

/**
 * 공지사항 목록 컴포넌트
 *
 * 디자인 스펙:
 * - 페이지 타이틀: 공지사항
 * - 페이지 설명: 공지사항을 확인합니다.
 * - 날짜 범위 선택 + 기간 프리셋 버튼
 * - 검색 + 정렬 (최신순)
 * - 테이블 컬럼: No, 제목, 작성자, 등록일, 조회수
 */

import { useState, useMemo, useCallback } from 'react';
import { useRouter } from 'next/navigation';
import { Bell } from 'lucide-react';
import { format } from 'date-fns';
import { TableCell, TableRow } from '@/components/ui/table';
import { Card, CardContent } from '@/components/ui/card';
import { Checkbox } from '@/components/ui/checkbox';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import {
  IntegratedListTemplateV2,
  type TableColumn,
  type PaginationConfig,
} from '@/components/templates/IntegratedListTemplateV2';
import { DateRangeSelector } from '@/components/molecules/DateRangeSelector';
import { type Notice, type SortOption, SORT_OPTIONS, MOCK_NOTICES } from './types';

const ITEMS_PER_PAGE = 10;

export function NoticeList() {
  const router = useRouter();

  // ===== 상태 관리 =====
  const [notices] = useState<Notice[]>(MOCK_NOTICES);
  const [searchValue, setSearchValue] = useState('');
  const [selectedItems, setSelectedItems] = useState<Set<string>>(new Set());
  const [currentPage, setCurrentPage] = useState(1);
  const [sortOption, setSortOption] = useState<SortOption>('latest');

  // 날짜 범위
  const [startDate, setStartDate] = useState(format(new Date(), 'yyyy-MM-dd'));
  const [endDate, setEndDate] = useState(format(new Date(), 'yyyy-MM-dd'));

  // ===== 필터링 및 정렬된 데이터 =====
  const filteredData = useMemo(() => {
    let result = [...notices];

    // 날짜 필터
    if (startDate && endDate) {
      result = result.filter((item) => {
        const itemDate = item.createdAt;
        return itemDate >= startDate && itemDate <= endDate;
      });
    }

    // 검색 필터
    if (searchValue) {
      const searchLower = searchValue.toLowerCase();
      result = result.filter(
        (item) =>
          item.title.toLowerCase().includes(searchLower) ||
          item.author.toLowerCase().includes(searchLower)
      );
    }

    // 정렬
    switch (sortOption) {
      case 'latest':
        result.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
        break;
      case 'oldest':
        result.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
        break;
      case 'views':
        result.sort((a, b) => b.viewCount - a.viewCount);
        break;
    }

    return result;
  }, [notices, searchValue, startDate, endDate, sortOption]);

  // ===== 페이지네이션 =====
  const paginatedData = useMemo(() => {
    const startIndex = (currentPage - 1) * ITEMS_PER_PAGE;
    return filteredData.slice(startIndex, startIndex + ITEMS_PER_PAGE);
  }, [filteredData, currentPage]);

  const totalPages = Math.ceil(filteredData.length / ITEMS_PER_PAGE);

  // ===== 핸들러 =====
  const handleToggleSelection = useCallback((id: string) => {
    setSelectedItems((prev) => {
      const newSet = new Set(prev);
      if (newSet.has(id)) {
        newSet.delete(id);
      } else {
        newSet.add(id);
      }
      return newSet;
    });
  }, []);

  const handleToggleSelectAll = useCallback(() => {
    if (selectedItems.size === paginatedData.length) {
      setSelectedItems(new Set());
    } else {
      setSelectedItems(new Set(paginatedData.map((item) => item.id)));
    }
  }, [selectedItems.size, paginatedData]);

  const handleRowClick = useCallback(
    (item: Notice) => {
      router.push(`/ko/customer-center/notices/${item.id}`);
    },
    [router]
  );

  // ===== 테이블 컬럼 =====
  const tableColumns: TableColumn[] = [
    { key: 'no', label: 'No.', className: 'w-[60px] text-center' },
    { key: 'title', label: '제목', className: 'min-w-[200px]' },
    { key: 'author', label: '작성자', className: 'w-[100px] text-center' },
    { key: 'createdAt', label: '등록일', className: 'w-[120px] text-center' },
    { key: 'viewCount', label: '조회수', className: 'w-[80px] text-center' },
  ];

  // ===== 테이블 행 렌더링 =====
  const renderTableRow = useCallback(
    (item: Notice, index: number, globalIndex: number) => {
      const isSelected = selectedItems.has(item.id);

      return (
        <TableRow
          key={item.id}
          className="hover:bg-muted/50 cursor-pointer"
          onClick={() => handleRowClick(item)}
        >
          <TableCell className="text-center" onClick={(e) => e.stopPropagation()}>
            <Checkbox
              checked={isSelected}
              onCheckedChange={() => handleToggleSelection(item.id)}
            />
          </TableCell>
          <TableCell className="text-center">{globalIndex}</TableCell>
          <TableCell>{item.title}</TableCell>
          <TableCell className="text-center">{item.author}</TableCell>
          <TableCell className="text-center">{item.createdAt}</TableCell>
          <TableCell className="text-center">{item.viewCount}</TableCell>
        </TableRow>
      );
    },
    [selectedItems, handleRowClick, handleToggleSelection]
  );

  // ===== 모바일 카드 렌더링 =====
  const renderMobileCard = useCallback(
    (
      item: Notice,
      index: number,
      globalIndex: number,
      isSelected: boolean,
      onToggle: () => void
    ) => {
      return (
        <Card
          className="cursor-pointer hover:bg-muted/50"
          onClick={() => handleRowClick(item)}
        >
          <CardContent className="p-4">
            <div className="flex items-start gap-3">
              <div onClick={(e) => e.stopPropagation()}>
                <Checkbox checked={isSelected} onCheckedChange={onToggle} />
              </div>
              <div className="flex-1 space-y-2">
                <div className="flex items-center justify-between">
                  <span className="text-sm text-muted-foreground">#{globalIndex}</span>
                  <span className="text-sm text-muted-foreground">조회 {item.viewCount}</span>
                </div>
                <h3 className="font-medium">{item.title}</h3>
                <div className="flex flex-wrap gap-2 text-sm text-muted-foreground">
                  <span>{item.author}</span>
                  <span>|</span>
                  <span>{item.createdAt}</span>
                </div>
              </div>
            </div>
          </CardContent>
        </Card>
      );
    },
    [handleRowClick]
  );

  // ===== 페이지네이션 설정 =====
  const pagination: PaginationConfig = {
    currentPage,
    totalPages,
    totalItems: filteredData.length,
    itemsPerPage: ITEMS_PER_PAGE,
    onPageChange: setCurrentPage,
  };

  return (
    <IntegratedListTemplateV2
      title="공지사항"
      description="공지사항을 확인합니다."
      icon={Bell}
      headerActions={
        <DateRangeSelector
          startDate={startDate}
          endDate={endDate}
          onStartDateChange={setStartDate}
          onEndDateChange={setEndDate}
        />
      }
      searchValue={searchValue}
      onSearchChange={setSearchValue}
      searchPlaceholder="제목, 작성자로 검색..."
      tableHeaderActions={
        <div className="flex items-center gap-2">
          <span className="text-sm text-muted-foreground">
            총 {filteredData.length}건
          </span>
          <Select value={sortOption} onValueChange={(v) => setSortOption(v as SortOption)}>
            <SelectTrigger className="w-[120px]">
              <SelectValue placeholder="정렬" />
            </SelectTrigger>
            <SelectContent>
              {SORT_OPTIONS.map((option) => (
                <SelectItem key={option.value} value={option.value}>
                  {option.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
      }
      tableColumns={tableColumns}
      data={paginatedData}
      allData={filteredData}
      selectedItems={selectedItems}
      onToggleSelection={handleToggleSelection}
      onToggleSelectAll={handleToggleSelectAll}
      getItemId={(item) => item.id}
      renderTableRow={renderTableRow}
      renderMobileCard={renderMobileCard}
      pagination={pagination}
    />
  );
}

export default NoticeList;