import tkinter as tk
from tkinter import messagebox, ttk, filedialog
from tkinterdnd2 import TkinterDnD, DND_FILES
from PIL import Image, ImageEnhance, ImageOps, ImageTk
from pyzbar.pyzbar import decode
import pyautogui
import qrcode

def process_qr_image(img):
    """画像の前処理とQRコードの解析（共通ロジック）"""
    img_gray = ImageOps.grayscale(img)
    width, height = img_gray.size
    max_size = 1000
    min_size = 400

    if width > max_size or height > max_size:
        img_gray.thumbnail((max_size, max_size), Image.Resampling.LANCZOS)
    elif width < min_size or height < min_size:
        scale = min_size / min(width, height)
        new_w = int(width * scale)
        new_h = int(height * scale)
        img_gray = img_gray.resize((new_w, new_h), Image.Resampling.LANCZOS)

    enhancer = ImageEnhance.Contrast(img_gray)
    img_processed = enhancer.enhance(3.0)
    return decode(img_processed)

def display_results(qr_codes):
    """解析結果を画面のテキストボックスに表示する"""
    result_box.delete("1.0", tk.END)
    if qr_codes:
        results = []
        for i, code in enumerate(qr_codes, 1):
            try:
                text_data = code.data.decode('utf-8')
            except UnicodeDecodeError:
                try:
                    text_data = code.data.decode('shift_jis')
                except:
                    text_data = code.data.decode('latin1', errors='replace')

            if len(qr_codes) > 1:
                results.append(f"[{i}個目]\n{text_data}")
            else:
                results.append(text_data)
        result_box.insert(tk.END, "\n\n---\n\n".join(results))
    else:
        result_box.insert(tk.END, "QRコードが見つかりませんでした。\n（範囲を少し広めに指定してみてください）")

def handle_drop(event):
    """ドラッグ＆ドロップ時の処理"""
    file_path = event.data.strip('{}')
    try:
        img = Image.open(file_path)
        qr_codes = process_qr_image(img)
        display_results(qr_codes)
    except Exception as e:
        messagebox.showerror("エラー", f"ファイルを処理できませんでした:\n{e}")

class ScreenShotSelector:
    """画面を薄暗くしてマウスで範囲選択させるクラス"""
    def __init__(self):
        root.withdraw()
        self.screenshot = pyautogui.screenshot()
        self.overlay = tk.Toplevel()
        self.overlay.attributes("-fullscreen", True)
        self.overlay.attributes("-alpha", 0.3)
        self.overlay.config(bg="black", cursor="cross")
        self.overlay.bind("<ButtonPress-1>", self.on_press)
        self.overlay.bind("<B1-Motion>", self.on_drag)
        self.overlay.bind("<ButtonRelease-1>", self.on_release)
        self.overlay.bind("<Escape>", self.cancel)

        self.canvas = tk.Canvas(self.overlay, bg="black", highlightthickness=0)
        self.canvas.pack(fill=tk.BOTH, expand=True)
        self.rect = None
        self.start_x = None
        self.start_y = None

    def on_press(self, event):
        self.start_x = event.x
        self.start_y = event.y
        self.rect = self.canvas.create_rectangle(self.start_x, self.start_y, self.start_x, self.start_y, outline="red", width=2)

    def on_drag(self, event):
        self.canvas.coords(self.rect, self.start_x, self.start_y, event.x, event.y)

    def on_release(self, event):
        end_x, end_y = event.x, event.y
        self.overlay.destroy()
        root.deiconify()

        x1, y1 = min(self.start_x, end_x), min(self.start_y, end_y)
        x2, y2 = max(self.start_x, end_x), max(self.start_y, end_y)

        if (x2 - x1) < 10 or (y2 - y1) < 10:
            return

        cropped_img = self.screenshot.crop((x1, y1, x2, y2))
        qr_codes = process_qr_image(cropped_img)
        display_results(qr_codes)

    def cancel(self, event):
        self.overlay.destroy()
        root.deiconify()

def generate_qr():
    """入力されたテキストからQRコードを生成する（標準サイズ設定）"""
    text = input_box.get("1.0", tk.END).strip()
    if not text:
        messagebox.showwarning("警告", "QRコードにする文字を入力してください。")
        return

    global current_qr_img

    # 標準的なQRコードの設定
    qr = qrcode.QRCode(
        version=1,
        error_correction=qrcode.constants.ERROR_CORRECT_M, # 誤り訂正レベルM（標準）
        box_size=10,                                        # 1ドットを10px（出力時約300px〜）
        border=4,                                          # 標準規格の白い余白
    )
    qr.add_data(text)
    qr.make(fit=True)

    current_qr_img = qr.make_image(fill_color="black", back_color="white")

    # 画面プレビュー用にリサイズして反映
    preview_img = current_qr_img.resize((200, 200), Image.Resampling.LANCZOS)
    img_tk = ImageTk.PhotoImage(preview_img)
    qr_preview_label.config(image=img_tk)
    qr_preview_label.image = img_tk

    save_btn.config(state=tk.NORMAL)

def save_qr():
    """生成したQRコードを保存する"""
    if 'current_qr_img' not in globals():
        return

    file_path = filedialog.asksaveasfilename(
        defaultextension=".png",
        filetypes=[("PNG Image", "*.png"), ("All Files", "*.*")],
        title="QRコードを保存"
    )
    if file_path:
        current_qr_img.save(file_path)
        messagebox.showinfo("成功", "QRコードを保存しました！")

# メインウィンドウの作成
root = TkinterDnD.Tk()
root.title("万能QRコード ツールボックス")
root.geometry("480x480")

# タブコントロールの作成
notebook = ttk.Notebook(root)
notebook.pack(fill=tk.BOTH, expand=True)

# ----------------- タブ1: 読み取り -----------------
tab1 = tk.Frame(notebook)
notebook.add(tab1, text="  QRコードを読み取る  ")

scan_btn = tk.Button(tab1, text="📸 画面のQRコードをスキャン", bg="#4CAF50", fg="white", font=("", 10, "bold"), command=lambda: root.after(200, ScreenShotSelector))
scan_btn.pack(fill=tk.X, padx=10, pady=5, ipady=5)

drop_label = tk.Label(tab1, text="または、ここに画像をドラッグ＆ドロップ", bg="#e0e0e0", height=4)
drop_label.pack(fill=tk.X, padx=10, pady=5)
drop_label.drop_target_register(DND_FILES)
drop_label.dnd_bind('<<Drop>>', handle_drop)

result_label = tk.Label(tab1, text="解析結果:")
result_label.pack(anchor=tk.W, padx=10, pady=(5, 0))

result_box = tk.Text(tab1, height=10)
result_box.pack(fill=tk.BOTH, padx=10, pady=5, expand=True)

# ----------------- タブ2: 作成 -----------------
tab2 = tk.Frame(notebook)
notebook.add(tab2, text="  QRコードを作る  ")

input_label = tk.Label(tab2, text="QRコードにしたいURLや文字を入力してください:")
input_label.pack(anchor=tk.W, padx=10, pady=(10, 0))

input_box = tk.Text(tab2, height=4)
input_box.pack(fill=tk.X, padx=10, pady=5)

# 操作ボタン
action_frame = tk.Frame(tab2)
action_frame.pack(fill=tk.X, padx=10, pady=5)

# 【修正箇所】 mr=5 を padx=5 に変更しました
make_btn = tk.Button(action_frame, text="✨ QRコードを生成", bg="#2196F3", fg="white", font=("", 10, "bold"), command=generate_qr)
make_btn.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5, ipady=3)

save_btn = tk.Button(action_frame, text="💾 画像として保存", bg="#9C27B0", fg="white", font=("", 10, "bold"), state=tk.DISABLED, command=save_qr)
save_btn.pack(side=tk.RIGHT, fill=tk.X, expand=True, padx=5, ipady=3)

# プレビューエリア
preview_frame = tk.LabelFrame(tab2, text="プレビュー（標準サイズで出力されます）")
preview_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

qr_preview_label = tk.Label(preview_frame, text="ここにプレビューが表示されます")
qr_preview_label.pack(fill=tk.BOTH, expand=True)

root.mainloop()
