from __future__ import annotations

import hashlib
import json
from pathlib import Path
from urllib.parse import quote

from fastapi import HTTPException
from fastapi.responses import FileResponse, Response


BUSINESS_LEDGER_DEFAULT_SOURCE_KEY = "business_ledger_default"


def sync_default_business_ledger_source(cur, incoming_files_dir: Path, served_dir: Path) -> None:
    cur.execute("SELECT to_regclass('public.integration_binary_sources') IS NOT NULL AS table_exists")
    row = cur.fetchone()
    table_exists = bool(row["table_exists"]) if row is not None else False
    if not table_exists:
        return

    business_dashboard_dir = incoming_files_dir / "사업관리대장"
    business_ledger_served_dir = served_dir / "ledger"
    candidates = [
        business_ledger_served_dir / "사업관리대장-1.xlsx",
        business_dashboard_dir / "사업관리대장-1.xlsx",
        business_dashboard_dir / "사업관리 대장-1.xlsx",
        business_dashboard_dir / "사업관리대장.xlsx",
        business_dashboard_dir / "사업관리 대장.xlsx",
    ]
    source_path = next((candidate for candidate in candidates if candidate.exists()), None)
    if source_path is None:
        return

    content = source_path.read_bytes()
    content_sha256 = hashlib.sha256(content).hexdigest()
    meta_json = {
        "byte_size": len(content),
        "source_path": str(source_path),
        "synced_from": "startup",
    }
    cur.execute(
        """
        INSERT INTO integration_binary_sources (
            source_key, source_name, filename, mime_type, content, content_sha256, meta_json, imported_at
        )
        VALUES (%s, %s, %s, %s, %s, %s, %s::jsonb, NOW())
        ON CONFLICT (source_key) DO UPDATE
        SET source_name = EXCLUDED.source_name,
            filename = EXCLUDED.filename,
            mime_type = EXCLUDED.mime_type,
            content = EXCLUDED.content,
            content_sha256 = EXCLUDED.content_sha256,
            meta_json = EXCLUDED.meta_json,
            imported_at = NOW()
        WHERE integration_binary_sources.content_sha256 IS DISTINCT FROM EXCLUDED.content_sha256
           OR integration_binary_sources.filename IS DISTINCT FROM EXCLUDED.filename
           OR integration_binary_sources.mime_type IS DISTINCT FROM EXCLUDED.mime_type
           OR integration_binary_sources.meta_json IS DISTINCT FROM EXCLUDED.meta_json
        """,
        (
            BUSINESS_LEDGER_DEFAULT_SOURCE_KEY,
            "사업관리대장 기본 원본",
            source_path.name,
            "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            content,
            content_sha256,
            json.dumps(meta_json, ensure_ascii=False),
        ),
    )


def build_business_ledger_default_response(cur) -> Response:
    cur.execute(
        """
        SELECT filename, mime_type, content
        FROM integration_binary_sources
        WHERE source_key = %s
        ORDER BY imported_at DESC
        LIMIT 1
        """,
        (BUSINESS_LEDGER_DEFAULT_SOURCE_KEY,),
    )
    row = cur.fetchone()
    if not row:
        raise HTTPException(status_code=404, detail="Business ledger default source not found.")

    filename = str(row["filename"] or "사업관리대장-1.xlsx")
    headers = {
        "Content-Disposition": 'inline; filename="business-ledger-default.xlsx"',
        "X-Source-Filename": "business-ledger-default.xlsx",
        "X-Original-Filename": quote(filename),
        "Cache-Control": "no-store, no-cache, must-revalidate, max-age=0",
        "Pragma": "no-cache",
    }
    return Response(
        content=bytes(row["content"]),
        media_type=str(
            row["mime_type"] or "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
        ),
        headers=headers,
    )


def build_ledger_index_response(ledger_index_path: Path) -> FileResponse:
    if not ledger_index_path.exists():
        raise HTTPException(status_code=404, detail="Business ledger integration file not found.")
    response = FileResponse(ledger_index_path)
    response.headers["Cache-Control"] = "no-store, no-cache, must-revalidate, max-age=0"
    response.headers["Pragma"] = "no-cache"
    return response
