from flask import Flask, render_template, request, jsonify, send_from_directory
from flask_cors import CORS
import json
import os
import time
import threading
from datetime import datetime, timedelta
import psutil
import pyautogui
import base64
from io import BytesIO
import schedule

app = Flask(__name__)
CORS(app)  # Enable CORS for all routes

# Data storage files
DATA_DIR = 'data'
EMPLOYEES_FILE = os.path.join(DATA_DIR, 'employees.json')
TIME_LOGS_FILE = os.path.join(DATA_DIR, 'time_logs.json')
ATTENDANCE_FILE = os.path.join(DATA_DIR, 'attendance.json')
SCREENSHOTS_DIR = os.path.join(DATA_DIR, 'screenshots')
MESSAGES_FILE = os.path.join(DATA_DIR, 'messages.json')

# Create directories if they don't exist
os.makedirs(DATA_DIR, exist_ok=True)
os.makedirs(SCREENSHOTS_DIR, exist_ok=True)

# Initialize data files
def init_data_files():
    files_data = {
        EMPLOYEES_FILE: [],
        TIME_LOGS_FILE: [],
        ATTENDANCE_FILE: [],
        MESSAGES_FILE: []
    }
    
    for file_path, default_data in files_data.items():
        if not os.path.exists(file_path):
            with open(file_path, 'w') as f:
                json.dump(default_data, f, indent=2)

init_data_files()

# Utility functions
def load_json(file_path):
    try:
        with open(file_path, 'r') as f:
            return json.load(f)
    except:
        return []

def save_json(file_path, data):
    with open(file_path, 'w') as f:
        json.dump(data, f, indent=2)

def get_current_time():
    return datetime.now().isoformat()

# Employee Management
class EmployeeManager:
    @staticmethod
    def add_employee(name, email, department, role):
        employees = load_json(EMPLOYEES_FILE)
        employee = {
            'id': len(employees) + 1,
            'name': name,
            'email': email,
            'department': department,
            'role': role,
            'status': 'offline',
            'last_activity': None,
            'created_at': get_current_time()
        }
        employees.append(employee)
        save_json(EMPLOYEES_FILE, employees)
        return employee
    
    @staticmethod
    def get_all_employees():
        return load_json(EMPLOYEES_FILE)
    
    @staticmethod
    def update_employee_status(employee_id, status):
        employees = load_json(EMPLOYEES_FILE)
        for emp in employees:
            if emp['id'] == employee_id:
                emp['status'] = status
                emp['last_activity'] = get_current_time()
                break
        save_json(EMPLOYEES_FILE, employees)

# Time Tracking
class TimeTracker:
    @staticmethod
    def clock_in(employee_id):
        time_logs = load_json(TIME_LOGS_FILE)
        log_entry = {
            'id': len(time_logs) + 1,
            'employee_id': employee_id,
            'clock_in': get_current_time(),
            'clock_out': None,
            'total_hours': 0,
            'date': datetime.now().strftime('%Y-%m-%d')
        }
        time_logs.append(log_entry)
        save_json(TIME_LOGS_FILE, time_logs)
        EmployeeManager.update_employee_status(employee_id, 'online')
        return log_entry
    
    @staticmethod
    def clock_out(employee_id):
        time_logs = load_json(TIME_LOGS_FILE)
        today = datetime.now().strftime('%Y-%m-%d')
        
        for log in reversed(time_logs):
            if log['employee_id'] == employee_id and log['date'] == today and not log['clock_out']:
                log['clock_out'] = get_current_time()
                # Calculate total hours
                clock_in = datetime.fromisoformat(log['clock_in'])
                clock_out = datetime.fromisoformat(log['clock_out'])
                total_seconds = (clock_out - clock_in).total_seconds()
                log['total_hours'] = round(total_seconds / 3600, 2)
                break
        
        save_json(TIME_LOGS_FILE, time_logs)
        EmployeeManager.update_employee_status(employee_id, 'offline')
        return log
    
    @staticmethod
    def get_time_logs(employee_id=None, date=None):
        time_logs = load_json(TIME_LOGS_FILE)
        if employee_id:
            time_logs = [log for log in time_logs if log['employee_id'] == employee_id]
        if date:
            time_logs = [log for log in time_logs if log['date'] == date]
        return time_logs

# Screenshot Manager
class ScreenshotManager:
    @staticmethod
    def take_screenshot(employee_id):
        try:
            screenshot = pyautogui.screenshot()
            timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
            filename = f"emp_{employee_id}_{timestamp}.png"
            filepath = os.path.join(SCREENSHOTS_DIR, filename)
            screenshot.save(filepath)
            return filename
        except Exception as e:
            print(f"Screenshot error: {e}")
            return None
    
    @staticmethod
    def get_screenshots(employee_id):
        screenshots = []
        for filename in os.listdir(SCREENSHOTS_DIR):
            if filename.startswith(f"emp_{employee_id}_"):
                screenshots.append({
                    'filename': filename,
                    'timestamp': filename.split('_')[2].replace('.png', ''),
                    'path': os.path.join(SCREENSHOTS_DIR, filename)
                })
        return sorted(screenshots, key=lambda x: x['timestamp'], reverse=True)

# Attendance Manager
class AttendanceManager:
    @staticmethod
    def mark_attendance(employee_id, status='present'):
        attendance_records = load_json(ATTENDANCE_FILE)
        today = datetime.now().strftime('%Y-%m-%d')
        
        # Check if already marked for today
        for record in attendance_records:
            if record['employee_id'] == employee_id and record['date'] == today:
                record['status'] = status
                record['updated_at'] = get_current_time()
                save_json(ATTENDANCE_FILE, attendance_records)
                return record
        
        # Create new record
        record = {
            'id': len(attendance_records) + 1,
            'employee_id': employee_id,
            'date': today,
            'status': status,
            'marked_at': get_current_time(),
            'updated_at': get_current_time()
        }
        attendance_records.append(record)
        save_json(ATTENDANCE_FILE, attendance_records)
        return record
    
    @staticmethod
    def get_attendance_report(start_date=None, end_date=None):
        attendance_records = load_json(ATTENDANCE_FILE)
        if start_date and end_date:
            attendance_records = [
                record for record in attendance_records
                if start_date <= record['date'] <= end_date
            ]
        return attendance_records

# Message Manager
class MessageManager:
    @staticmethod
    def send_message(from_emp_id, to_emp_id, message, message_type='text'):
        messages = load_json(MESSAGES_FILE)
        msg = {
            'id': len(messages) + 1,
            'from_employee_id': from_emp_id,
            'to_employee_id': to_emp_id,
            'message': message,
            'type': message_type,
            'timestamp': get_current_time(),
            'read': False
        }
        messages.append(msg)
        save_json(MESSAGES_FILE, messages)
        return msg
    
    @staticmethod
    def get_messages(employee_id):
        messages = load_json(MESSAGES_FILE)
        return [msg for msg in messages if msg['to_employee_id'] == employee_id or msg['from_employee_id'] == employee_id]

# Routes
@app.route('/')
def index():
    return render_template('index.html')

@app.route('/employee')
def employee_portal():
    return render_template('employee.html')

@app.route('/api/employees', methods=['GET', 'POST'])
def employees():
    if request.method == 'POST':
        data = request.json
        employee = EmployeeManager.add_employee(
            data['name'], data['email'], data['department'], data['role']
        )
        return jsonify(employee)
    return jsonify(EmployeeManager.get_all_employees())

@app.route('/api/clock-in/<int:employee_id>', methods=['POST'])
def clock_in(employee_id):
    log = TimeTracker.clock_in(employee_id)
    AttendanceManager.mark_attendance(employee_id, 'present')
    return jsonify(log)

@app.route('/api/clock-out/<int:employee_id>', methods=['POST'])
def clock_out(employee_id):
    log = TimeTracker.clock_out(employee_id)
    return jsonify(log)

@app.route('/api/time-logs/<int:employee_id>')
def get_time_logs(employee_id):
    logs = TimeTracker.get_time_logs(employee_id)
    return jsonify(logs)

@app.route('/api/take-screenshot/<int:employee_id>', methods=['POST'])
def take_screenshot(employee_id):
    filename = ScreenshotManager.take_screenshot(employee_id)
    if filename:
        return jsonify({'status': 'success', 'filename': filename})
    return jsonify({'status': 'error'}), 500

@app.route('/api/screenshots/<int:employee_id>')
def get_screenshots(employee_id):
    screenshots = ScreenshotManager.get_screenshots(employee_id)
    return jsonify(screenshots)

@app.route('/api/screenshots/<filename>')
def serve_screenshot(filename):
    return send_from_directory(SCREENSHOTS_DIR, filename)

@app.route('/api/attendance', methods=['GET', 'POST'])
def attendance():
    if request.method == 'POST':
        data = request.json
        record = AttendanceManager.mark_attendance(
            data['employee_id'], data.get('status', 'present')
        )
        return jsonify(record)
    
    start_date = request.args.get('start_date')
    end_date = request.args.get('end_date')
    records = AttendanceManager.get_attendance_report(start_date, end_date)
    return jsonify(records)

@app.route('/api/messages', methods=['GET', 'POST'])
def messages():
    if request.method == 'POST':
        data = request.json
        message = MessageManager.send_message(
            data['from_employee_id'], data['to_employee_id'], 
            data['message'], data.get('type', 'text')
        )
        return jsonify(message)
    
    employee_id = request.args.get('employee_id')
    if employee_id:
        msgs = MessageManager.get_messages(int(employee_id))
        return jsonify(msgs)
    return jsonify([])

# Auto screenshot scheduler (runs every 10 minutes for active employees)
def auto_screenshot_job():
    employees = EmployeeManager.get_all_employees()
    for emp in employees:
        if emp['status'] == 'online':
            ScreenshotManager.take_screenshot(emp['id'])

# Schedule auto screenshots
schedule.every(10).minutes.do(auto_screenshot_job)

def run_scheduler():
    while True:
        schedule.run_pending()
        time.sleep(60)

# Start scheduler in background thread
scheduler_thread = threading.Thread(target=run_scheduler, daemon=True)
scheduler_thread.start()

if __name__ == '__main__':
    # Get local IP address
    import socket
    hostname = socket.gethostname()
    local_ip = socket.gethostbyname(hostname)
    print(f"Server running on:")
    print(f"Local: http://localhost:8080")
    print(f"Network: http://{local_ip}:8080")
    print(f"Mobile access: Use the Network URL above")
    
    app.run(debug=True, host='0.0.0.0', port=8080)