import os
import json
import fcntl
from datetime import datetime
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from pydantic import BaseModel
from typing import List, Dict, Any

app = FastAPI(title="Order Manager Web API")
templates = Jinja2Templates(directory="templates")

# Docker 환경에서 마운트될 데이터 폴더 경로
DATA_DIR = os.getenv("DATA_DIR", "/app/data")
DATA_FILE = os.path.join(DATA_DIR, "data.json")
CATALOG_FILE = os.path.join(DATA_DIR, "catalog_master.json")

def read_json_file(filepath: str) -> dict:
    if not os.path.exists(filepath):
        return {}
    
    with open(filepath, 'r', encoding='utf-8') as f:
        try:
            fcntl.flock(f, fcntl.LOCK_SH)
            data = json.load(f)
            fcntl.flock(f, fcntl.LOCK_UN)
            return data
        except json.JSONDecodeError:
            fcntl.flock(f, fcntl.LOCK_UN)
            return {}
        except Exception as e:
            # 윈도우 로컬 테스트 시 fcntl이 없을 수 있으므로 예외처리
            f.seek(0)
            return json.load(f)

def write_json_file(filepath: str, data: dict):
    with open(filepath, 'w', encoding='utf-8') as f:
        try:
            fcntl.flock(f, fcntl.LOCK_EX)
            json.dump(data, f, ensure_ascii=False, indent=4)
            fcntl.flock(f, fcntl.LOCK_UN)
        except Exception as e:
            # 윈도우 로컬 테스트 시 예외처리
            json.dump(data, f, ensure_ascii=False, indent=4)

def get_order_archive_path(date_str=None):
    """현재 날짜 또는 주어진 날짜에 해당하는 'YYYY-MM 주문목록.json' 파일 경로를 반환합니다."""
    # data.json에서 archiveDir 설정 읽기
    config = read_json_file(DATA_FILE)
    archive_dir_name = config.get("archiveDir", "50. Archive/주문내역")
    
    # 상위 디렉토리(Vault 루트) 계산
    vault_root = os.path.dirname(DATA_DIR)
    archive_dir = os.path.join(vault_root, archive_dir_name)
    
    if not os.path.exists(archive_dir):
        os.makedirs(archive_dir, exist_ok=True)
        
    if not date_str:
        now = datetime.now()
        date_str = now.strftime("%Y-%m")
        
    filename = f"{date_str} 주문목록.json"
    return os.path.join(archive_dir, filename)

@app.get("/", response_class=HTMLResponse)
def read_root(request: Request):
    """대시보드 페이지"""
    return templates.TemplateResponse("index.html", {"request": request})

@app.get("/catalog", response_class=HTMLResponse)
def view_catalog(request: Request):
    """카탈로그 검색 페이지"""
    catalog_data = read_json_file(CATALOG_FILE)
    items = catalog_data.get("items", [])
    return templates.TemplateResponse("catalog.html", {"request": request, "items": items})

@app.get("/orders", response_class=HTMLResponse)
def view_orders(request: Request):
    """주문 관리 페이지 (현재 달 기준)"""
    now = datetime.now()
    date_str = now.strftime("%Y-%m")
    archive_path = get_order_archive_path(date_str)
    
    orders_data = []
    if os.path.exists(archive_path):
        orders_data = read_json_file(archive_path)
        if isinstance(orders_data, dict):
            # 구조가 객체 형태일 경우
            orders_data = orders_data.get("orders", [])
            
    return templates.TemplateResponse("orders.html", {"request": request, "orders": orders_data, "current_month": date_str})

@app.get("/api/catalog")
def get_catalog_api():
    """카탈로그 API"""
    return read_json_file(CATALOG_FILE)

@app.post("/api/orders")
def create_order_api(new_order: dict):
    """새 주문 기록 API"""
    now = datetime.now()
    date_str = now.strftime("%Y-%m")
    archive_path = get_order_archive_path(date_str)
    
    # 1. 파일 읽기 (빈 리스트로 초기화)
    orders_data = []
    if os.path.exists(archive_path):
        orders_data = read_json_file(archive_path)
        if isinstance(orders_data, dict):
            # 만약 기존 파일이 객체형태({"orders": [...]}) 라면 배열로 추출
            orders_data = orders_data.get("orders", [])
            
    if not isinstance(orders_data, list):
        orders_data = []
        
    # 2. 주문 정보에 날짜 추가
    new_order["createdAt"] = now.isoformat()
    orders_data.append(new_order)
    
    # 3. 파일 쓰기
    write_json_file(archive_path, orders_data)
    
    return {"status": "success", "message": f"{date_str} 주문목록에 저장되었습니다."}
