#!/usr/bin/env python3
import os
import sys
import shutil
import hashlib
from pathlib import Path
import json
from datetime import datetime
import mimetypes
import logging

# Configurar logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# Extensões por tipo
VIDEO_EXTENSIONS = {'.mp4', '.mov', '.avi', '.mkv', '.webm', '.flv', '.wmv'}
IMAGE_EXTENSIONS = {'.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.svg', '.tiff'}
TEXT_EXTENSIONS = {'.txt', '.md', '.doc', '.docx', '.rtf'}
PDF_EXTENSIONS = {'.pdf'}

class CampaignOrganizer:
    def __init__(self, input_dir):
        self.input_dir = Path(input_dir).resolve()
        self.videos_dir = self.input_dir / 'videos'
        self.images_dir = self.input_dir / 'imagens'
        self.texts_dir = self.input_dir / 'textos'
        self.pdfs_dir = self.input_dir / 'pdfs'
        self.outros_dir = self.input_dir / 'outros'
        self.metadata = {
            'campaign': 'Milla Borges - Redação Blindada',
            'organized_at': datetime.now().isoformat(),
            'files': []
        }
        
    def create_directories(self):
        """Criar diretórios para organização"""
        for dir_path in [self.videos_dir, self.images_dir, self.texts_dir, self.pdfs_dir, self.outros_dir]:
            dir_path.mkdir(exist_ok=True)
            logging.info(f"Diretório criado/verificado: {dir_path}")
    
    def get_file_hash(self, filepath):
        """Gerar hash MD5 do arquivo para evitar duplicatas"""
        hash_md5 = hashlib.md5()
        with open(filepath, "rb") as f:
            for chunk in iter(lambda: f.read(4096), b""):
                hash_md5.update(chunk)
        return hash_md5.hexdigest()[:8]
    
    def safe_filename(self, filename, counter=1):
        """Gerar nome de arquivo único e seguro"""
        base = Path(filename).stem
        ext = Path(filename).suffix
        # Remover caracteres especiais
        safe_base = "".join(c for c in base if c.isalnum() or c in (' ', '-', '_')).rstrip()
        safe_base = safe_base.replace(' ', '_')
        
        if counter > 1:
            return f"{safe_base}_{counter}{ext}"
        return f"{safe_base}{ext}"
    
    def organize_files(self):
        """Organizar arquivos por tipo"""
        file_counters = {}
        
        for root, dirs, files in os.walk(self.input_dir):
            # Pular diretórios de destino
            if any(str(d) in root for d in [self.videos_dir, self.images_dir, self.texts_dir, self.pdfs_dir, self.outros_dir]):
                continue
                
            for file in files:
                if file.startswith('.'):  # Ignorar arquivos ocultos
                    continue
                    
                src_path = Path(root) / file
                file_ext = src_path.suffix.lower()
                
                # Determinar diretório de destino
                if file_ext in VIDEO_EXTENSIONS:
                    dest_dir = self.videos_dir
                    file_type = 'video'
                elif file_ext in IMAGE_EXTENSIONS:
                    dest_dir = self.images_dir
                    file_type = 'image'
                elif file_ext in TEXT_EXTENSIONS:
                    dest_dir = self.texts_dir
                    file_type = 'text'
                elif file_ext in PDF_EXTENSIONS:
                    dest_dir = self.pdfs_dir
                    file_type = 'pdf'
                else:
                    dest_dir = self.outros_dir
                    file_type = 'other'
                
                # Gerar nome único
                base_name = self.safe_filename(file)
                counter = file_counters.get(base_name, 1)
                new_name = self.safe_filename(file, counter)
                
                while (dest_dir / new_name).exists():
                    counter += 1
                    new_name = self.safe_filename(file, counter)
                
                file_counters[base_name] = counter + 1
                
                # Mover arquivo
                dest_path = dest_dir / new_name
                try:
                    shutil.move(str(src_path), str(dest_path))
                    logging.info(f"Movido: {src_path.name} -> {dest_path}")
                    
                    # Adicionar aos metadados
                    self.metadata['files'].append({
                        'original_name': file,
                        'new_name': new_name,
                        'type': file_type,
                        'original_path': str(src_path.relative_to(self.input_dir)),
                        'new_path': str(dest_path.relative_to(self.input_dir)),
                        'size': dest_path.stat().st_size,
                        'hash': self.get_file_hash(dest_path)
                    })
                except Exception as e:
                    logging.error(f"Erro ao mover {src_path}: {e}")
        
        # Salvar metadados
        metadata_path = self.input_dir / 'campaign_metadata.json'
        with open(metadata_path, 'w', encoding='utf-8') as f:
            json.dump(self.metadata, f, ensure_ascii=False, indent=2)
        logging.info(f"Metadados salvos em: {metadata_path}")
        
        # Limpar diretórios vazios
        self.cleanup_empty_dirs()
        
    def cleanup_empty_dirs(self):
        """Remover diretórios vazios após organização"""
        for root, dirs, files in os.walk(self.input_dir, topdown=False):
            if root == str(self.input_dir):
                continue
            if not any(Path(root).iterdir()):
                try:
                    os.rmdir(root)
                    logging.info(f"Diretório vazio removido: {root}")
                except Exception as e:
                    logging.error(f"Erro ao remover diretório {root}: {e}")
    
    def print_summary(self):
        """Imprimir resumo da organização"""
        summary = {
            'videos': len(list(self.videos_dir.glob('*'))),
            'imagens': len(list(self.images_dir.glob('*'))),
            'textos': len(list(self.texts_dir.glob('*'))),
            'pdfs': len(list(self.pdfs_dir.glob('*'))),
            'outros': len(list(self.outros_dir.glob('*')))
        }
        
        print("\n=== RESUMO DA ORGANIZAÇÃO ===")
        for tipo, count in summary.items():
            print(f"{tipo.capitalize()}: {count} arquivos")
        print(f"Total: {sum(summary.values())} arquivos")
        print("=============================\n")

def main():
    if len(sys.argv) != 2:
        print("Uso: python organizar_campanha.py <diretório>")
        sys.exit(1)
    
    input_dir = sys.argv[1]
    
    if not os.path.exists(input_dir):
        print(f"Erro: Diretório '{input_dir}' não encontrado.")
        sys.exit(1)
    
    organizer = CampaignOrganizer(input_dir)
    
    print(f"Organizando arquivos em: {organizer.input_dir}")
    organizer.create_directories()
    organizer.organize_files()
    organizer.print_summary()
    
    print("Organização concluída!")

if __name__ == "__main__":
    main()