o
    i R                     @   s^  d dl mZmZ d dlmZ d dlmZ d dlmZ d dl	m
Z
 d dlmZ d dlmZ d dlZd dlZd dlZd d	lmZ ed
dgdZeddejfddZeddejfddZdedefddZdedefddZdedefddZ dededefd d!Z!ded"ed#ed$ed%ed&edefd'd(Z"e#d)defd*d+Z$e#d,d-d. Z%dS )/    )	APIRouterHTTPException)FileResponse)studyplan_schema)studyplan_module)studyplan_questions)fill_excel_with_data)loggerN)Pathz/goal-skill-t/api/studyplan	StudyPlan)prefixtagsz/startrequestc              
      s   z,t  }|stddd|d }td| j  |d |d |dd	d
t|dW S  tyI } zt	d|  tdt
|dd}~ww )u   
    학습계획표 시작 - 첫 번째 질문 반환
    
    Returns:
        - question_number: 질문 번호 (1)
        - question_text: 질문 내용
        - current: 현재 질문 번호 (1)
        - total: 전체 질문 수 (5)
      zNo questions availablestatus_codedetailr   zStudyPlan Started for session: question_numbertextreason    r   question_textr   currenttotalzStudyPlan Start Error: N)r   get_questionsr   r	   info
session_idgetlen	Exceptionerrorstr)r   all_questionsfirst_questione r'   >/home/air/goalskill_sales/back/app/routers/studyplan_router.pystart_studyplan   s$   
r)   z/answerc              
      s  zpt | j}|stdddtj| j| j|d | jd | j}tt 	 }t
d| d| d| j  ||krTt| jI d	H }d
d|rOd| j dW S d	dW S t 	 }|| }d|d |d |dd|d |ddW S  ty } zt
d|  tdt|dd	}~ww )u   
    학습계획표 답변 제출
    
    Returns:
        - status: "continue" (계속) or "completed" (완료)
        - next_question: 다음 질문 (continue인 경우)
        - result: 완료 메시지 (completed인 경우)
      zQuestion not foundr   r   )r   r   r   answer_textzStudyPlan Progress: / for session N	completedu_   学習計画表の入力が完了しました！

学習計画表のPDFを生成しました。z/studyplan/pdf/)statusmessagepdf_urlcontinuer   r   r   r   r   )r/   next_questionzStudyPlan Answer Error: r   )r   get_question_by_numberr   r   r   save_studyplan_questionr   r+   r    r   r	   r   process_final_resultr   r!   r"   r#   )r   current_questionanswered_counttotal_questionspdf_pathr$   r3   r&   r'   r'   r(   answer_studyplan9   sJ   

r;   r   returnc              
      s  zddl }t| }t|dkr2tdt| d|   td|  tddt| d	d
t|I dH }|d|d d 	 }|d|d d 	 }|dt
|d d 	 }|dt
|d d 	 }|d|d d 	 }td tddd |D   td| d|  td| dt| d td| dt| d td|  td  tj| |||||d! tj| |||||d" t| |||||d!I dH }	td#|  d$|	  |	W S  ty }
 z
td%|
  |
d}
~
ww )&uZ  
    모든 질문 완료 시 최종 결과 처리
    - studyplan_log에서 답변들 가져오기
    - 답변 파싱 (데이터베이스 스키마에 맞게)
    - studyplan_Output에 저장
    - user_profile_summary에 동기화
    - BASE 엑셀 복사 → 데이터 채우기 → PDF 생성
    
    Returns:
        PDF 파일 경로
    r   N   zExpected 5 answers, but got r-   z	Answers: i  z Not all questions answered. Got z answers instead of 5.r   total_durationr+   current_statusr   weekday_hours   weekend_hours   preferred_time_slot   z === StudyPlan Parsing Result ===zOriginal answers: c                 S   s   g | ]}|d  qS )r+   r'   ).0ar'   r'   r(   
<listcomp>   s    z(process_final_result.<locals>.<listcomp>zParsed data: duration=z	, status=zParsed weekday_hours=z (type: )zParsed weekend_hours=zParsed time_slot=z ================================)r   r>   r?   r@   rB   rD   )r   studyplan_durationstudyplan_statusstudyplan_weekday_hoursstudyplan_weekend_hoursstudyplan_time_slotz.StudyPlan Final Result Processed for session: z, PDF: zStudyPlan Final Result Error: )rer   get_answers_by_sessionr    r	   r"   r   parse_answers_with_air   stripextract_numberr   typesave_studyplan_outputsync_to_user_profile_summarygenerate_studyplan_scheduler!   )r   rO   answersparsed_datar>   r?   r@   rB   rD   r:   r&   r'   r'   r(   r6   w   sh   



	r6   rX   c                    s  z|ddl m} ddl}d}t| dD ]\}}|d| d|d  d	| d|d
  d	7 }qd| d}| }|jjd|dddd}|j }	|	drb|		dd }	|	dr^|	dd }	|	 }	|
|	}
t|
dd|
d< t|
dd|
d< |
W S  ty } z9td| d | d d
  | d d
  t| d d
  t| d d
  | d d
  dW  Y d}~S d}~ww )u  
    AI를 사용하여 5개의 답변을 분석하고 구조화된 데이터 추출
    
    Args:
        answers: 답변 리스트 (question_number, question_text, answer_text 포함)
    
    Returns:
        {
            'total_duration': str,  # 예: "6ヶ月"
            'current_status': str,  # 예: "会社員"
            'weekday_hours': int,   # 예: 1
            'weekend_hours': int,   # 예: 3
            'preferred_time_slot': str  # 예: "夕方"
        }
    r   )get_gemini_modelNr   r   Qz: r   z
Ar+   z

um   
以下の5つの質問と回答を分析して、構造化されたデータを抽出してください。

u  

以下のJSON形式で返答してください。数字は必ず整数で返してください。
{
    "total_duration": "目標期間（例: 6ヶ月）",
    "current_status": "現在の状態（例: 会社員）",
    "weekday_hours": 平日の学習時間（整数、例: 1）,
    "weekend_hours": 週末の学習時間（整数、例: 3）,
    "preferred_time_slot": "希望時間帯（例: 夕方、夜間など、元のテキストそのまま）"
}

重要:
- weekday_hours: Q3の回答から平日（月〜金）の学習時間を抽出してください。ユーザーが「1時間」と言ったら1、「2時間」と言ったら2です。
- weekend_hours: Q4の回答から週末の学習時間を抽出してください。ユーザーが「3時間」と言ったら3、「6時間」と言ったら6です。
- weekday_hoursとweekend_hoursは必ず整数で返してください。推測や補完をせず、ユーザーが実際に言った数字だけを返してください。
- preferred_time_slotはユーザーが入力した元のテキストをそのまま返してください（例: "夕方"、"夜間"など）
- JSONのみを返答してください。他の説明は不要です。
zgemini-2.5-flashg?zapplication/json)temperatureresponse_mime_type)modelcontentsconfigz```jsonrE   r@   rB   zAI parsing error: z#, falling back to simple extractionrA   rC   )r>   r?   r@   rB   rD   )app.core.configrZ   ra   	enumeratemodelsgenerate_contentr   rR   
startswithsplitloadsintr   r!   r	   r"   rS   )rX   rZ   ra   qa_textianswerpromptclientresponseresult_textparsedr&   r'   r'   r(   rQ      sL   ,




rQ   r   c                 C   s(   ddl }|d| }|rt| S dS )uQ   
    텍스트에서 숫자 추출
    예: "2時間" → 2, "6時間" → 6
    r   Nz\d+)rO   searchri   group)r   rO   matchr'   r'   r(   rS     s
   rS   
excel_path
output_dirc              
   C   s  znt d|   t dtj|   ddddddd	|| g	}t d
d|  tj|ddddd}t d|j  |j	rJt 
d|j	  tjtj| d d }tj||}tj|sltd| |W S  ty } zdt|v sdt| v rt d  t d|   d}~w tjy } zt d|j  t d|j	   d}~w tjy   t d   ty } z	t d|   d}~ww )u   
    LibreOffice를 사용하여 Excel 파일을 PDF로 변환합니다.
    
    Args:
        excel_path: 엑셀 파일 경로
        output_dir: PDF 출력 디렉토리
    
    Returns:
        생성된 PDF 파일 경로
    zConverting Excel to PDF: zExcel file exists: libreofficez
--headlessz--nodefaultz--nolockcheckz--convert-tozJpdf:calc_pdf_Export:{"SinglePageSheets":{"type":"boolean","value":"true"}}z--outdirzLibreOffice command:  T   )capture_outputr   checktimeoutz#LibreOffice PDF conversion stdout: z#LibreOffice PDF conversion stderr: r   .pdfzPDF file was not created: z	not foundzZERROR: 'libreoffice' command not found. Is LibreOffice installed and in the system's PATH?zERROR: Nz3ERROR: LibreOffice conversion failed. Return code: zStderr: z'ERROR: LibreOffice conversion timed outz4An unexpected error occurred during PDF conversion: )r	   r   ospathexistsjoin
subprocessrunstdoutstderrwarningsplitextbasenameFileNotFoundErrorr#   lowerr"   CalledProcessError
returncodeTimeoutExpiredr!   )ru   rv   commandresultpdf_filenamer:   r&   r'   r'   r(   convert_excel_to_pdf+  sV   

r   r>   r?   r@   rB   rD   c              
      sZ  zt t jjj}|d }|jdd |d }| s-td|  td W dS |d|  d	 }	t	||	 t
t|	|||||d
 tt|	t|d}
td|	  tdtj|	 d td|
  tdtj|
 d td|	 d |
W S  ty } ztd|  ddl}t|  W Y d}~dS d}~ww )u  
    학습계획표 시간표 엑셀 파일 생성 및 PDF 변환
    BASE 엑셀 템플릿을 복사해서 유저 데이터를 채운 후 LibreOffice로 PDF 변환
    
    Args:
        session_id: 세션 ID
        total_duration: 목표 기간
        current_status: 현재 상태
        weekday_hours: 평일 학습 시간
        weekend_hours: 주말 학습 시간
        preferred_time_slot: 선호 시간대
    
    Returns:
        PDF 파일 경로
    studyplan_filesT)exist_okzbase_studyplan_template.xlsxu'   BASE 엑셀 템플릿이 없습니다: uT   먼저 'python create_base_excel.py'를 실행하여 BASE 엑셀을 생성하세요.N
studyplan_z.xlsx)ru   r>   r?   r@   rB   rD   )ru   rv   zStudyPlan Excel generated: zStudyPlan Excel file size: z byteszStudyPlan PDF generated: zStudyPlan PDF file size: z+=== Excel file available for manual check: z ===z StudyPlan PDF Generation Error: r   )r
   __file__resolveparentmkdirr   r	   r"   shutilcopy2r   r#   r   r   r~   r   getsizer!   	traceback
format_exc)r   r>   r?   r@   rB   rD   base_dirstudyplan_dirbase_excel_pathuser_excel_pathr:   r&   r   r'   r'   r(   rW   i  sJ   

rW   z/pdf/{session_id}c                    s(  zvddl }tt jjj}|d d|  d }| s#tddddd	lm} t	|d
}|
 }W d   n1 s=w   Y  d|  d}|jj|dd}ddl}	tj|}
dt|
 d}||dd|  d| dddd|dddW S  ty } ztd|  tdt|dd}~ww )u7   
    학습계획표 PDF 다운로드/미리보기
    r   Nr   r   r}   r*   zPDF file not foundr   Responserbu   学習計画表_r   safe"application/pdfzinline; filename="studyplan_z.pdf"; filename*=UTF-8''#no-cache, no-store, must-revalidateno-cache0*)Content-DispositionContent-TypeCache-ControlPragmaExpiresETagAccess-Control-Allow-Origincontent
media_typeheaderszStudyPlan PDF Download Error: r   )urllib.parser
   r   r   r   r   r   fastapi.responsesr   openreadparsequotetimer~   r   getmtimeri   r!   r	   r"   r#   )r   urllibr   r:   r   fpdf_contentfilename_utf8filename_encodedr   
file_mtimeetagr&   r'   r'   r(   get_studyplan_pdf  sB   
r   z/admin-base-curriculumc            
   
      s4  zut t jjj} | d d }td|  | s+td|  tdddtd|  t	|d	}|
 }W d
   n1 sGw   Y  dd
l}d}d}|jj|dd}ddlm} ||dd| d| dddddddW S  ty~     ty }	 ztd|	  tdt|	dd
}	~	ww )u{   
    학습계획표 양식 PDF 파일 서빙
    /home/air/goalskill_t/back/studyplan_files/admin_base_curriculum.pdf
    r   zadmin_base_curriculum.pdfz(Admin Base Curriculum PDF Request: path=z%Admin Base Curriculum PDF not found: r*   z#Admin base curriculum PDF not foundr   z!Admin Base Curriculum PDF found: r   Nr   u&   学習計画表_基本フォーム.pdfr   r   r   r   zinline; filename="z"; filename*=UTF-8''r   r   r   r   )r   r   r   r   r   r   r   z!Admin Base Curriculum PDF Error: r   )r
   r   r   r   r	   r   r   r"   r   r   r   r   r   r   r   r   r!   r#   )
r   r:   r   r   r   filename_asciir   r   r   r&   r'   r'   r(   get_admin_base_curriculum  sF   
r   )&fastapir   r   r   r   app.schemasr   
app.modelsr   app.servicesr   &app.services.studyplan_excel_generatorr   rb   r	   r~   r   r   pathlibr
   routerpostStartStudyPlanRequestr)   AnswerStudyPlanRequestr;   r#   r6   listdictrQ   ri   rS   r   rW   r   r   r   r'   r'   r'   r(   <module>   sH   #=QV>
F0