import io
from typing import List, Dict, Any
from datetime import datetime
from openpyxl import Workbook
from openpyxl.styles import Font, Alignment, PatternFill, Border, Side
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4, landscape
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from sqlalchemy.orm import Session
from app.models.dit import DitRecord
from app.models.sample import SampleRecord
from app.models.order import OrderRecord
from app.models.match import MatchResult, MatchStatus, TargetType
from app.routers.lab import fetch_no_dit_samples, fetch_high_qty_no_order_samples

class ReportGenerator:
    def __init__(self, db: Session):
        self.db = db

    def get_attribution_data(self) -> List[Dict[str, Any]]:
        """取得歸因明細資料"""
        dit_records = self.db.query(DitRecord).all()
        result = []

        for dit in dit_records:
            row = {
                'op_id': dit.op_id,
                'customer': dit.customer,
                'pn': dit.pn,
                'eau': dit.eau,
                'stage': dit.stage,
                'sample_order': None,
                'order_no': None,
                'order_status': None,
                'order_amount': None
            }

            # 找到已接受的樣品匹配
            sample_match = self.db.query(MatchResult).filter(
                MatchResult.dit_id == dit.id,
                MatchResult.target_type == TargetType.SAMPLE,
                MatchResult.status.in_([MatchStatus.accepted, MatchStatus.auto_matched])
            ).first()

            if sample_match:
                sample = self.db.query(SampleRecord).filter(
                    SampleRecord.id == sample_match.target_id
                ).first()
                if sample:
                    row['sample_order'] = sample.order_no

            # 找到已接受的訂單匹配
            order_match = self.db.query(MatchResult).filter(
                MatchResult.dit_id == dit.id,
                MatchResult.target_type == TargetType.ORDER,
                MatchResult.status.in_([MatchStatus.accepted, MatchStatus.auto_matched])
            ).first()

            if order_match:
                order = self.db.query(OrderRecord).filter(
                    OrderRecord.id == order_match.target_id
                ).first()
                if order:
                    row['order_no'] = order.order_no
                    row['order_status'] = order.status if order.status else None
                    row['order_amount'] = order.amount

            result.append(row)

        return result

    def generate_excel(self) -> io.BytesIO:
        """產生 Excel 報表 (包含三個分頁：DIT歸因明細, 成功送樣, 取得訂單)"""
        wb = Workbook()
        
        # 取得所有資料
        all_data = self.get_attribution_data()
        
        # 定義樣式
        header_font = Font(bold=True, color="FFFFFF")
        header_fill = PatternFill(start_color="4F46E5", end_color="4F46E5", fill_type="solid")
        header_alignment = Alignment(horizontal="center", vertical="center")
        
        headers = ['OP編號', '客戶名稱', '料號', 'EAU', '階段', '樣品單號', '訂單單號', '訂單狀態', '訂單金額']
        column_widths = [15, 30, 20, 12, 15, 15, 15, 12, 12]

        def create_sheet(sheet_name, data_rows):
            if sheet_name == "DIT歸因明細":
                 ws = wb.active
                 ws.title = sheet_name
            else:
                 ws = wb.create_sheet(title=sheet_name)

            # 表頭
            for col, header in enumerate(headers, 1):
                cell = ws.cell(row=1, column=col, value=header)
                cell.font = header_font
                cell.fill = header_fill
                cell.alignment = header_alignment

            # 資料
            for row_idx, row_data in enumerate(data_rows, 2):
                ws.cell(row=row_idx, column=1, value=row_data['op_id'])
                ws.cell(row=row_idx, column=2, value=row_data['customer'])
                ws.cell(row=row_idx, column=3, value=row_data['pn'])
                ws.cell(row=row_idx, column=4, value=row_data['eau'])
                ws.cell(row=row_idx, column=5, value=row_data['stage'])
                ws.cell(row=row_idx, column=6, value=row_data['sample_order'] or '-')
                ws.cell(row=row_idx, column=7, value=row_data['order_no'] or '-')
                ws.cell(row=row_idx, column=8, value=row_data['order_status'] or '-')
                ws.cell(row=row_idx, column=9, value=row_data['order_amount'] or 0)

            # 調整欄寬
            for col, width in enumerate(column_widths, 1):
                ws.column_dimensions[chr(64 + col)].width = width

        # 1. DIT歸因明細 (全部)
        create_sheet("DIT歸因明細", all_data)

        # 2. 成功送樣 (有樣品單號)
        success_samples = [row for row in all_data if row['sample_order']]
        create_sheet("成功送樣", success_samples)

        # 3. 取得訂單 (有訂單單號)
        orders_received = [row for row in all_data if row['order_no']]
        create_sheet("取得訂單", orders_received)

        # 4. 未歸因大額樣品 (New)
        no_dit_samples = fetch_no_dit_samples(self.db)
        if no_dit_samples:
             ws = wb.create_sheet(title="未歸因大額樣品")
             # Header
             sub_headers = ['樣品單號', '客戶名稱', '料號', '送樣日期', '數量', '建議']
             for col, header in enumerate(sub_headers, 1):
                 cell = ws.cell(row=1, column=col, value=header)
                 cell.font = header_font
                 cell.fill = header_fill
                 
             # Data
             for row_idx, s in enumerate(no_dit_samples, 2):
                 ws.cell(row=row_idx, column=1, value=s.order_no or s.sample_id)
                 ws.cell(row=row_idx, column=2, value=s.customer)
                 ws.cell(row=row_idx, column=3, value=s.pn)
                 ws.cell(row=row_idx, column=4, value=s.date)
                 ws.cell(row=row_idx, column=5, value=s.qty)
                 ws.cell(row=row_idx, column=6, value="請檢查 DIT 歸因")
                 
             # Widths
             ws.column_dimensions['B'].width = 30
             ws.column_dimensions['C'].width = 20

        # 5. 大額無單樣品 (New)
        high_qty_no_order = fetch_high_qty_no_order_samples(self.db)
        if high_qty_no_order:
             ws = wb.create_sheet(title="大額無單樣品")
             # Header
             sub_headers = ['樣品單號', '客戶名稱', '料號', '送樣日期', '數量', '送樣天數', '狀態']
             for col, header in enumerate(sub_headers, 1):
                 cell = ws.cell(row=1, column=col, value=header)
                 cell.font = header_font
                 cell.fill = header_fill
                 
             # Data
             for row_idx, s in enumerate(high_qty_no_order, 2):
                 ws.cell(row=row_idx, column=1, value=s.order_no or s.sample_id)
                 ws.cell(row=row_idx, column=2, value=s.customer)
                 ws.cell(row=row_idx, column=3, value=s.pn)
                 ws.cell(row=row_idx, column=4, value=s.date)
                 ws.cell(row=row_idx, column=5, value=s.qty)
                 ws.cell(row=row_idx, column=6, value=s.days_since_sent)
                 ws.cell(row=row_idx, column=7, value="高投入無回報")

             # Widths
             ws.column_dimensions['B'].width = 30
             ws.column_dimensions['C'].width = 20

        # 儲存到 BytesIO
        output = io.BytesIO()
        wb.save(output)
        output.seek(0)
        return output

    def generate_pdf(self) -> io.BytesIO:
        """產生 PDF 報表"""
        output = io.BytesIO()
        doc = SimpleDocTemplate(output, pagesize=landscape(A4))
        elements = []

        styles = getSampleStyleSheet()

        # 標題
        title = Paragraph("DIT Attribution Report", styles['Title'])
        elements.append(title)
        elements.append(Spacer(1, 20))

        # 日期
        date_text = Paragraph(f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M')}", styles['Normal'])
        elements.append(date_text)
        elements.append(Spacer(1, 20))

        # 表格資料
        data = self.get_attribution_data()

        table_data = [['OP No.', 'Customer', 'P/N', 'EAU', 'Stage', 'Sample', 'Order', 'Status', 'Amount']]

        for row in data:
            table_data.append([
                row['op_id'],
                row['customer'][:20] + '...' if len(row['customer']) > 20 else row['customer'],
                row['pn'],
                str(row['eau']),
                row['stage'] or '-',
                row['sample_order'] or '-',
                row['order_no'] or '-',
                row['order_status'] or '-',
                f"${row['order_amount']:,.0f}" if row['order_amount'] else '-'
            ])

        # 建立表格
        table = Table(table_data)
        table.setStyle(TableStyle([
            ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#4F46E5')),
            ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('FONTSIZE', (0, 0), (-1, 0), 10),
            ('FONTSIZE', (0, 1), (-1, -1), 8),
            ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
            ('BACKGROUND', (0, 1), (-1, -1), colors.beige),
            ('GRID', (0, 0), (-1, -1), 1, colors.black),
            ('ROWBACKGROUNDS', (0, 1), (-1, -1), [colors.white, colors.HexColor('#F8FAFC')]),
        ]))

        elements.append(table)

        doc.build(elements)
        output.seek(0)
        return output
