import os
from flask import Flask, request, render_template, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy
from werkzeug.utils import secure_filename

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secretkey'
# 데이터베이스 설정 (SQLite 사용)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///orders.db'
# 업로드 폴더 설정
app.config['UPLOAD_FOLDER'] = 'uploads'
# 파일 크기 제한: 10KB보다 작으면 업로드 제한
app.config['MAX_CONTENT_LENGTH'] = 10 * 1024  # 10KB

db = SQLAlchemy(app)

# 허용 파일 확장자 목록
ALLOWED_EXTENSIONS = {'jpg', 'jpeg', 'gif', 'png', 'webp', 'heic', 'heif'}

# 주문 정보를 저장하는 모델 (Order)
class Order(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    customer_name = db.Column(db.String(50), nullable=False)   # 받는 분 성함
    order_channel = db.Column(db.String(20), nullable=False)     # 주문 채널 (네이버, 쿠팡, 지마켓, 직거래 등)
    photo_size = db.Column(db.String(20), nullable=False)        # 사진 크기 (예: 4x6, 3x5 등)
    gloss_type = db.Column(db.String(10), nullable=False)          # 유광, 무광
    photo_option = db.Column(db.String(20), nullable=False)        # 사진 옵션 (이미지풀, 페이퍼풀)
    quantity = db.Column(db.Integer, nullable=False)             # 주문 장수
    filename = db.Column(db.String(100), nullable=True)            # 업로드한 파일명
    folder_path = db.Column(db.String(200), nullable=True)         # 저장된 폴더 경로

with app.app_context():
    db.create_all()

def allowed_file(filename):
    """파일 확장자가 허용 목록에 있는지 확인"""
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def create_order_folder(order):
    """
    주문 정보를 바탕으로 폴더 구조 생성
    상위 폴더 명명 규칙:
      - 기본 형식: "주문자명 사진크기 [유광/유무광] [옵션] 수량장 - 주문채널"
      - 유광만 있는 경우: 유광은 "(유광)"으로 표기
      - 무광만 있는 경우: 무광은 표기하지 않음
      - 옵션: 페이퍼풀은 '필인', 이미지풀은 '피트인'
      - 상위 폴더에서 이미지풀과 페이퍼풀이 같이 있으면 "필피트"로 표기하지만,
        여기서는 단일 주문 항목이므로 해당 옵션만 적용합니다.
    하위 폴더는 주문한 항목에 대해 모든 옵션을 명시하여 출력합니다.
    """
    # 유광이면 "(유광)"으로, 무광이면 공백
    gloss_text = "(유광)" if order.gloss_type == "유광" else ""
    # 옵션: 페이퍼풀은 '필인', 이미지풀은 '피트인'
    if order.photo_option == "페이퍼풀":
        option_text = "필인"
    elif order.photo_option == "이미지풀":
        option_text = "피트인"
    else:
        option_text = order.photo_option

    # 상위 폴더명 생성
    folder_name = f"{order.customer_name} {order.photo_size} {gloss_text} {option_text} {order.quantity}장 - {order.order_channel}"
    # 공백 정리
    folder_name = " ".join(folder_name.split())
    folder_path = os.path.join(app.config['UPLOAD_FOLDER'], folder_name)
    os.makedirs(folder_path, exist_ok=True)
    return folder_path

# 사용자 페이지: 파일 업로드 및 주문 입력
@app.route('/', methods=['GET', 'POST'])
def upload_order():
    if request.method == 'POST':
        # 폼 데이터 수집
        customer_name = request.form.get('customer_name')
        order_channel = request.form.get('order_channel')
        photo_size = request.form.get('photo_size')
        gloss_type = request.form.get('gloss_type')   # "유광" 또는 "무광"
        photo_option = request.form.get('photo_option')  # "페이퍼풀" 또는 "이미지풀"
        quantity = request.form.get('quantity')

        try:
            quantity = int(quantity)
        except:
            flash("수량은 숫자로 입력해주세요.")
            return redirect(request.url)

        # 파일 업로드 처리
        if 'photo' not in request.files:
            flash("업로드할 파일이 없습니다.")
            return redirect(request.url)
        file = request.files['photo']
        if file.filename == '':
            flash("파일을 선택해주세요.")
            return redirect(request.url)
        # 허용 확장자 확인
        if not allowed_file(file.filename):
            flash("허용되지 않는 파일 형식입니다. (jpg, jpeg, gif, png, webp, heic, heif)")
            return redirect(request.url)
        # 파일 크기 체크 (10KB 이하이면 업로드 불가)
        file.seek(0, os.SEEK_END)
        file_length = file.tell()
        file.seek(0)
        if file_length <= 10 * 1024:
            flash("파일 크기가 너무 작습니다. 10KB보다 큰 파일을 업로드해주세요.")
            return redirect(request.url)

        # 주문 정보 DB 저장
        new_order = Order(
            customer_name=customer_name,
            order_channel=order_channel,
            photo_size=photo_size,
            gloss_type=gloss_type,
            photo_option=photo_option,
            quantity=quantity
        )
        db.session.add(new_order)
        db.session.commit()

        # 주문 폴더 생성 후 파일 저장
        folder_path = create_order_folder(new_order)
        filename = secure_filename(file.filename)
        file_save_path = os.path.join(folder_path, filename)
        file.save(file_save_path)

        # DB에 파일명과 폴더 경로 업데이트
        new_order.filename = filename
        new_order.folder_path = folder_path
        db.session.commit()

        return redirect(url_for('preview_order', order_id=new_order.id))
    return render_template('upload.html')

# 미리보기 페이지: 업로드된 이미지와 주문 상세 정보 표시, 크롭 기능(클라이언트 사이드 구현 가능)
@app.route('/preview/<int:order_id>')
def preview_order(order_id):
    order = Order.query.get_or_404(order_id)
    # 업로드된 파일의 URL 생성
    # (실제 서비스에서는 uploads 폴더를 static 파일로 제공하거나 별도 라우트를 구성)
    file_url = url_for('static', filename=f"{order.folder_path}/{order.filename}")
    return render_template('preview.html', order=order, file_url=file_url)

# 관리자 페이지: 주문 목록 및 옵션 관리 페이지 (사진 크기, 크롭 옵션 추가/삭제 등 관리)
@app.route('/admin')
def admin_page():
    orders = Order.query.all()
    return render_template('admin.html', orders=orders)

if __name__ == '__main__':
    # 업로드 폴더가 없으면 생성
    os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
    app.run(debug=True)
