o
    	iX                     @   s   d Z ddlmZ ddlmZmZmZmZmZ ddl	m
Z
 ddlmZmZ ddlmZ ddefd	d
ZddededefddZdd ZdededededededefddZdS )u[   
학습계획표 엑셀 파일 생성
BASE 엑셀 템플릿 생성 및 데이터 채우기
    )Workbook)Font	AlignmentPatternFillBorderSideget_column_letter)PageMarginsPrintPageSetup)PathNoutput_pathc              
   C   sn  | du rt t jjj}|d d } t | jjddd t }|j}d|_tdddd	d
}tdddd	d
}tddd}t	dddd}t	dddd}t	dddd}	t	dddd}
t
tddtddtddtddd}|d d|d< ||d _||d _tddd|d _d|jd _d|d< ||d _||d _tddd|d _|d  d!|jd" _g d#}d$}|D ]a\}}}|d% ||< tdddd&|| _||| _tddd|| _||| _d'||< ||| _||| _tddd|| _||| _d(| }d'||< ||| _||| _d)|j| _|d7 }qd*|d+< ||d+ _||d+ _tddd|d+ _|d, d!|jd- _d.|d/< tdd-dd0d1|d/ _|d2 d|jd _g d3}g d4}t||D ]\}}|| d5 }||_||_||_tddd|_||_qcd!|jd _g d6}t|d7d8D ]\}}||d9| < ||d9|  _|dk r|	n|
|d9|  _tddd|d9|  _||d9|  _d'|d:| < ||d:|  _|dk r|	n|
|d:|  _tddd|d:|  _||d:|  _d'|d;| < ||d;|  _|dk r|	n|
|d;|  _tddd|d;|  _||d;|  _d'|d(| < |dk r;|	n|
|d(|  _||d(|  _d)|j| _qd<|jd9 _d<|jd: _d=|jd; _d>|jd( _td?d?d?d?d@d@dA|_tdBdCdddD|_d|j_d|j_dE|_g |_ z|!dFdG t"dH W n t#y } zt"dI|  W Y d}~nd}~ww z|$d>dF t"dJ W n t#y } zt"dK|  W Y d}~nd}~ww dE|_tdBdCdddD|_d|j_d|j_td?d?d?d?d@d@dA|_g |_ t"dL|j% dM|j& dN|j  |'|  dOdPl(m)} || }|j}t"dQ|j% dM|j& dN|j  |*  t+| S )Ru   
    BASE 엑셀 템플릿 생성
    
    Args:
        output_path: 저장할 경로 (없으면 기본 경로)
    
    Returns:
        엑셀 파일 경로
    Nstudyplan_fileszbase_studyplan_template.xlsxT)parentsexist_oku   学習計画表u   メイリオ   FFFFFF)namesizeboldcolor      )r   r   4472C4solid)start_color	end_color	fill_typeD9E1F2E7F3FFFFF2CCthin)style)leftrighttopbottomzA1:D1A1center)
horizontalvertical      u   【基本情報】A3r#   zA3:D3      ))u   目標期間B4C4)u   現在の状態B5C5)u   平日学習時間B6C6)u   週末学習時間B7C7)u   希望時間帯B8C8   :)r   r   r    D   u   【週間スケジュール】A10zA10:D10
   u8   (このパターンを目標期間中繰り返します)A11666666)r   r   italicr   zA11:D11)u   曜日u   学習時間u	   時間帯)ABC12u	   月曜日u	   火曜日u	   水曜日u	   木曜日u	   金曜日u	   土曜日u	   日曜日   startrD   rE   rF      #      g      ?g333333?)r#   r$   r%   r&   headerfooter	landscape	   orientation	paperSizefitToHeight
fitToWidthA1:D19   d   z?BASE Template: Force deleted rows 20-120 to clear ghost stylingz-BASE Template: Could not delete rows 20-120: z<BASE Template: Force deleted cols E-X to clear ghost stylingz*BASE Template: Could not delete cols E-X: z$BASE Template before save - max_row=, max_column=z, print_area=r   load_workbookz.BASE Template after save and reload - max_row=),r   __file__resolveparentmkdirr   activetitler   r   r   r   merge_cellsfontfillr   	alignmentrow_dimensionsheightborderzipvalue	enumeratecolumn_dimensionswidthr
   page_marginsr   
page_setuphorizontalCenteredverticalCentered
print_areapage_breaksdelete_rowsprint	Exceptiondelete_colsmax_row
max_columnsaveopenpyxlr]   closestr)r   base_dirwbws
title_fontheader_fontnormal_fontheader_fill	info_fillweekday_fillweekend_fillthin_border
info_itemsrowlabel
label_cell
value_celld_cellheadersheader_colscolrO   cellweekdaysidxdayer]   wb_checkws_check r   H/home/air/goalskill_sales/back/app/services/studyplan_excel_generator.pycreate_base_excel_template   s&  





















 
 r   time_slot_texthoursreturnc              
   C   s  |    }ddddddddd}d	}| D ]\}}|| v r#|} nq|rZ|d	urZtt|d
\}}|d | }	|	|d  }
|
d d }|
d }|dd
|d}| d| S dddddddddd	}| D ]\}}|| v rv|  S qjd| v sd| v sd
| v r| dd} | S | S )u  
    시간대 텍스트를 시간 범위 형식으로 변환
    학습 시간(hours)이 주어지면 시작 시간부터 해당 시간만큼 계산
    
    Args:
        time_slot_text: 시간대 텍스트 (예: "夕方")
        hours: 학습 시간 (예: 1, 3) - None이면 기본 범위 반환
    
    Returns:
        시간 범위 (예: "17:00~18:00" 또는 "17:00~20:00")
    z06:00z09:00z12:00z14:00z17:00z19:00z22:00)   朝   午前   昼   午後   夕方   夜間   深夜   夜間/深夜Nr;   <      02d~z06:00~09:00z09:00~12:00z12:00~14:00z14:00~17:00z17:00~19:00z19:00~22:00z22:00~02:00z19:00~02:00)	r   r   r   r   r   r   r   r   u    夜間/深夜（19:00〜02:00）u   〜)lowerstripitemsmapintsplitreplace)r   r   time_slot_lowertime_slot_start_map
start_timekeyrl   
start_hour	start_minstart_minutesend_minutesend_hourend_minend_timetime_slot_mapr   r   r   _convert_time_slot_to_range  sT   r   c              
   C   s   ddl m} ddlm}m} zA||\}}||}| jjD ]/}|j|  kr+|jkrLn q|j	|  kr9|j
krLn q||j	}	|j}
|	 |
   W S qW |S  tyb } zW Y d}~|S d}~ww )uz   
    병합된 셀인 경우 병합의 시작 셀 좌표를 반환
    병합되지 않은 셀이면 그대로 반환
    r   r   coordinate_from_stringcolumn_index_from_stringN)openpyxl.utilsr	   openpyxl.utils.cellr   r   merged_cellsrangesmin_rowrz   min_colmax_colrx   )r   cell_coordinater	   r   r   r   r   col_idxmerged_range	start_col	start_rowr   r   r   r   _get_merged_cell_startL  s&   

r   
excel_pathtotal_durationcurrent_statusweekday_hoursweekend_hourspreferred_time_slotc                    s^  ddl m} || }|j  fdd}|}	ddlm}
 |
d |
d| dt| d	| dt| d
	 |
d| d|  |
d|	 d |
d zt d}||| |
d| d|  W n ty{ } z	|
	d|   d}~ww zt d}||| |
d| d|  W n ty } z	|
	d|   d}~ww zt d}||| d |
d| d| d W n ty } z	|
	d|   d}~ww zt d}||| d |
d| d| d W n ty } z	|
	d|   d}~ww zt d}|||	 |
d| d |	  W n ty9 } z	|
	d!|   d}~ww g d"}t
|d#d$D ]{\}}d%| }d&| }zQ|d'k r}||| d t||}||| |
d| d(| d)| d(| d*	 n$||| d t||}||| |
d| d(| d)| d(| d+	 W qD ty } z|
	d,| d-| d(|   d}~ww z d.d/ |
d0 W n ty } z|
d1|  W Y d}~nd}~ww z d2d. |
d3 W n ty } z|
d4|  W Y d}~nd}~ww d5 _td6d7d8d8d9 _g  _|
d: |
d; j d< j  |
d= j  |
d> jj d? jj  |
d@ jj  |
dAt j  ||  |
dB|   ddl m} || }|j}|
dC |
d;|j d<|j  |
d=|j  |
d>|jj d?|jj  |
dD |  | S )Euy  
    BASE 엑셀 템플릿에 데이터 채우기
    
    Args:
        excel_path: 엑셀 파일 경로
        total_duration: 목표 기간
        current_status: 현재 상태
        weekday_hours: 평일 학습 시간
        weekend_hours: 주말 학습 시간
        preferred_time_slot: 선호 시간대
    
    Returns:
        채워진 엑셀 파일 경로
    r   r\   c                    s  ddl m}m} ddlm} zdt | }g }||\}}||}	t jjD ],}
|
j	|  kr4|
j
krRn q&|
j|	  krB|
jkrRn q&|t|
  t|
 q&| |< |d| d| d|  d |D ]} | qhW dS  ty } zc|d|  d	| d
 zt | }| |< |d| d|  W n2 ty } z&|d|  d	|  z| |  _W n   td|  d	| W Y d}~nd}~ww W Y d}~dS W Y d}~dS d}~ww )u2   병합된 셀도 안전하게 값을 쓰는 함수r   r   loggerzSuccessfully wrote z to z (original: )zError writing to : z, trying direct writezDirect write succeeded: zFailed to write to zCannot write to N)r   r   r   app.core.configr   r   listr   r   r   rz   r   r   appendr   unmerge_cellsdebugrd   rx   warningerrorrl   )
cell_coordrl   r   r   r   
start_cellmerged_ranges_to_restorer   r   r   r   merged_range_strr   e2r   r   r   safe_write_cell  sJ   

z-fill_excel_with_data.<locals>.safe_write_cellr   z=== Filling Excel ===zReceived values: weekday_hours=z (type: z), weekend_hours=r   z	Duration=z	, Status=zTime slot: z) (will be calculated per weekday/weekend)z====================r0   zWrote z (B4): zError writing B4: Nr2   z (B5): zError writing B5: r4   u   時間z (B6): zError writing B6: r6   z (B7): zError writing B7: r8   z (B8): zError writing B8: rH   rI   rJ   rE   rF   r   r   u   時間, z
 (weekday)z
 (weekend)zError writing z or rY   rZ   z0Force deleted rows 20-120 to clear ghost stylingzCould not delete rows 20-120: rN   z-Force deleted cols E-X to clear ghost stylingzCould not delete cols E-X: rX   rQ   rR   r,   rS   z#=== Excel File Info Before Save ===zmax_row=r[   zprint_area=zpage_setup.fitToHeight=z, fitToWidth=zpage_setup.orientation=zpage_breaks count=zExcel file saved to: z$=== Excel File Info After Reload ===z%=====================================)r}   r]   rb   r   r   infotyper   rx   r   rm   r   rv   r   ry   rt   r   rq   ru   rz   r{   rV   rW   rT   lenr|   r~   )r   r   r   r   r   r   r]   r   r   time_slot_for_summaryr   target_cellr   r   r   r   b_cellc_celltime_slot_weekdaytime_slot_weekendr   r   r   r   r   fill_excel_with_dataj  s   2
,













&

$



r   )N)__doc__r}   r   openpyxl.stylesr   r   r   r   r   r   r	   openpyxl.worksheet.pager
   r   pathlibr   r   r   r   r   r   r   r   r   r   r   <module>   s&    sK