#!/usr/bin/env python3
# hacked_fixed.py - clean indentation, shake fixed, uses tkinter + pillow
# Exit: press SPACE

import tkinter as tk
from tkinter import font as tkfont
try:
    from PIL import Image, ImageTk
except Exception:
    Image = None
    ImageTk = None
import random
import textwrap
import time
import os
import sys

SEAL_IMAGE = "/mnt/data/9767e71c-a2a5-4fe2-9b21-1cb3f8886af7.png"
BG_COLOR = "#050505"
HEADER_COLOR = "#ff2b2b"
BODY_COLOR = "#e6e6e6"
HIGHLIGHT_COLOR = "#00d65f"
FONT_FAMILY = "DejaVu Sans"

HEADER_TEXT = "YOUR COMPUTER HAS BEEN LOCKED!"
SUBHEADER = ("This operating system is locked due to detected illegal activity. "
             "All access has been restricted. Unauthorized attempts to bypass "
             "this lock may result in system instability.")
LEFT_PARAGRAPHS = [
    "Following violations were detected:",
    "- Unauthorized access to restricted resources",
    "- Suspicious network activity and exfiltration attempts",
    "- Tampering with protected system components",
    "",
    "To unlock the computer you are required to follow the instructions provided "
    "by the administrator. Failure to comply may result in prolonged lockout."
]
FOOTER = "You have 72 hours to contact support."

def wrap_list(text_list, width_chars=60):
    out = []
    for p in text_list:
        out.extend(textwrap.wrap(p, width=width_chars) or [""])
    return out

class FakeRansom:
    def __init__(self, root):
        self.root = root
        root.title("Locked")
        root.configure(bg=BG_COLOR)
        root.attributes("-fullscreen", True)
        root.config(cursor="none")
        root.protocol("WM_DELETE_WINDOW", self.ignore_close)

        self.width = root.winfo_screenwidth()
        self.height = root.winfo_screenheight()

        self.font_header = tkfont.Font(family=FONT_FAMILY, size=56, weight="bold")
        self.font_sub = tkfont.Font(family=FONT_FAMILY, size=16)
        self.font_body = tkfont.Font(family=FONT_FAMILY, size=14)
        self.font_small = tkfont.Font(family=FONT_FAMILY, size=12)

        self.canvas = tk.Canvas(root, bg=BG_COLOR, highlightthickness=0)
        self.canvas.pack(fill="both", expand=True)

        self.header_id = self.canvas.create_text(
            40, 40, anchor="nw", text=HEADER_TEXT, font=self.font_header,
            fill=HEADER_COLOR
        )

        self.sub_id = self.canvas.create_text(
            40, 120, anchor="nw", text=SUBHEADER, font=self.font_sub, fill=BODY_COLOR, width=self.width//2 - 80
        )

        lines = wrap_list(LEFT_PARAGRAPHS, width_chars=80)
        y = 220
        self.body_text_ids = []
        for line in lines:
            tid = self.canvas.create_text(40, y, anchor="nw", text=line, font=self.font_body, fill=BODY_COLOR)
            self.body_text_ids.append(tid)
            y += 22

        self.highlight_id = self.canvas.create_text(
            40, y+10, anchor="nw", text="To unlock the computer you are obliged to contact the administrator.",
            font=self.font_body, fill=HIGHLIGHT_COLOR
        )

        self.canvas.create_text(40, self.height-60, anchor="nw", text=FOOTER, font=self.font_small, fill=BODY_COLOR)

        self.seal_tk = None
        if SEAL_IMAGE and Image and ImageTk and os.path.exists(SEAL_IMAGE):
            try:
                img = Image.open(SEAL_IMAGE).convert("RGBA")
                max_w = self.width // 3
                max_h = self.height // 2
                ratio = min(max_w / img.width, max_h / img.height, 1.0)
                new_size = (int(img.width * ratio), int(img.height * ratio))
                img = img.resize(new_size, Image.LANCZOS)
                self.seal_tk = ImageTk.PhotoImage(img)
                self.canvas.create_image(self.width - new_size[0] - 40, 60, anchor="nw", image=self.seal_tk)
            except Exception as e:
                print("Could not load seal image:", e, file=sys.stderr)

        self.blink_state = True
        self.root.bind("<space>", self.exit_on_space)
        self.root.bind("<Escape>", lambda e: None)
        self.root.after(500, self.blink)

        self.root.after(2500, self.shake_once)

        self.dot_x = 40 + self.font_header.measure(HEADER_TEXT) + 20
        self.dot_y = 70
        self.dot_phase = 0
        self.root.after(300, self.animate_dots)

    def ignore_close(self):
        pass

    def blink(self):
        self.blink_state = not self.blink_state
        new_col = HEADER_COLOR if self.blink_state else "#800000"
        self.canvas.itemconfig(self.header_id, fill=new_col)
        self.root.after(500, self.blink)

    def animate_dots(self):
        self.canvas.delete("dots")
        for i in range(3):
            fill = BODY_COLOR if (i <= self.dot_phase) else "#333333"
            self.canvas.create_oval(self.dot_x + i*18, self.dot_y, self.dot_x + i*18+12, self.dot_y+12,
                                    fill=fill, outline="", tags="dots")
        self.dot_phase = (self.dot_phase + 1) % 3
        self.root.after(400, self.animate_dots)

    def shake_once(self):
        # move canvas items (no pack/place) to avoid flicker
        steps = 8
        magnitude = 8
        offsets = []
        for i in range(steps):
            offsets.append((random.randint(-magnitude, magnitude), random.randint(-magnitude, magnitude)))
        offsets += [(-x, -y) for (x, y) in offsets[::-1]]

        def do_step(i=0):
            if i >= len(offsets):
                return
            dx, dy = offsets[i]
            self.canvas.move("all", dx, dy)
            self.root.after(25, lambda: do_step(i + 1))

        do_step()
        self.root.after(4000 + random.randint(0, 2000), self.shake_once)

    def exit_on_space(self, event=None):
        self.root.config(cursor="")
        self.root.destroy()

def main():
    root = tk.Tk()
    app = FakeRansom(root)
    root.mainloop()

if __name__ == "__main__":
    main()
