# -*- coding: utf-8 -*-
"""
Wildlife Sound Locator — Bilingual Excel Template (VI / EN).

Exports a structured Excel template with:
    - Sheet "Data": 20-column bilingual header for field data entry
    - Sheet "Species": Full species reference catalog
    - Sheet "Guide": Instructions for filling the template

Imports filled Excel templates back into the plugin's data table.

Author: Lộc Vũ Trung (LVT) / Slow Forest
License: GPL-3.0
"""

import datetime

from .species_data import (
    SPECIES_DB, GROUPS, HABITATS, TERRAINS,
    WEATHER_CONDITIONS, WIND_DIRECTIONS, COUNT_OPTIONS,
)


# ── Column definitions (bilingual) ──────────────────────────────

COLUMNS = [
    ("STT\nNo.", "observer_id", 12),
    ("Kinh độ\nLongitude", "longitude", 16),
    ("Vĩ độ\nLatitude", "latitude", 16),
    ("Góc phương vị (°)\nBearing (°)", "bearing_deg", 18),
    ("Cự ly (m)\nDistance (m)", "distance_m", 14),
    ("Sai số góc (±°)\nAngle error (±°)", "error_angle_deg", 18),
    ("Sai số cự ly (%)\nDist. error (%)", "error_distance_pct", 18),
    ("Độ cao (m)\nElevation (m)", "elevation_m", 14),
    ("Hiện trạng rừng\nHabitat", "habitat", 24),
    ("Địa hình\nTerrain", "terrain", 18),
    ("Nhóm loài\nSpecies group", "species_group", 20),
    ("Tên loài (VN)\nSpecies (VN)", "species_vn", 24),
    ("Tên khoa học\nScientific name", "species_sci", 24),
    ("Số lượng\nCount", "count", 14),
    ("Ngày giờ\nDatetime", "datetime", 20),
    ("Người khảo sát\nSurveyor", "surveyor", 20),
    ("Tuyến tuần tra\nPatrol route", "patrol_route", 18),
    ("Thời tiết\nWeather", "weather", 18),
    ("Hướng gió\nWind direction", "wind_dir", 18),
    ("Ghi chú\nNotes", "notes", 30),
]

COLUMN_KEYS = [c[1] for c in COLUMNS]


def export_template(filepath):
    """Export a bilingual Excel template for field data entry.

    Args:
        filepath: Output .xlsx file path.

    Returns:
        True on success, raises on error.
    """
    try:
        from openpyxl import Workbook
        from openpyxl.styles import (
            Font, PatternFill, Alignment, Border, Side
        )
    except ImportError:
        raise ImportError(
            "openpyxl is required. Install: pip install openpyxl")

    wb = Workbook()

    # ── Sheet 1: Data ───────────────────────────────────────────
    ws = wb.active
    ws.title = "Data"

    # Header styles
    header_fill = PatternFill("solid", fgColor="1B5E20")
    header_font = Font(name="Arial", size=10, bold=True, color="FFFFFF")
    header_align = Alignment(
        horizontal="center", vertical="center", wrap_text=True)
    thin_border = Border(
        left=Side(style="thin"),
        right=Side(style="thin"),
        top=Side(style="thin"),
        bottom=Side(style="thin"))

    for col_idx, (header, _, width) in enumerate(COLUMNS, 1):
        cell = ws.cell(row=1, column=col_idx, value=header)
        cell.font = header_font
        cell.fill = header_fill
        cell.alignment = header_align
        cell.border = thin_border
        ws.column_dimensions[
            chr(64 + col_idx) if col_idx <= 26
            else f"A{chr(64 + col_idx - 26)}"
        ].width = width

    # Set row height for wrapped header
    ws.row_dimensions[1].height = 36

    # Add sample row
    sample = [
        "OBS001", 105.234567, 18.456789, 135, 300, 15, 30,
        450, HABITATS[0], TERRAINS[1], GROUPS[0],
        "Vượn đen tuyền", "Nomascus concolor", COUNT_OPTIONS[1],
        datetime.datetime.now().strftime("%Y-%m-%d %H:%M"),
        "Nguyễn Văn A", "T-03", WEATHER_CONDITIONS[0],
        WIND_DIRECTIONS[0], "Nghe rõ 2 cá thể kêu đồng loạt",
    ]
    light_fill = PatternFill("solid", fgColor="E8F5E9")
    for col_idx, val in enumerate(sample, 1):
        cell = ws.cell(row=2, column=col_idx, value=val)
        cell.fill = light_fill
        cell.border = thin_border
        cell.alignment = Alignment(horizontal="center", vertical="center")

    # Add empty rows (3–50) with borders
    for row in range(3, 51):
        for col_idx in range(1, len(COLUMNS) + 1):
            cell = ws.cell(row=row, column=col_idx)
            cell.border = thin_border

    # Freeze header row
    ws.freeze_panes = "A2"

    # ── Sheet 2: Species ────────────────────────────────────────
    ws2 = wb.create_sheet("Species")
    sp_headers = [
        "Nhóm / Group", "Tên Việt Nam / VN Name",
        "Tên khoa học / Scientific", "IUCN", "NĐ84",
        "Cự ly min (m)", "Cự ly max (m)",
    ]
    for col_idx, h in enumerate(sp_headers, 1):
        cell = ws2.cell(row=1, column=col_idx, value=h)
        cell.font = header_font
        cell.fill = PatternFill("solid", fgColor="0D47A1")
        cell.alignment = header_align
        cell.border = thin_border

    ws2.column_dimensions["A"].width = 22
    ws2.column_dimensions["B"].width = 28
    ws2.column_dimensions["C"].width = 30
    ws2.column_dimensions["D"].width = 8
    ws2.column_dimensions["E"].width = 8
    ws2.column_dimensions["F"].width = 14
    ws2.column_dimensions["G"].width = 14

    row_idx = 2
    for group in GROUPS:
        for sp in SPECIES_DB.get(group, []):
            vn, sci, iucn, nd84, rmin, rmax = sp
            ws2.cell(row=row_idx, column=1, value=group)
            ws2.cell(row=row_idx, column=2, value=vn)
            ws2.cell(row=row_idx, column=3, value=sci)
            ws2.cell(row=row_idx, column=4, value=iucn)
            ws2.cell(row=row_idx, column=5, value=nd84)
            ws2.cell(row=row_idx, column=6, value=rmin)
            ws2.cell(row=row_idx, column=7, value=rmax)
            for c in range(1, 8):
                ws2.cell(row=row_idx, column=c).border = thin_border
                ws2.cell(row=row_idx, column=c).alignment = Alignment(
                    horizontal="center", vertical="center")
            row_idx += 1

    ws2.freeze_panes = "A2"
    ws2.row_dimensions[1].height = 30

    # ── Sheet 3: Guide ──────────────────────────────────────────
    ws3 = wb.create_sheet("Guide")
    ws3.column_dimensions["A"].width = 80
    guide_lines = [
        "HƯỚNG DẪN ĐIỀN MẪU / TEMPLATE GUIDE",
        "",
        "1. Điền dữ liệu vào sheet 'Data' — Fill data in sheet 'Data'",
        "2. Dòng 2 là dữ liệu mẫu, có thể xoá — Row 2 is sample, can delete",
        "3. Toạ độ: WGS-84 (Kinh độ/Vĩ độ thập phân) — Decimal degrees",
        "4. Góc phương vị: 0°=Bắc, 90°=Đông, 180°=Nam, 270°=Tây",
        "   Bearing: 0°=North, 90°=East, 180°=South, 270°=West",
        "5. Cự ly: Ước tính (m) từ vị trí đứng đến nguồn âm",
        "   Distance: Estimated (m) from observer to sound source",
        "6. Sai số góc: Mặc định ±15° — Angle error: default ±15°",
        "7. Sai số cự ly: Mặc định ±30% — Distance error: default ±30%",
        "8. Nhóm loài: Thú / Chim / Lưỡng cư / Bò sát / Côn trùng",
        "   Groups: Mammal / Bird / Amphibian / Reptile / Insect",
        "9. Tham khảo sheet 'Species' để tra tên loài và cự ly",
        "   Refer to 'Species' sheet for species names & ranges",
        "",
        "CÁC GIÁ TRỊ HIỆN TRẠNG / HABITAT VALUES:",
    ] + [f"   - {h}" for h in HABITATS] + [
        "",
        "CÁC GIÁ TRỊ ĐỊA HÌNH / TERRAIN VALUES:",
    ] + [f"   - {t}" for t in TERRAINS] + [
        "",
        "CÁC GIÁ TRỊ THỜI TIẾT / WEATHER VALUES:",
    ] + [f"   - {w}" for w in WEATHER_CONDITIONS] + [
        "",
        "CÁC GIÁ TRỊ HƯỚNG GIÓ / WIND DIRECTION VALUES:",
    ] + [f"   - {d}" for d in WIND_DIRECTIONS]

    guide_font = Font(name="Consolas", size=11)
    title_font = Font(name="Arial", size=13, bold=True, color="1B5E20")
    for i, line in enumerate(guide_lines, 1):
        cell = ws3.cell(row=i, column=1, value=line)
        cell.font = title_font if i == 1 else guide_font

    # ── Save ────────────────────────────────────────────────────
    wb.save(filepath)
    return True


def import_template(filepath):
    """Read a filled Excel template and return list of record dicts.

    Args:
        filepath: Path to .xlsx file.

    Returns:
        List of dicts, each with keys matching COLUMN_KEYS.
    """
    try:
        from openpyxl import load_workbook
    except ImportError:
        raise ImportError(
            "openpyxl is required. Install: pip install openpyxl")

    wb = load_workbook(filepath, read_only=True, data_only=True)
    ws = wb["Data"]

    records = []
    for row_idx, row in enumerate(ws.iter_rows(min_row=2, values_only=True)):
        if row_idx == 0 and row and str(row[0]).startswith("OBS"):
            # Skip sample row if it looks like the default
            pass  # nosec B110
        if not any(row):
            continue  # skip empty rows
        record = {}
        for col_idx, key in enumerate(COLUMN_KEYS):
            val = row[col_idx] if col_idx < len(row) else None
            record[key] = val
        # Validate essential fields
        if record.get("longitude") and record.get("latitude"):
            records.append(record)

    wb.close()
    return records
