
    Si                        d Z ddlmZ ddlZddlmZmZ ddlmZmZ ddl	m
Z
 ddlmZ dZd	Zd
ZdZedz  ez  edz  ez  z   ZdZdZe G d d             ZddZ G d d      Zy)uY  세션 인사이트 엔진.

task-timers.json 기반으로 작업 통계와 비용을 추정한다.
ASCII 가로 막대 차트, 기간별 필터, 팀/상태별 집계를 지원한다.

데이터 형식 (task-timers.json):
    {
      "tasks": {
        "task-1.0": {
          "task_id": "task-1.0",
          "team_id": "dev1-team",
          "description": "설명",
          "start_time": "2026-03-01T10:00:00",
          "end_time": "2026-03-01T10:30:00",
          "duration_seconds": 1800.0,
          "status": "completed",
          "duration_human": "30분"
        }
      }
    }

Usage:
    from utils.insights_engine import InsightsEngine
    engine = InsightsEngine("/home/jay/workspace/memory/task-timers.json")
    summary = engine.get_summary(days=30)
    chart = engine.render_ascii_chart(summary.tasks_by_team, title="팀별 태스크")
    )annotationsN)	dataclassfield)datetime	timedelta)Path)Anyi@  i'  g      @g      .@i@B u   █   c                  r    e Zd ZU dZded<   ded<   ded<   ded<    ee      Zd	ed
<    ee      Zd	ed<   y)InsightsSummaryu   작업 인사이트 요약.inttotal_taskscompleted_tasksfloatavg_duration_minutestotal_estimated_cost)default_factorydict[str, int]tasks_by_teamtasks_by_statusN)	__name__
__module____qualname____doc____annotations__r   dictr   r        F/home/jay/workspace/.worktrees/task-2117-dev1/utils/insights_engine.pyr   r   5   s;    %$)$$?M>?&+D&AO^Ar   r   c                ^    | sy	 t        j                  |       S # t        t        f$ r Y yw xY w)u.   ISO 형식 datetime 문자열을 파싱한다.N)r   fromisoformat
ValueError	TypeError)dt_strs    r   _parse_datetimer%   A   s5    %%f--	" s    ,,c                  <    e Zd ZdZddZd	dZd
dZdddZdddZy)InsightsEngineu   task-timers.json 기반 작업 인사이트 엔진.

    Args:
        data_path: task-timers.json 파일 경로 (str 또는 Path).
    c                $    t        |      | _        y N)r   _path)self	data_paths     r   __init__zInsightsEngine.__init__S   s    )_
r   c                   | j                   j                         sg S 	 t        | j                   d      5 }t        j                  |      }ddd       j                  di       }t        |t              rt        |j                               S g S # 1 sw Y   FxY w# t        t        j                  t        f$ r g cY S w xY w)uF   JSON에서 태스크 목록을 로드한다. 실패 시 빈 리스트.zutf-8)encodingNtasks)r*   existsopenjsonloadget
isinstancer   listvaluesOSErrorJSONDecodeErrorAttributeError)r+   fdata
tasks_dicts       r   _load_taskszInsightsEngine._load_tasksV   s    zz  "I	djj73 $qyy|$'2.J*d+J--/00I$ $ --~> 	I	s/   B BAB B BB  B?>B?c                    t        j                         t        |      z
  }g }|D ]G  }t        |j	                  d            }||j                  |       1||k\  s7|j                  |       I |S )u(   기간 내 태스크만 필터링한다.)days
start_time)r   nowr   r%   r5   append)r+   r0   rA   cutoffresulttaskstarts          r   _filter_by_dayszInsightsEngine._filter_by_daysd   sl    )"66') 	$D#DHH\$:;E}d#d#	$ r   c           	        | j                         }| j                  ||      }|st        ddddi i       S t        |      }t	        d |D              }|D cg c]0  }t        |j                  d      t        t        f      s)|d   dz  2 }}|rt	        |      t        |      z  nd}|t        z  }	i }
|D ]/  }|j                  d      xs d}|
j                  |d      d	z   |
|<   1 i }|D ]/  }|j                  d
      xs d}|j                  |d      d	z   ||<   1 t        ||t        |d      t        |	d      |
|      S c c}w )u   기간 내 작업 통계 요약을 반환한다.

        Args:
            days: 조회 기간 (일). 기본 30일.

        Returns:
            InsightsSummary 인스턴스.
        r   g        )r   r   r   r   r   r   c              3  J   K   | ]  }|j                  d       dk(  sd  yw)status	completed   N)r5   ).0ts     r   	<genexpr>z-InsightsEngine.get_summary.<locals>.<genexpr>   s     QA!%%/[2PaQs   ##duration_secondsg      N@team_idunknownrN   rL         )r?   rI   r   lensumr6   r5   r   r   _COST_PER_TASKround)r+   rA   	all_tasksr0   r   r   rP   	durationsavg_durationr   r   teamr   rL   s                 r   get_summaryzInsightsEngine.get_summaryr   s    $$&	$$Y5" !%(%(  "  %jQQQ <AxaJquuUgOhknpujvDwQ)*T1x	x:Cs9~I6  /? )+ 	AA55#0yD"/"3"3D!"<q"@M$	A
 +- 	IAUU8_1	F&5&9&9&!&Dq&HOF#	I #+!&|Q!7!&';Q!?'+
 	
% ys   *E
Ec           
        |sy|rt        |j                               nd}|dk  rd}g }|r7|j                  d|        |j                  ddt        |      dz   z  z          |rt        d |D              nd}|j	                         D ]\  \  }}|dkD  rt        dt        ||z  t        z              nd}t        |z  }	|j                  d|d	| dd|	d	t         dd|        ^ d
j                  |      S )u   가로 막대 ASCII 차트를 반환한다.

        Args:
            data: {레이블: 값} 딕셔너리.
            title: 차트 제목 (선택).

        Returns:
            ASCII 차트 문자열.
         rN   r   z  -rU   c              3  2   K   | ]  }t        |        y wr)   )rW   )rO   ks     r   rQ   z4InsightsEngine.render_ascii_chart.<locals>.<genexpr>   s     -1A-s   
   <
)	maxr8   rD   rW   itemsrZ   _BAR_MAX_WIDTH	_BAR_CHARjoin)
r+   r=   titlepeaklines	max_labellabelvalue	bar_widthbars
             r   render_ascii_chartz!InsightsEngine.render_ascii_chart   s	    %)s4;;=!q19DLL2eW&LLs5zA~ 667 26C---2	 JJL 	VLE5HMPQ	AuUT\N%BCDWXIi'CLL2eAi[ =1C.9I7I3J"UGTU	V
 yyr   N)r,   z
str | PathreturnNone)rv   list[dict[str, Any]])r0   rx   rA   r   rv   rx   )r
   )rA   r   rv   r   )ra   )r=   r   rm   strrv   ry   )	r   r   r   r   r-   r?   rI   r_   ru   r   r   r   r'   r'   L   s!    %3
j r   r'   )r$   z
str | Nonerv   zdatetime | None)r   
__future__r   r3   dataclassesr   r   r   r   pathlibr   typingr	   _AVG_INPUT_TOKENS_PER_TASK_AVG_OUTPUT_TOKENS_PER_TASK_INPUT_PRICE_PER_1M_OUTPUT_PRICE_PER_1MrY   rk   rj   r   r%   r'   r   r   r   <module>r      s   8 #  ( (  
 $ $   *-@@!I-0DDE 
 	 B B Bz  z r   