import os
import csv
import pandas as pd
from datetime import datetime
from config import EXCEL_EXPORT_DIR
from utils.momo_url_utils import build_momo_product_url, normalize_momo_product_url

class Exporter:
    """
    報表匯出管理器
    負責將數據轉換為 CSV/Excel 格式並儲存至 exports 目錄
    """
    def __init__(self):
        self.export_dir = EXCEL_EXPORT_DIR
        if not os.path.exists(self.export_dir):
            try:
                os.makedirs(self.export_dir)
            except OSError:
                pass

    def _write_csv(self, filename, headers, rows):
        """內部方法：寫入 CSV 檔案 (含 BOM 以支援 Excel 中文顯示)"""
        filepath = os.path.join(self.export_dir, filename)
        try:
            with open(filepath, 'w', newline='', encoding='utf-8-sig') as f:
                writer = csv.writer(f)
                writer.writerow(headers)
                writer.writerows(rows)
            return filepath
        except Exception as e:
            print(f"❌ Export error: {e}")
            return None

    def _safe_product_url(self, product):
        sku = str(getattr(product, 'i_code', '') or '')
        return normalize_momo_product_url(getattr(product, 'url', None), sku) or build_momo_product_url(sku)

    def generate_all_categories_report(self):
        """匯出所有分類商品快照"""
        # 由於 app.py 呼叫此方法時未傳入數據，需自行查詢資料庫
        from database.manager import DatabaseManager
        from database.models import PriceRecord
        from sqlalchemy import func

        db = DatabaseManager()
        session = db.get_session()
        try:
            # 查詢每個商品最新價格
            subq = session.query(func.max(PriceRecord.id).label('max_id')).group_by(PriceRecord.product_id).subquery()
            records = session.query(PriceRecord).join(subq, PriceRecord.id == subq.c.max_id).all()
            
            rows = []
            for r in records:
                rows.append([r.product.category, r.product.name, r.price, self._safe_product_url(r.product), r.timestamp.strftime('%Y-%m-%d %H:%M')])
            
            filename = f"All_Products_{datetime.now().strftime('%Y%m%d_%H%M')}.csv"
            return self._write_csv(filename, ['Category', 'Name', 'Price', 'URL', 'Last Update'], rows)
        finally:
            session.close()

    def generate_price_change_report(self, items):
        """匯出價格異動商品"""
        rows = []
        for item in items:
            rec = item['record']
            diff = item['yesterday_diff']
            rows.append([rec.product.category, rec.product.name, rec.price, diff, self._safe_product_url(rec.product)])
        
        filename = f"Price_Changes_{datetime.now().strftime('%Y%m%d_%H%M')}.csv"
        return self._write_csv(filename, ['Category', 'Name', 'Price', 'Change', 'URL'], rows)

    def generate_low_price_report(self):
        return self._write_csv(f"Low_Price_{datetime.now().strftime('%Y%m%d')}.csv", ['Message'], [['Feature not fully implemented']])

    def generate_custom_report(self, items, title):
        rows = []
        for item in items:
            rec = item['record']
            rows.append([rec.product.category, rec.product.name, rec.price, self._safe_product_url(rec.product)])
        filename = f"{title}_{datetime.now().strftime('%Y%m%d_%H%M')}.csv"
        return self._write_csv(filename, ['Category', 'Name', 'Price', 'URL'], rows)

    def generate_delisted_report(self, items, title):
        rows = []
        for item in items:
            p = item['product']
            price = item['last_price']
            rows.append([p.category, p.name, price, self._safe_product_url(p), "DELISTED"])
        filename = f"{title}_{datetime.now().strftime('%Y%m%d_%H%M')}.csv"
        return self._write_csv(filename, ['Category', 'Name', 'Last Price', 'URL', 'Status'], rows)

    def generate_all_products_excel(self, items):
        """匯出所有商品至 Excel (依分類分頁)"""
        data = []
        for item in items:
            rec = item['record']
            data.append({
                '分類': rec.product.category,
                '商品名稱': rec.product.name,
                '價格': rec.price,
                '連結': self._safe_product_url(rec.product),
                '更新時間': rec.timestamp.strftime('%Y-%m-%d %H:%M')
            })
        
        filename = f"MOMO_All_{datetime.now().strftime('%Y%m%d_%H%M')}.xlsx"
        filepath = os.path.join(self.export_dir, filename)
        
        df = pd.DataFrame(data)
        with pd.ExcelWriter(filepath, engine='openpyxl') as writer:
            for cat, group in df.groupby('分類'):
                sheet_name = str(cat)[:30].replace('/', '_').replace(':', '') # 處理 Excel 工作表名稱限制
                group.to_excel(writer, sheet_name=sheet_name, index=False)
        
        return filepath

    def generate_changes_excel(self, increase, decrease):
        """匯出漲跌商品至 Excel (兩個分頁)"""
        filename = f"MOMO_Changes_{datetime.now().strftime('%Y%m%d_%H%M')}.xlsx"
        filepath = os.path.join(self.export_dir, filename)
        
        with pd.ExcelWriter(filepath, engine='openpyxl') as writer:
            # 漲價
            data_inc = [{'分類': i['record'].product.category, '商品名稱': i['record'].product.name, '價格': i['record'].price, '漲幅': i['yesterday_diff'], '連結': self._safe_product_url(i['record'].product)} for i in increase]
            pd.DataFrame(data_inc).to_excel(writer, sheet_name='漲價商品', index=False)
            
            # 跌價
            data_dec = [{'分類': i['record'].product.category, '商品名稱': i['record'].product.name, '價格': i['record'].price, '跌幅': i['yesterday_diff'], '連結': self._safe_product_url(i['record'].product)} for i in decrease]
            pd.DataFrame(data_dec).to_excel(writer, sheet_name='跌價商品', index=False)
            
        return filepath

    def generate_delisted_excel(self, delisted_items):
        """匯出下架商品至 Excel"""
        filename = f"MOMO_Delisted_{datetime.now().strftime('%Y%m%d_%H%M')}.xlsx"
        filepath = os.path.join(self.export_dir, filename)
        
        data = [{'分類': i['product'].category, '商品名稱': i['product'].name, '最後價格': i['last_price'], '連結': self._safe_product_url(i['product']), '狀態': '下架'} for i in delisted_items]
        
        with pd.ExcelWriter(filepath, engine='openpyxl') as writer:
            pd.DataFrame(data).to_excel(writer, sheet_name='下架商品', index=False)
            
        return filepath
