"use client";
import { useEffect, useRef, useState, useCallback, useMemo } from "react";
import { DateRangeEnum } from "@/app/constants/dateRange";
import { useSession, signIn } from "next-auth/react";

import CalenderSelector from "@/app/components/CalenderSelector";
import SvgChannelFilter from "@/app/components/svgs/svgChannelFilter";
import ChannelFilter from "@/app/components/ChannelFilter";

// App.tsx
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend,
} from "chart.js";
import { Line } from "react-chartjs-2";

// Chart.js 모듈 등록 (꼭 필요)
ChartJS.register(
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend
);

type ListChannelRawItem = {
  id: string;
  email?: string;
  handle: string;
  isApproved: boolean;
  createtime: string;
  icon?: string;
};

type ListChannelItem = {
  id: string;
  email?: string;
  handle: string;
  createtime: string;
  is_approved: boolean;
  icon?: string;
};

export default function Page({user}: {user: any}) {
  const [myChannelList, setMyChannelList] = useState<ListChannelItem[]>([]);
  const [visibleChannelIds, setVisibleChannelIds] = useState<Set<string>>(new Set());
  const [channelsReady, setChannelsReady] = useState<boolean>(false);

  const fetchListChannel = useCallback(async (options?: {
    cache?: RequestCache;
    signal?: AbortSignal;
  }): Promise<ListChannelItem[]> => {
    const response = await fetch('/api/channel/list', {
      cache: options?.cache ?? 'no-store',
      signal: options?.signal,
    });
    console.log('list_channel response:', response);

    if (!response.ok) {
      let message = '';
      try {
        message = await response.text();
      } catch {}
      throw new Error(`list_channel 요청 실패: ${response.status} ${message}`);
    }

    const data = (await response.json()) as { items: ListChannelRawItem[] } | unknown;
    const items = (data as { items: ListChannelRawItem[] })?.items ?? [];

    return items.map((item) => ({
      id: item.id,
      email: item.email,
      handle: item.handle,
      createtime: item.createtime,
      is_approved: item.isApproved,
      icon: item.icon,
    }));
  }, []);

  const [chanellist, setChanellist] = useState<string[]>([]);
  const [contentlist, setContentlist] = useState<{
    id: string;
    subject: string;
    pubDate: Date;
    views: number;
    validViews: number;
    premiumViews: number;
    watchTime: number;
    publisher?: string;
  }[]>([]);
  const [selectedChannels, setSelectedChannels] = useState<string[]>(chanellist);
  const [loading, setLoading] = useState<boolean>(false);
  const [dateRange, setDateRange] = useState<{
    startDate: Date;
    endDate: Date;
  }>({
    startDate: new Date(),
    endDate: new Date()
  });

  const [dateString, setDateString] = useState<string>("2025.03.01 ~ 2025.03.31");
  const chartRef = useRef<HTMLDivElement>(null);
  const [hasRun, setHasRun] = useState(false);
  const [calendarOpen, setCalendarOpen] = useState(false);
  const [filterOpen, setFilterOpen] = useState(false);

  // 전역 상수는 공용 파일에서 import

  const [globalDateRangeType, setGlobalDateRangeType] = useState<number>(DateRangeEnum.ALL);
  const [dateRangeBlock1, setDateRangeBlock1] = useState<number>(DateRangeEnum.ALL);
  const [dateRangeBlock2, setDateRangeBlock2] = useState<number>(DateRangeEnum.ALL);
  const [dateRangeBlock3, setDateRangeBlock3] = useState<number>(DateRangeEnum.ALL);
  const [dateRangeBlock4, setDateRangeBlock4] = useState<number>(DateRangeEnum.ALL);
  const [dateRangeGraph, setDateRangeGraph] = useState<number>(DateRangeEnum.ALL);

  const [startDate, setStartDate] = useState<Date>(new Date(Date.now()-30*24*60*60*1000));
  const [endDate, setEndDate] = useState<Date>(new Date());
  const [cpv, setCpv] = useState<number>(0);
  const [rows, setRows] = useState<Array<{
    id: string;
    subject: string;
    pubDate: string;
    views: number;
    premiumViews: number;
    watchTime: number;
    handle: string;
    handleId: string | null;
    icon: string;
    validViews: number;
    expectedRevenue: number;
  }>>([]);
  const [checkedIds, setCheckedIds] = useState<Set<string>>(new Set());
  const [sortKey, setSortKey] = useState<'handle'|'subject'|'pubDate'|'watchTime'|'views'|'premiumViews'|'validViews'|'expectedRevenue'>('pubDate');
  const [sortDir, setSortDir] = useState<'asc'|'desc'>('desc');
  const handleSort = useCallback((key: 'handle'|'subject'|'pubDate'|'watchTime'|'views'|'premiumViews'|'validViews'|'expectedRevenue') => {
    setSortDir(prev => (sortKey === key ? (prev === 'asc' ? 'desc' : 'asc') : 'desc'));
    setSortKey(key);
  }, [sortKey]);

  // 그래프에 표시할 선택 지표
  const [selectedMetric, setSelectedMetric] = useState<'views'|'validViews'|'premiumViews'|'expectedRevenue'>('validViews')

  const fetchMyContents = useCallback(async (s: Date, e: Date) => {
    const qs = `start=${encodeURIComponent(s.toISOString())}&end=${encodeURIComponent(e.toISOString())}`;
    const res = await fetch(`/api/contents/mycontent?${qs}`, { cache: 'no-store' });
    const data = await res.json();

    if (!res.ok) throw new Error(data?.error ?? 'LOAD_FAILED');
    const items = data.items ?? [];
    setCpv(data.cpv ?? 0);
    console.log(items)
    setRows(items);
    // 초기 로드 시 전체 선택
    setCheckedIds(new Set(items.map((it: any) => it.id)));
  }, []);



  const data = {
    labels: ["Jan", "Feb", "Mar", "Apr", "May"],
    datasets: [
      {
        label: "",
        data: [120000, 150000, 200000, 190000, 230000],
        borderColor: "#F94B37", // 새로운 색상 적용
        backgroundColor: "rgba(249, 75, 55, 0.5)", // 배경색도 변경
      },
    ],
  };

  const options = {
    responsive: true,
    plugins: {
      legend: { display: false },
      title: { display: false, text: "정산 수익 추이" },
    },

    scales: {
      x: {
        grid: {
          display: false,
        },
      },
      y: {
        grid: {
          display: true,
        },
        ticks: {
          stepSize: 20000,
        },
      },
    },
    elements: {
      line: {
        tension: 0.4, // 곡선으로 변경
      },
    },
  };

  useEffect(() => {
    if (!hasRun) {
      if (chartRef.current) {
        setHasRun(true);
        chartRef.current.style.width = '10px';
        setTimeout(() => {
          chartRef.current!.style.width = '100%';
        }, 100);
      }
    }
  }, [hasRun, chartRef.current]);

  const handleCheckboxChange = (channel: string) => {
    setSelectedChannels(prev =>
      prev.includes(channel)
        ? prev.filter(c => c !== channel)
        : [...prev, channel]
    );
  };

  const filteredContentList = contentlist.filter(content =>
    selectedChannels.length === 0 || (content.publisher && selectedChannels.includes(content.publisher))
  );

  const formatNumberWithCommas = (number: number): string => {
    return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  };

  useEffect(() => {
    const handleResize = () => {
      window.resizeTo(500, 500);
      setTimeout(() => {
        window.resizeTo(window.screen.availWidth, window.screen.availHeight);
      }, 1000);
    };
    
    handleResize();
    
  }, []);

  // 내 채널 목록: 최초 1회만 호출
  useEffect(() => {
    (async () => {
      try {
        const items = await fetchListChannel({ cache: 'no-store' });
        console.log('list_channel:', items);
        setMyChannelList(items);
        // 초기에는 전체 채널 가시
        setVisibleChannelIds(new Set(items.map(i => i.id)));
        setChannelsReady(true);
      } catch (e) {
        console.error('list_channel 요청 에러:', e);
      }
    })();
  }, [fetchListChannel]);


  if (loading) {
    return <div className="spinner">Loading...</div>;
  }

  // 빈 집합은 "아무 채널도 선택되지 않음"으로 간주하여 행을 숨깁니다
  const visibleRows = rows.filter(r => visibleChannelIds.size > 0 && r.handleId && visibleChannelIds.has(r.handleId));
  console.log(visibleRows)
  const sortedVisibleRows = useMemo(() => {
    const copy = [...visibleRows];
    const factor = sortDir === 'asc' ? 1 : -1;
    copy.sort((a,b) => {
      let va: any, vb: any;
      switch (sortKey) {
        case 'pubDate': va = new Date(a.pubDate).getTime(); vb = new Date(b.pubDate).getTime(); break;
        case 'watchTime': va = a.watchTime; vb = b.watchTime; break;
        case 'views': va = a.views; vb = b.views; break;
        case 'premiumViews': va = a.premiumViews; vb = b.premiumViews; break;
        case 'validViews': va = a.validViews; vb = b.validViews; break;
        case 'expectedRevenue': va = a.expectedRevenue; vb = b.expectedRevenue; break;
        case 'handle': va = a.handle; vb = b.handle; break;
        case 'subject': va = a.subject; vb = b.subject; break;
        default: va = 0; vb = 0;
      }
      if (typeof va === 'string' && typeof vb === 'string') return va.localeCompare(vb) * factor;
      return ((va as number) - (vb as number)) * factor;
    });
    return copy;
  }, [visibleRows, sortKey, sortDir]);
  const allVisibleChecked = visibleRows.length > 0 && visibleRows.every(r => checkedIds.has(r.id));
  const totals = useMemo(() => {
    let views = 0, premium = 0, valid = 0, revenue = 0;
    for (const r of sortedVisibleRows) {
      if (checkedIds.has(r.id)) {
        views += r.views;
        premium += r.premiumViews;
        valid += r.validViews;
        revenue += r.expectedRevenue;
      }
    }
    return { views, premium, valid, revenue: Math.round(revenue) };
  }, [sortedVisibleRows, checkedIds]);

  // 그래프 데이터/옵션
  const metricLabel: Record<'views'|'validViews'|'premiumViews'|'expectedRevenue', string> = {
    views: '총 조회수',
    validViews: '유효 조회수',
    premiumViews: '프리미엄 조회수',
    expectedRevenue: '예상 수익',
  }
  const metricColor: Record<'views'|'validViews'|'premiumViews'|'expectedRevenue', { border: string, bg: string }> = {
    views: { border: '#1f6feb', bg: 'rgba(31, 111, 235, 0.25)' },
    validViews: { border: '#F94B37', bg: 'rgba(249, 75, 55, 0.25)' },
    premiumViews: { border: '#7C3AED', bg: 'rgba(124, 58, 237, 0.25)' },
    expectedRevenue: { border: '#16A34A', bg: 'rgba(22, 163, 74, 0.25)' },
  }
  const selectedRows = useMemo(() => sortedVisibleRows.filter(r => checkedIds.has(r.id)), [sortedVisibleRows, checkedIds])
  const selectedIdsKey = useMemo(() => {
    const ids = Array.from(checkedIds)
    if (ids.length === 0) return ''
    ids.sort()
    return ids.join(',')
  }, [checkedIds])
  const [seriesMode, setSeriesMode] = useState<'items'|'series'>('series')
  const [seriesInterval, setSeriesInterval] = useState<'day'|'week'|'month'>('day')
  const [seriesItems, setSeriesItems] = useState<Array<{ period: string, views: number, validViews: number, premiumViews: number, expectedRevenue: number }>>([])
  const [seriesLoading, setSeriesLoading] = useState<boolean>(false)
  const chartData = useMemo(() => {
    const col = metricColor[selectedMetric]
    if (seriesMode === 'series') {
      const labels = seriesItems.map(it => it.period)
      const dataVals = seriesItems.map(it => (it as any)[selectedMetric] as number)
      return { labels, datasets: [{ label: `${metricLabel[selectedMetric]} (${seriesInterval})`, data: dataVals, borderColor: col.border, backgroundColor: col.bg, tension: 0.35 }] }
    }
    const labels = selectedRows.map(r => r.subject)
    const dataVals = selectedRows.map(r => (r as any)[selectedMetric] as number)
    return { labels, datasets: [{ label: metricLabel[selectedMetric], data: dataVals, borderColor: col.border, backgroundColor: col.bg, tension: 0.35 }] }
  }, [selectedRows, selectedMetric, seriesMode, seriesItems, seriesInterval])
  const chartOptions = useMemo(() => ({
    responsive: true,
    plugins: { legend: { display: false }, title: { display: false } },
    scales: { x: { grid: { display: false } }, y: { grid: { display: true } } },
    elements: { line: { tension: 0.35 } },
  }), [])

  // 시리즈 모드일 때 옵션/기간 변경 시 자동 데이터 로드
  useEffect(() => {
    if (seriesMode !== 'series') return;
    const s = startDate; const e = endDate;
    const qs = new URLSearchParams();
    qs.set('start', s.toISOString());
    qs.set('end', e.toISOString());
    qs.set('mode', 'series');
    qs.set('interval', seriesInterval);
    if (selectedIdsKey) qs.set('contentIds', selectedIdsKey);
    let cancelled = false;
    setSeriesLoading(true);
    (async () => {
      try {
        const res = await fetch(`/api/contents/mycontent?${qs.toString()}`, { cache: 'no-store' });
        const data = await res.json();
        if (res.ok && !cancelled) setSeriesItems(data.items || []);
      } catch (e) {
        if (!cancelled) console.error(e);
      } finally {
        if (!cancelled) setSeriesLoading(false);
      }
    })();
    return () => { cancelled = true; };
  }, [seriesMode, seriesInterval, startDate, endDate, selectedIdsKey]);

  // 시리즈 모드 해제 시 스피너 숨김 보장
  useEffect(() => {
    if (seriesMode !== 'series') setSeriesLoading(false);
  }, [seriesMode]);

  // 채널 필터가 변경되면, 보이지 않는 콘텐츠는 선택 해제하되
  // 초기 로딩 등으로 가시 채널이 비어있을 땐 해제하지 않음.
  // 가시 채널이 채워지고 선택이 비어있으면 전체 선택으로 초기화.
  useEffect(() => {
    if (visibleChannelIds.size === 0) return;
    const visibleIdSet = new Set(visibleRows.map(r => r.id));
    setCheckedIds(prev => {
      if (prev.size === 0) return visibleIdSet; // 기본 전체 선택
      const next = new Set(Array.from(prev).filter(id => visibleIdSet.has(id)));
      return next;
    });
  }, [visibleChannelIds, rows]);


  return (
    <div className="
    grid
    grid-cols-[1fr_1fr_1fr_1fr]
    grid-rows-[36px_minmax(300px,auto)_135px_135px_135px_135px]
    sm:grid-rows-[36px_minmax(400px,600px)_minmax(200px,250px)_minmax(200px,250px)]
    gap-2
    w-full
    h-full
    lg:gap-5
    py-2
    ">
      <div className="order-1 col-[1/5] row-[1/2] flex flex-row">
        <div className="grow h-[48px] flex flex-row items-center overflow-y-hidden overflow-x-auto mx-1 scrollbar-thin-x scrollbar-outside-x" style={{ scrollbarGutter: 'stable both-edges' }}>
          {myChannelList.length === 0 ? (
            <div className=" h-[32px] border-1 border-border-pale rounded-xl flex items-center justify-center bg-white mx-1 px-2 min-w-[fit-content] font-semibold text-[#848484]">
              등록된 채널이 없습니다.
            </div>
          ) : visibleChannelIds.size === 0 ? (
            <div className=" h-[32px] border-1 border-border-pale rounded-xl flex items-center justify-center bg-white mx-1 px-2 min-w-[fit-content] font-semibold text-[#F94B37]">
              선택된 채널이 없습니다. 오른쪽 필터에서 채널을 선택하세요.
            </div>
          ) : (
            myChannelList.filter(c => visibleChannelIds.has(c.id)).map((channel, index) => (
              <div key={index} className=" h-[30px] border-1 border-border-pale rounded-xl flex items-center justify-center bg-white mx-1 px-2 min-w-[fit-content] font-semibold">
                <div className="w-[24px] h-[24px] rounded-full border-1 border-[#e6e9ef] overflow-hidden mr-2">
                  {channel.icon ? (
                    <img src={channel.icon} alt="channel icon" className="w-[24px] h-[24px] rounded-full" />
                  ) : (
                    <div className="w-[24px]  h-[24px] bg-[#e6e9ef] rounded-full border-1 border-[#848484]" />
                  )}
                </div>
                <span className="text-sm font-semibold">{channel.handle}</span>
              </div>
            ))
          )}

        </div>
        <div className='flex flex-row items-center'>
          <CalenderSelector 
            dateString={dateString} 
            is_ri={true} 
            is_small={false}
            isOpen={calendarOpen}
            onOpenChange={(open)=>{ setCalendarOpen(open); if (open) setFilterOpen(false); }}
            onRangeChange={(s,e)=>{ 
              setStartDate(s); setEndDate(e);
              setDateString(`${s.toISOString().slice(0,10)} ~ ${e.toISOString().slice(0,10)}`);
              fetchMyContents(s,e).catch(console.error);
            }} 
          />
          <div className="w-2"> </div>
          <ChannelFilter
            channel_list={myChannelList}
            visibleSet={visibleChannelIds}
            onChangeVisible={(next) => setVisibleChannelIds(new Set(next))}
            isOpen={filterOpen}
            onOpenChange={(open)=>{ setFilterOpen(open); if (open) setCalendarOpen(false); }}
          />
          <div className="w-2"> </div>
        </div>
      </div>

      <div className="
      border-1 border-[#e6e9ef] rounded-lg  bg-white col-[1/5] row-[2/3] 
      min-h-[300px]
      overflow-auto
      ">
        <table className="w-full h-full border-separate border-spacing-y-1 table-auto px-[10px]">
          <colgroup>
            <col className="w-[56px]" />
            <col className="min-w-[160px] max-w-[180px]" />
            <col className="min-w-[140px] w-[160px]" />
            <col className="min-w-[280px]" />
            <col className="min-w-[120px] w-[120px]" />
            <col className="min-w-[120px] w-[120px]" />
            <col className="min-w-[160px] w-[160px]" />
            <col className="min-w-[140px] w-[140px]" />
            <col className="w-[300px]" />
          </colgroup>
          <thead>
            <tr className="sticky top-0 bg-white h-[49px] z-1">
              <th className="border-b-1 border-[#e6e9ef] pl-2 whitespace-nowrap">
                <input 
                  type="checkbox" 
                  className="w-[18px] h-[18px]"
                  checked={allVisibleChecked}
                  onChange={() => {
                    const next = new Set(checkedIds);
                    if (allVisibleChecked) {
                      visibleRows.forEach(r => next.delete(r.id));
                    } else {
                      visibleRows.forEach(r => next.add(r.id));
                    }
                    setCheckedIds(next);
                  }}
                />
              </th>
              <th className="border-b-1 right-border border-[#e6e9ef] whitespace-nowrap cursor-pointer select-none" onClick={()=> handleSort('handle')}>핸들
                <span className={`ml-1 inline-block w-3 text-[10px] ${sortKey==='handle' ? 'opacity-100' : 'opacity-0'}`}>{sortDir==='asc'?'▲':'▼'}</span>
              </th>
              <th className="border-b-1 right-border border-[#e6e9ef] whitespace-nowrap cursor-pointer select-none" onClick={()=> handleSort('pubDate')}>게시일
                <span className={`ml-1 inline-block w-3 text-[10px] ${sortKey==='pubDate' ? 'opacity-100' : 'opacity-0'}`}>{sortDir==='asc'?'▲':'▼'}</span>
              </th>
              <th className="border-b-1 right-border border-[#e6e9ef] whitespace-nowrap cursor-pointer select-none" onClick={()=> handleSort('subject')}>영상 제목
                <span className={`ml-1 inline-block w-3 text-[10px] ${sortKey==='subject' ? 'opacity-100' : 'opacity-0'}`}>{sortDir==='asc'?'▲':'▼'}</span>
              </th>
              <th className="border-b-1 right-border border-[#e6e9ef] whitespace-nowrap cursor-pointer select-none" onClick={()=> handleSort('watchTime')}>시청시간
                <span className={`ml-1 inline-block w-3 text-[10px] ${sortKey==='watchTime' ? 'opacity-100' : 'opacity-0'}`}>{sortDir==='asc'?'▲':'▼'}</span>
              </th>
              <th className="border-b-1 right-border border-[#e6e9ef] whitespace-nowrap cursor-pointer select-none" onClick={()=> handleSort('views')}>조회수
                <span className={`ml-1 inline-block w-3 text-[10px] ${sortKey==='views' ? 'opacity-100' : 'opacity-0'}`}>{sortDir==='asc'?'▲':'▼'}</span>
              </th>
              <th className="border-b-1 right-border border-[#e6e9ef] whitespace-nowrap cursor-pointer select-none" onClick={()=> handleSort('premiumViews')}>premium 조회수
                <span className={`ml-1 inline-block w-3 text-[10px] ${sortKey==='premiumViews' ? 'opacity-100' : 'opacity-0'}`}>{sortDir==='asc'?'▲':'▼'}</span>
              </th>
              <th className="border-b-1 right-border border-[#e6e9ef] whitespace-nowrap cursor-pointer select-none " onClick={()=> handleSort('validViews')}>유효 조회수
                <span className={`ml-1 inline-block w-3 text-[10px] ${sortKey==='validViews' ? 'opacity-100' : 'opacity-0'}`}>{sortDir==='asc'?'▲':'▼'}</span>
              </th>
              <th className="border-b-1 border-[#e6e9ef] whitespace-nowrap min-w-[180px] cursor-pointer select-none " onClick={()=> handleSort('expectedRevenue')}>예상수익
                <span className={`ml-1 inline-block w-3 text-[10px] ${sortKey==='expectedRevenue' ? 'opacity-100' : 'opacity-0'}`}>{sortDir==='asc'?'▲':'▼'}</span>
              </th>
            </tr>
          </thead>
          <tbody>
            {visibleChannelIds.size === 0 && (
              <tr>
                <td colSpan={8} className="text-center py-6 text-[#848484]">선택된 채널이 없습니다. 채널 필터에서 채널을 선택하세요.</td>
              </tr>
            )}
            {visibleChannelIds.size > 0 && visibleRows.length === 0 && (
              <tr>
                <td colSpan={8} className="text-center py-6 text-[#848484]">표시할 데이터가 없습니다.</td>
              </tr>
            )}
            {sortedVisibleRows.map((r) => (
              <tr key={r.id} className="h-[54px] border-1 border-[#e6e9ef] rounded-lg font-semibold">
                <td className="justify-center items-center rounded-l-lg border-l-1 border-t-1 border-b-1 border-[#e6e9ef] pl-2">
                  <input type="checkbox" className="w-[18px] h-[18px]" 
                    checked={checkedIds.has(r.id)}
                    onChange={(e)=>{
                      const next = new Set(checkedIds);
                      if (e.target.checked) next.add(r.id); else next.delete(r.id);
                      setCheckedIds(next);
                    }}
                  />
                </td>
                <td className="right-border border-b-1 border-t-1 border-[#e6e9ef] text-left whitespace-nowrap overflow-hidden pl-3">
                  <div className="flex items-center justify-start">
                    {r.icon && <img src={r.icon} alt="icon" className="w-6 h-6 mr-2 rounded-full" />}
                    {r.handle}
                  </div>
                </td>
                <td className="right-border border-b-1 border-t-1  border-[#e6e9ef] text-center whitespace-nowrap overflow-hidden">{new Date(r.pubDate).toISOString().slice(0,10)}</td>
                <td className="right-border border-b-1 border-t-1  border-[#e6e9ef] text-center whitespace-nowrap overflow-hidden">
                  <a
                    href={`https://www.youtube.com/watch?v=${encodeURIComponent(r.id)}`}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="text-[#1f6feb] hover:underline"
                    title={r.subject}
                  >
                    {r.subject}
                  </a>
                </td>
                <td className="right-border border-b-1 border-t-1 border-[#e6e9ef] text-center">{formatNumberWithCommas(r.watchTime)}</td>
                <td className="right-border border-b-1 border-t-1 border-[#e6e9ef] text-center">{formatNumberWithCommas(r.views)}</td>
                <td className="right-border border-b-1 border-t-1 border-[#e6e9ef] text-center">{formatNumberWithCommas(r.premiumViews)}</td>
                <td className="right-border border-b-1 border-t-1 border-[#e6e9ef] text-center ">{formatNumberWithCommas(r.validViews)}</td>
                <td className=" border-[#e6e9ef] text-center border-r-1 border-b-1 border-t-1 rounded-r-lg whitespace-nowrap px-2 ">
                  <span className="inline-block min-w-[180px] text-center">{formatNumberWithCommas(Math.round(r.expectedRevenue))}</span>
                </td>
              </tr>
            ))}
            {sortedVisibleRows.length === 1 && (
              <tr>
                <td colSpan={9} className="p-0">
                  <div style={{ height: 'calc(100% - 49px - 54px)' }} />
                </td>
              </tr>
            )}
          </tbody>
        </table>
      </div>

      <div className={`border-1 col-[1/5] sm:col-[1/3] sm:row-[3/4] xl:col-[1/2] xl:row-[3/4] bg-white rounded-lg flex flex-col justify-around items-start p-3 cursor-pointer`}
        style={{ borderColor: selectedMetric==='views' ? metricColor.views.border : '#e6e9ef' }}
        onClick={() => setSelectedMetric('views')}
      >
        <div>
          <div className="text-xl font-bold mb-2">총 조회수</div>
          {/* <div className=""> <CalenderSelector dateString={dateString} is_ri={false} is_small={true} /> </div> */}
        </div>
        <div>
          <div className="text-3xl font-bold"> {formatNumberWithCommas(totals.views)} <span className="text-sm text-[#848484]"> 회</span></div>
          {/* <div className="text-xs font-normal text-[#F94B37]"> + 0.24%</div> */}
        </div>
      </div>

      <div className={`border-1 col-[1/5] sm:col-[3/5] sm:row-[3/4] xl:col-[2/3] xl:row-[3/4] bg-white rounded-lg flex flex-col justify-around items-start  p-3 cursor-pointer`}
        style={{ borderColor: selectedMetric==='premiumViews' ? metricColor.premiumViews.border : '#e6e9ef' }}
        onClick={() => setSelectedMetric('premiumViews')}
      >

        <div>
          <div className="text-xl font-bold mb-2"> 프리미엄 조회수</div>
          {/* <div className=""> <CalenderSelector dateString={dateString} is_ri={false} is_small={true} /> </div> */}
        </div>
        <div>
          <div className="text-3xl font-bold"> {formatNumberWithCommas(totals.premium)} <span className="text-sm text-[#848484]"> 회</span></div>
          {/* <div className="text-xs font-normal text-[#F94B37]"> + 0.24%</div> */}
        </div>
      </div>
      <div className={`border-1 col-[1/5] sm:col-[1/3] sm:row-[4/5] xl:col-[1/2] xl:row-[4/5] bg-white rounded-lg flex flex-col justify-around items-start p-3 cursor-pointer`}
        style={{ borderColor: selectedMetric==='validViews' ? metricColor.validViews.border : '#e6e9ef' }}
        onClick={() => setSelectedMetric('validViews')}
      >
        <div>
          <div className="text-xl font-bold mb-2"> 유효 조회수</div>
          {/* <div className=""> <CalenderSelector dateString={dateString} is_ri={false} is_small={true} /> </div> */}
        </div>

        <div>
          <div className="text-3xl font-bold"> {formatNumberWithCommas(totals.valid)} <span className="text-sm text-[#848484]"> 회</span></div>
          {/* <div className="text-xs font-normal text-[#F94B37]"> + 0.24%</div> */}
        </div>
      </div>
      <div className={`border-1 col-[1/5] sm:col-[3/5] sm:row-[4/5] xl:col-[2/3] xl:row-[4/5] bg-white rounded-lg flex flex-col justify-around items-start p-3 cursor-pointer`}
        style={{ borderColor: selectedMetric==='expectedRevenue' ? metricColor.expectedRevenue.border : '#e6e9ef' }}
        onClick={() => setSelectedMetric('expectedRevenue')}
      >

        <div>
          <div className="text-xl font-bold mb-2"> 예상 수익 </div>
          {/* <div className=""> <CalenderSelector dateString={dateString} is_ri={false} is_small={true} /> </div> */}
        </div>
        <div>
          <div className="text-3xl font-bold"> {formatNumberWithCommas(totals.revenue)} <span className="text-sm text-[#848484]"> 원</span></div>
          {/* <div className="text-xs font-normal text-[#0000FF]"> - 1.24%</div> */}
        </div>
      </div>
      <div className="border-1 hidden  xl:col-[3/5] xl:row-[3/5] bg-white rounded-lg p-4 xl:flex xl:flex-col" style={{ borderColor: metricColor[selectedMetric].border }}>
        <div className="text-xl font-bold"> {metricLabel[selectedMetric]} 추이 </div>
        <div className="text-normal text-gray-500 flex flex-row gap-2 items-center">
          <select className="border-1 border-[#e6e9ef] rounded px-2 py-1" value={seriesMode} onChange={e => setSeriesMode(e.target.value as any)}>
            <option value="items">항목별</option>
            <option value="series">기간별</option>
          </select>
          {seriesMode === 'series' && (
            <select className="border-1 border-[#e6e9ef] rounded px-2 py-1" value={seriesInterval} onChange={e => setSeriesInterval(e.target.value as any)}>
              <option value="day">일</option>
              <option value="week">주</option>
              <option value="month">월</option>
            </select>
          )}
        </div>
        <div className="flex flex-row justify-start items-center"> 
          <div className="font-bold text-3xl my-4"> {formatNumberWithCommas(
            selectedMetric === 'views' ? totals.views :
            selectedMetric === 'validViews' ? totals.valid :
            selectedMetric === 'premiumViews' ? totals.premium : totals.revenue
          )} </div>
          {/* <div className=" p-2 pt-5 text-sm font-normal text-[#F94B37]"> + 0.24%</div> */}
        </div>
        <div className="w-full flex-1 items-center justify-center flex" ref={chartRef}>
          {seriesMode === 'series' && seriesLoading ? (
            <div className="flex items-center justify-center w-full h-full">
              <div className="animate-spin rounded-full h-8 w-8 border-4 border-[#e6e9ef]" style={{ borderTopColor: metricColor[selectedMetric].border }} />
            </div>
          ) : (
            <Line data={chartData} options={chartOptions} />
          )}
        </div>
      </div>
    </div>
  );
}