import requests

from bs4 import BeautifulSoup

import pandas as pd

import matplotlib.pyplot as plt

import sqlite3

from fpdf import FPDF

import smtplib

from email.mime.multipart import MIMEMultipart

from email.mime.text import MIMEText


# 1. 웹 데이터 수집 및 파싱

def fetch_weather_data(city):

    url = f"https://example.com/weather/{city}"

    response = requests.get(url)

    soup = BeautifulSoup(response.text, 'html.parser')

    

    data = []

    table = soup.find('table')

    rows = table.find_all('tr')

    for row in rows[1:]:

        cols = row.find_all('td')

        cols = [col.text.strip() for col in cols]

        data.append(cols)

    

    df = pd.DataFrame(data, columns=['Date', 'Temperature', 'Humidity', 'Wind'])

    return df


# 2. 데이터 처리 및 분석

def process_weather_data(df):

    df['Date'] = pd.to_datetime(df['Date'])

    df['Temperature'] = pd.to_numeric(df['Temperature'], errors='coerce')

    df['Humidity'] = pd.to_numeric(df['Humidity'], errors='coerce')

    df['Wind'] = pd.to_numeric(df['Wind'], errors='coerce')

    df.dropna(inplace=True)

    weekly_avg = df.resample('W', on='Date').mean().reset_index()

    return weekly_avg


# 3. 데이터 시각화

def visualize_weather_data(df, city):

    plt.figure(figsize=(10, 6))

    plt.plot(df['Date'], df['Temperature'], marker='o', label='Temperature')

    plt.plot(df['Date'], df['Humidity'], marker='s', label='Humidity')

    plt.plot(df['Date'], df['Wind'], marker='^', label='Wind')

    plt.title(f'Weekly Average Weather Data for {city}')

    plt.xlabel('Date')

    plt.ylabel('Values')

    plt.legend()

    plt.grid(True)

    plt.savefig(f'{city}_weather_plot.png')

    plt.show()


# 4. 데이터베이스 저장

def save_to_database(df, city):

    conn = sqlite3.connect('weather_data.db')

    df.to_sql(city, conn, if_exists='replace', index=False)

    conn.close()


# 5. PDF 보고서 생성

class PDF(FPDF):

    def header(self):

        self.set_font('Arial', 'B', 12)

        self.cell(0, 10, 'Weekly Weather Report', 0, 1, 'C')

    

    def footer(self):

        self.set_y(-15)

        self.set_font('Arial', 'I', 8)

        self.cell(0, 10, f'Page {self.page_no()}', 0, 0, 'C')

    

    def chapter_title(self, title):

        self.set_font('Arial', 'B', 12)

        self.cell(0, 10, title, 0, 1, 'L')

        self.ln(5)

    

    def chapter_body(self, body):

        self.set_font('Arial', '', 12)

        self.multi_cell(0, 10, body)

        self.ln()


    def add_chart(self, image_path):

        self.add_page()

        self.image(image_path, x = 10, y = 30, w = 190)


def create_pdf_report(city):

    pdf = PDF()

    pdf.add_page()

    pdf.chapter_title(f'Weekly Weather Report for {city}')

    pdf.chapter_body('This report includes the weekly average weather data.')

    pdf.add_chart(f'{city}_weather_plot.png')

    pdf.output(f'{city}_weather_report.pdf')


# 6. 이메일 발송

def send_email(subject, body, recipient, attachment):

    sender_email = "youremail@example.com"

    sender_password = "yourpassword"

    

    message = MIMEMultipart()

    message['From'] = sender_email

    message['To'] = recipient

    message['Subject'] = subject

    

    message.attach(MIMEText(body, 'plain'))

    

    with open(attachment, 'rb') as file:

        part = MIMEText(file.read(), 'base64', 'pdf')

        part['Content-Disposition'] = f'attachment; filename="{attachment}"'

        message.attach(part)

    

    try:

        server = smtplib.SMTP('smtp.example.com', 587)

        server.starttls()

        server.login(sender_email, sender_password)

        server.sendmail(sender_email, recipient, message.as_string())

        server.quit()

        print("Email sent successfully.")

    except Exception as e:

        print(f"Error: {e}")


# 7. 전체 자동화 워크플로우

def main():

    city = 'Seoul'

    recipient_email = 'recipient@example.com'

    

    print("Fetching weather data...")

    df = fetch_weather_data(city)

    

    print("Processing weather data...")

    weekly_avg = process_weather_data(df)

    

    print("Visualizing weather data...")

    visualize_weather_data(weekly_avg, city)

    

    print("Saving data to database...")

    save_to_database(weekly_avg, city)

    

    print("Creating PDF report...")

    create_pdf_report(city)

    

    print("Sending email...")

    send_email(

        subject='Weekly Weather Report',

        body=f'Please find attached the weekly weather report for {city}.',

        recipient=recipient_email,

        attachment=f'{city}_weather_report.pdf'

    )


if __name__ == "__main__":

    main()