import os
from datetime import datetime
from flask import Flask, jsonify, render_template
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_cors import CORS
from flask_mail import Mail, Message
import threading

# Load environment variables from .env file
try:
    from dotenv import load_dotenv
    load_dotenv()
except ImportError:
    print("python-dotenv not installed. Environment variables will be loaded from system.")

# --- 1. APPLICATION SETUP & CONFIGURATION ---

# Get the absolute path of the directory where this file is located
basedir = os.path.abspath(os.path.dirname(__file__))

# Create the Flask application instance
app = Flask(__name__)
application=app
# Configure the database
# Suppress a warning from SQLAlchemy
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# Define the path for the SQLite database file
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL') or \
    'sqlite:///' + os.path.join(basedir, 'fire_log.db')

# Email configuration
app.config['MAIL_SERVER'] = os.environ.get('MAIL_SERVER') or 'smtp.gmail.com'
app.config['MAIL_PORT'] = int(os.environ.get('MAIL_PORT') or 587)
app.config['MAIL_USE_TLS'] = os.environ.get('MAIL_USE_TLS', 'true').lower() in ['true', 'on', '1'] or TRUE
app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME') or 'ruhul.amin.tnt@gmail.com'
app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD') or 'msbrztpncbfqvrxf'
app.config['MAIL_DEFAULT_SENDER'] = os.environ.get('MAIL_DEFAULT_SENDER') or 'ruhul.amin.tnt@gmail.com'
app.config['NOTIFICATION_EMAIL'] = os.environ.get('NOTIFICATION_EMAIL') or 'ruhul.amin.tnt@gmail.com'

print("MAIL_USERNAME:", app.config['MAIL_USERNAME'])
print("MAIL_PASSWORD exists:", bool(app.config['MAIL_PASSWORD']))
print("MAIL PASSWOR", app.config['MAIL_PASSWORD'])


# --- 2. INITIALIZE EXTENSIONS ---

# Initialize the SQLAlchemy database object
db = SQLAlchemy(app)
# Initialize the Migrate object for handling database migrations
migrate = Migrate(app, db)
# Initialize CORS for cross-origin requests
CORS(app)
# Initialize Flask-Mail for email notifications
mail = Mail(app)


# --- 3. DATABASE MODEL DEFINITION ---

class Event(db.Model):
    """Represents a single fire event in the database."""
    id = db.Column(db.Integer, primary_key=True)
    fire_alert_time = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    extinguish_time = db.Column(db.DateTime, nullable=True)
    status = db.Column(db.String(20), nullable=False, default='active')

    def __repr__(self):
        return f'<Event {self.id} - Status: {self.status}>'

    def to_dict(self):
        """Serializes the model object to a dictionary for JSON responses."""
        return {
            'id': self.id,
            'fire_alert_time': self.fire_alert_time.isoformat() if self.fire_alert_time else None,
            'extinguish_time': self.extinguish_time.isoformat() if self.extinguish_time else None,
            'status': self.status
        }


# --- 4. EMAIL NOTIFICATION FUNCTIONS ---

def send_async_email(app, msg):
    """Send email asynchronously to avoid blocking the main thread."""
    with app.app_context():
        try:
            mail.send(msg)
        except Exception as e:
            print(f"Failed to send email: {e}")

def send_fire_alert_email(event):
    """Send email notification for fire alert."""
    try:
        if not app.config.get('NOTIFICATION_EMAIL') or not app.config.get('MAIL_USERNAME'):
            print("Email configuration not set. Skipping email notification.")
            return
        
        msg = Message(
            subject='🔥 FIRE ALERT - Immediate Action Required',
            recipients=[app.config['NOTIFICATION_EMAIL']],
            sender=app.config['MAIL_DEFAULT_SENDER'] or app.config['MAIL_USERNAME']
        )
        
        msg.html = f"""
        <html>
        <body style="font-family: Arial, sans-serif; background-color: #f8f9fa; padding: 20px;">
            <div style="max-width: 600px; margin: 0 auto; background-color: white; border-radius: 10px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); overflow: hidden;">
                <div style="background: linear-gradient(45deg, #ff6b6b, #ffa500); color: white; padding: 20px; text-align: center;">
                    <h1 style="margin: 0; font-size: 24px;">🔥 FIRE ALERT</h1>
                    <p style="margin: 5px 0 0 0; font-size: 16px;">Fire Fighting Bot System</p>
                </div>
                <div style="padding: 30px;">
                    <div style="background-color: #fff5f5; border-left: 4px solid #ff6b6b; padding: 15px; margin-bottom: 20px;">
                        <h2 style="color: #c53030; margin: 0 0 10px 0;">Fire Detected!</h2>
                        <p style="margin: 0; color: #2d3748;">A fire has been detected and logged in the system.</p>
                    </div>
                    
                    <table style="width: 100%; border-collapse: collapse; margin-bottom: 20px;">
                        <tr>
                            <td style="padding: 10px; border-bottom: 1px solid #e2e8f0; font-weight: bold; color: #4a5568;">Event ID:</td>
                            <td style="padding: 10px; border-bottom: 1px solid #e2e8f0; color: #2d3748;">#{event.id}</td>
                        </tr>
                        <tr>
                            <td style="padding: 10px; border-bottom: 1px solid #e2e8f0; font-weight: bold; color: #4a5568;">Alert Time:</td>
                            <td style="padding: 10px; border-bottom: 1px solid #e2e8f0; color: #2d3748;">{event.fire_alert_time.strftime('%Y-%m-%d %H:%M:%S UTC')}</td>
                        </tr>
                        <tr>
                            <td style="padding: 10px; border-bottom: 1px solid #e2e8f0; font-weight: bold; color: #4a5568;">Status:</td>
                            <td style="padding: 10px; border-bottom: 1px solid #e2e8f0; color: #c53030; font-weight: bold;">ACTIVE</td>
                        </tr>
                    </table>
                    
                    <div style="background-color: #f7fafc; padding: 15px; border-radius: 5px; margin-bottom: 20px;">
                        <h3 style="margin: 0 0 10px 0; color: #2d3748;">Immediate Actions Required:</h3>
                        <ul style="margin: 0; padding-left: 20px; color: #4a5568;">
                            <li>Fire fighting bot has been activated</li>
                            <li>Verify the fire location immediately</li>
                            <li>Ensure emergency protocols are followed</li>
                            <li>Monitor the dashboard for updates</li>
                        </ul>
                    </div>
                    
                    <div style="text-align: center;">
                        <p style="margin: 0; color: #718096; font-size: 14px;">This is an automated notification from the Fire Fighting Bot System.</p>
                    </div>
                </div>
            </div>
        </body>
        </html>
        """
        
        # Send email in background thread
        thread = threading.Thread(target=send_async_email, args=(app, msg))
        thread.start()
        print(f"Fire alert email sent for event {event.id}")
        
    except Exception as e:
        print(f"Error sending fire alert email: {e}")

def send_fire_extinguished_email(event):
    """Send email notification when fire is extinguished."""
    try:
        if not app.config.get('NOTIFICATION_EMAIL') or not app.config.get('MAIL_USERNAME'):
            print("Email configuration not set. Skipping email notification.")
            return
        
        # Calculate response time
        if event.fire_alert_time and event.extinguish_time:
            duration = event.extinguish_time - event.fire_alert_time
            duration_str = str(duration).split('.')[0]  # Remove microseconds
        else:
            duration_str = "Unknown"
        
        msg = Message(
            subject='✅ Fire Extinguished - All Clear',
            recipients=[app.config['NOTIFICATION_EMAIL']],
            sender=app.config['MAIL_DEFAULT_SENDER'] or app.config['MAIL_USERNAME']
        )
        
        msg.html = f"""
        <html>
        <body style="font-family: Arial, sans-serif; background-color: #f8f9fa; padding: 20px;">
            <div style="max-width: 600px; margin: 0 auto; background-color: white; border-radius: 10px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); overflow: hidden;">
                <div style="background: linear-gradient(45deg, #48bb78, #38a169); color: white; padding: 20px; text-align: center;">
                    <h1 style="margin: 0; font-size: 24px;">✅ FIRE EXTINGUISHED</h1>
                    <p style="margin: 5px 0 0 0; font-size: 16px;">Fire Fighting Bot System</p>
                </div>
                <div style="padding: 30px;">
                    <div style="background-color: #f0fff4; border-left: 4px solid #48bb78; padding: 15px; margin-bottom: 20px;">
                        <h2 style="color: #2f855a; margin: 0 0 10px 0;">Fire Successfully Extinguished!</h2>
                        <p style="margin: 0; color: #2d3748;">The fire has been successfully extinguished and the area is now safe.</p>
                    </div>
                    
                    <table style="width: 100%; border-collapse: collapse; margin-bottom: 20px;">
                        <tr>
                            <td style="padding: 10px; border-bottom: 1px solid #e2e8f0; font-weight: bold; color: #4a5568;">Event ID:</td>
                            <td style="padding: 10px; border-bottom: 1px solid #e2e8f0; color: #2d3748;">#{event.id}</td>
                        </tr>
                        <tr>
                            <td style="padding: 10px; border-bottom: 1px solid #e2e8f0; font-weight: bold; color: #4a5568;">Alert Time:</td>
                            <td style="padding: 10px; border-bottom: 1px solid #e2e8f0; color: #2d3748;">{event.fire_alert_time.strftime('%Y-%m-%d %H:%M:%S UTC')}</td>
                        </tr>
                        <tr>
                            <td style="padding: 10px; border-bottom: 1px solid #e2e8f0; font-weight: bold; color: #4a5568;">Extinguished Time:</td>
                            <td style="padding: 10px; border-bottom: 1px solid #e2e8f0; color: #2d3748;">{event.extinguish_time.strftime('%Y-%m-%d %H:%M:%S UTC')}</td>
                        </tr>
                        <tr>
                            <td style="padding: 10px; border-bottom: 1px solid #e2e8f0; font-weight: bold; color: #4a5568;">Response Time:</td>
                            <td style="padding: 10px; border-bottom: 1px solid #e2e8f0; color: #2d3748; font-weight: bold;">{duration_str}</td>
                        </tr>
                        <tr>
                            <td style="padding: 10px; border-bottom: 1px solid #e2e8f0; font-weight: bold; color: #4a5568;">Status:</td>
                            <td style="padding: 10px; border-bottom: 1px solid #e2e8f0; color: #2f855a; font-weight: bold;">EXTINGUISHED</td>
                        </tr>
                    </table>
                    
                    <div style="background-color: #f7fafc; padding: 15px; border-radius: 5px; margin-bottom: 20px;">
                        <h3 style="margin: 0 0 10px 0; color: #2d3748;">Post-Incident Actions:</h3>
                        <ul style="margin: 0; padding-left: 20px; color: #4a5568;">
                            <li>Verify the area is completely safe</li>
                            <li>Check for any remaining hot spots</li>
                            <li>Document the incident for records</li>
                            <li>Inspect fire fighting equipment</li>
                        </ul>
                    </div>
                    
                    <div style="text-align: center;">
                        <p style="margin: 0; color: #718096; font-size: 14px;">This is an automated notification from the Fire Fighting Bot System.</p>
                    </div>
                </div>
            </div>
        </body>
        </html>
        """
        
        # Send email in background thread
        thread = threading.Thread(target=send_async_email, args=(app, msg))
        thread.start()
        print(f"Fire extinguished email sent for event {event.id}")
        
    except Exception as e:
        print(f"Error sending fire extinguished email: {e}")


# --- 5. API ENDPOINTS (ROUTES) ---
@app.route('/')
def index():
    """Dashboard home page"""
    return render_template('index.html')

@app.route('/api')
def api_info():
    """API information endpoint"""
    return "Fire Alert System Backend API is running."

@app.route('/fire_alert', methods=['GET'])
def fire_alert():
    """
    API endpoint to log a new fire alert.
    Creates a new Event record with the current time and 'active' status.
    """
    try:
        # Create a new Event object. Defaults handle the time and status.
        new_event = Event()
        db.session.add(new_event)
        db.session.commit()
        
        print(f"SUCCESS: New fire alert logged with ID: {new_event.id} at {new_event.fire_alert_time}")
        
        # Send email notification
        send_fire_alert_email(new_event)
        
        return jsonify({
            'status': 'success',
            'message': 'New fire alert logged.',
            'event': new_event.to_dict()
        }), 201
    except Exception as e:
        db.session.rollback()
        print(f"ERROR: Could not log fire alert. {e}")
        return jsonify({'status': 'error', 'message': 'Could not log fire alert.'}), 500


@app.route('/fire_extinguished', methods=['GET'])
def fire_extinguished():
    """
    API endpoint to mark the current fire as extinguished.
    Finds the most recent 'active' event and updates its status and time.
    """
    try:
        # Find the most recent 'active' event using a query
        active_event = Event.query.filter_by(status='active').order_by(Event.fire_alert_time.desc()).first()

        if not active_event:
            print("ERROR: 'Extinguished' signal received, but no active fire found.")
            return jsonify({
                'status': 'error',
                'message': 'No active fire event found to extinguish.'
            }), 404
        
        # Update the event's status and extinguish time
        active_event.status = 'extinguished'
        active_event.extinguish_time = datetime.utcnow()
        db.session.commit()
        
        print(f"SUCCESS: Fire event ID {active_event.id} marked as extinguished.")
        
        # Send email notification
        send_fire_extinguished_email(active_event)
        
        return jsonify({
            'status': 'success',
            'message': f'Fire event {active_event.id} marked as extinguished.',
            'event': active_event.to_dict()
        }), 200
    except Exception as e:
        db.session.rollback()
        print(f"ERROR: Could not update event. {e}")
        return jsonify({'status': 'error', 'message': 'Could not update event.'}), 500


@app.route('/events', methods=['GET'])
def get_events():
    """
    Endpoint to retrieve all fire events.
    """
    events = Event.query.order_by(Event.id.desc()).all()
    events_list = [event.to_dict() for event in events]
    return jsonify(events_list), 200


@app.route('/status', methods=['GET'])
def get_status():
    """
    Bonus endpoint to check the status of the most recent event.
    """
    latest_event = Event.query.order_by(Event.id.desc()).first()

    if not latest_event:
        return jsonify({'status': 'no_events', 'message': 'No events logged yet.'}), 404

    return jsonify(latest_event.to_dict()), 200


# --- 6. SCRIPT EXECUTION ---

# Create database tables if they don't exist
with app.app_context():
    db.create_all()

# This block allows running the app directly using `python app.py`
# However, using `flask run` is recommended for development.
if __name__ == '__main__':
    # Makes the server accessible on your local network so the ESP32 can reach it
    app.run(host='0.0.0.0', port=5000, debug=True)