import io
import json

import xlsxwriter
from markupsafe import escape

from odoo import http
from odoo.http import content_disposition, request

# "Leave Remaining Export for Payroll" -- payroll only needs the Remaining
# figure per leave type per employee (not Allocated/Used), in the column
# order Employee Code, Employee, then one "Remaining" column per leave
# type. Reuses the Leave Balances Grid view's already-computed rows
# (leave_balance_action.js's gridRows), same pattern as grid_export.py,
# just a narrower payload/layout.

REMAINING_COLOR = "#206b45"


def _payroll_payload(data):
    payload = json.loads(data)
    return payload.get("leave_types") or [], payload.get("rows") or [], payload.get("year") or ""


class XenoLeavePayrollExport(http.Controller):

    @http.route("/xeno_leave/payroll_export/xlsx", type="http", auth="user")
    def payroll_export_xlsx(self, data):
        leave_types, rows, year = _payroll_payload(data)

        output = io.BytesIO()
        workbook = xlsxwriter.Workbook(output, {"in_memory": True})
        sheet = workbook.add_worksheet("Leave Remaining")

        header_fmt = workbook.add_format({
            "bold": True, "bg_color": "#fafafa", "border": 1,
            "align": "center", "valign": "vcenter",
        })
        code_fmt = workbook.add_format({"border": 1})
        name_fmt = workbook.add_format({"bold": True, "border": 1})
        remaining_fmt = workbook.add_format({
            "border": 1, "align": "right", "font_color": REMAINING_COLOR, "bold": True,
        })

        sheet.merge_range(0, 0, 1, 0, "Employee Code", header_fmt)
        sheet.merge_range(0, 1, 1, 1, "Employee", header_fmt)
        col = 2
        for lt in leave_types:
            # A single column per type -- nothing to merge (merge_range
            # needs more than one cell), so both header rows are just
            # written directly.
            sheet.write(0, col, lt.get("name", ""), header_fmt)
            sheet.write(1, col, "Remaining", header_fmt)
            col += 1
        sheet.set_column(0, 0, 14)
        sheet.set_column(1, 1, 24)
        if leave_types:
            sheet.set_column(2, col - 1, 13)

        r = 2
        for row in rows:
            sheet.write(r, 0, row.get("employeeCode", ""), code_fmt)
            sheet.write(r, 1, row.get("employeeName", ""), name_fmt)
            c = 2
            for cell in row.get("cells", []):
                sheet.write(r, c, cell.get("remainingStr", ""), remaining_fmt)
                c += 1
            r += 1

        sheet.freeze_panes(2, 2)
        workbook.close()
        output.seek(0)

        return request.make_response(
            output.read(),
            headers=[
                ("Content-Type",
                 "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"),
                ("Content-Disposition",
                 content_disposition(f"Leave_Remaining_Payroll_{year}.xlsx")),
            ],
        )

    @http.route("/xeno_leave/payroll_export/pdf", type="http", auth="user")
    def payroll_export_pdf(self, data):
        leave_types, rows, year = _payroll_payload(data)
        html = self._build_html(leave_types, rows, year)

        pdf_content = request.env["ir.actions.report"].sudo()._run_wkhtmltopdf(
            [html], landscape=True)

        return request.make_response(
            pdf_content,
            headers=[
                ("Content-Type", "application/pdf"),
                ("Content-Disposition",
                 content_disposition(f"Leave_Remaining_Payroll_{year}.pdf")),
            ],
        )

    def _build_html(self, leave_types, rows, year):
        type_headers = "".join(
            f'<th>{escape(lt.get("name", ""))}</th>' for lt in leave_types
        )
        sub_headers = "<th>Remaining</th>" * len(leave_types)

        body_rows = []
        for row in rows:
            cells = "".join(
                f'<td class="num remaining">{escape(c.get("remainingStr", ""))}</td>'
                for c in row.get("cells", [])
            )
            body_rows.append(
                f'<tr><td class="code">{escape(row.get("employeeCode", ""))}</td>'
                f'<td class="name">{escape(row.get("employeeName", ""))}</td>{cells}</tr>'
            )

        return f"""<!DOCTYPE html><html><head><meta charset="utf-8"/><style>
            body {{ font-family: Arial, Helvetica, sans-serif; font-size: 11px; }}
            h2 {{ margin: 0 0 12px; color: #1a2b4a; }}
            table {{ border-collapse: collapse; width: 100%; }}
            th, td {{ border: 1px solid #ccc; padding: 4px 8px; }}
            th {{ background: #fafafa; text-align: center; }}
            td.name {{ font-weight: bold; }}
            td.code {{ color: #6b6b6b; }}
            td.num {{ text-align: right; }}
            td.remaining {{ color: {REMAINING_COLOR}; font-weight: bold; }}
        </style></head><body>
            <h2>Leave Remaining Export for Payroll &mdash; {escape(str(year))}</h2>
            <table>
                <thead>
                    <tr><th rowspan="2">Employee Code</th><th rowspan="2">Employee</th>{type_headers}</tr>
                    <tr>{sub_headers}</tr>
                </thead>
                <tbody>{"".join(body_rows)}</tbody>
            </table>
        </body></html>"""
