Загрузка данных


# -*- coding: utf-8 -*-
# project_manager.py

import datetime as dt
import os
import sqlite3
import time 
from pathlib import Path
from tkinter import messagebox

from gui.models import Project
from modules.project_database import ProjectDatabase


class ProjectManager:
    """
    Класс для управления проектами.
    Автоматически загружает список проектов из файлов .db в папке 'project_dbs'.
    """

    DB_DIRECTORY = "project_dbs"
    DB_EXTENSION = ".db"

    def __init__(self):
        """Инициализирует менеджер и загружает существующие проекты."""
        self.projects = []
        self.projects_dir = self._initialize_projects_directory()

        if self.projects_dir:
            self._load_existing_projects()

    def _initialize_projects_directory(self):
        projects_dir = os.path.join(os.getcwd(), self.DB_DIRECTORY)
        try:
            os.makedirs(projects_dir, exist_ok=True)
            print(f"[INFO] Папка для проектов готова: {projects_dir}")
            return projects_dir
        except Exception as e:
            print(f"[ERROR] Не удалось создать/проверить папку 'project_dbs': {e}")
            return None

    def _load_existing_projects(self):
        """Сканирует папку project_dbs и загружает метаданные проектов."""
        
        # КРИТИЧЕСКИ ВАЖНО: Очищаем список ПЕРЕД циклом, чтобы избежать дублей
        self.projects.clear()

        if not self.projects_dir or not os.path.exists(self.projects_dir):
            print("[INFO] Папка проектов не найдена или пуста.")
            return

        for filename in sorted(os.listdir(self.projects_dir)):
            file_path = os.path.join(self.projects_dir, filename)
            
            # Проверяем, что это именно файл базы данных проекта
            if os.path.isfile(file_path) and filename.lower().endswith(self.DB_EXTENSION):
                try:
                    project_code = os.path.splitext(filename)[0]
                    
                    # Читаем имя прямо из файла БД
                    conn = sqlite3.connect(file_path)
                    cursor = conn.cursor()
                    
                    # Проверяем наличие таблицы на случай битого файла
                    cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='project_data';")
                    if not cursor.fetchone():
                        print(f"[WARN] Файл {filename} пустой (нет таблиц). Пропускаем.")
                        continue

                    cursor.execute("SELECT name FROM project_data LIMIT 1")
                    row = cursor.fetchone()
                    
                    # Если таблица есть, но данных нет — используем имя файла как название
                    human_name = row[0] if row and row[0] else project_code.replace("_", " ").title()

                    # Создаем объект модели Project
                    project = Project(name=human_name)
                    project.id = project_code
                    
                    self.projects.append(project)
                    print(f"[LOAD] Проект '{human_name}' (Код: {project_code}) загружен.")

                except Exception as e:
                    print(f"[ERROR] Не удалось прочитать {filename}: {e}")
                finally:
                    if 'conn' in locals():
                        conn.close()



    def list_projects(self):
        return self.projects

    def add_project(self, project_object):
        """
        Режим "Вайб + Пауза": ждем пару секунд, чтобы ОС пришла в себя.
        """
        try:
            raw_id = str(project_object.id).strip().lower()
            name = str(project_object.name).strip()
            
            if not raw_id or not name:
                return False

            project_code = raw_id
            db_path = Path(self.DB_DIRECTORY) / f"{project_code}.db"

            # --- ШАГ 1: ГЛУБОКИЙ СБРОС СОЕДИНЕНИЙ ---
            print("[CLEANUP] Сброс всех соединений...")
            for proj in self.projects:
                if hasattr(proj, 'connection') and proj.connection is not None:
                    try:
                        proj.connection.close()
                        proj.connection = None
                    except Exception:
                        pass
                        
            if hasattr(self, 'db_connection') and self.db_connection is not None:
                try:
                    self.db_connection.close()
                    self.db_connection = None
                except Exception:
                    pass
            if hasattr(self, 'connection') and self.connection is not None:
                try:
                    self.connection.close()
                    self.connection = None
                except Exception:
                    pass

            # --- ШАГ 2: ПАУЗА ДЛЯ WINDOWS ---
            # Ждем 2 секунды. Антивирус за это время уйдет, 
            # а удаленные ранее файлы исчезнут из индекса проводника.
            print("[WAIT] Делаем паузу для операционной системы (2 сек)...")
            time.sleep(2) 

            # --- ШАГ 3: МЯГКАЯ ПРОВЕРКА СУЩЕСТВОВАНИЯ ---
            # Теперь проверяем exists() только ПОСЛЕ паузы
            if db_path.exists():
                messagebox.showerror(
                    "Файл уже существует", 
                    ("Проект с таким кодом уже создан физически.\n\n"
                     "Если ты его не видишь в списке:\n"
                     "1. Проверь папку project_dbs на наличие дублей (например, rrr (1).db).\n"
                     "2. Убедись, что поле ID уникально."
                    )
                )
                return False

            # --- ШАГ 4: ЧИСТОЕ СОЗДАНИЕ ---
            print("[ACTION] Создаем базу данных...")
            conn = sqlite3.connect(db_path)
            cursor = conn.cursor()

            cursor.execute(
                """
                CREATE TABLE IF NOT EXISTS project_data (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    project_code TEXT UNIQUE NOT NULL,
                    created_at TEXT NOT NULL,
                    name TEXT NOT NULL,
                    description TEXT DEFAULT '',
                    date_opened TEXT DEFAULT '',
                    responsible TEXT DEFAULT ''
                )
                """
            )

            current_time = dt.datetime.now().isoformat()
            cursor.execute(
                """
                INSERT INTO project_data (
                    project_code, created_at, name, description, date_opened, responsible
                ) VALUES (?, ?, ?, ?, ?, ?)
                """,
                (
                    project_code,
                    current_time,
                    name,
                    getattr(project_object, "description", ""),
                    getattr(project_object, "date_opened", ""),
                    getattr(project_object, "responsible", ""),
                ),
            )

            conn.commit()
            conn.close()
            print("[SUCCESS] База создана.")

        except Exception as e:
            print(f"[FATAL] Create failed: {e}")
            import traceback
            traceback.print_exc()
            
            # Чистим мусор при любой ошибке
            if db_path.exists():
                try:
                    os.remove(db_path)
                except OSError:
                    pass
            
            messagebox.showerror("Ошибка", f"Не удалось записать данные:\n{e}")
            return False

        # --- ОБНОВЛЕНИЕ СПИСКА ---
        self._load_existing_projects() 
        self.update_groups_tree()
        
        return True