# -*- coding: utf-8 -*-
"""
Forest Inventory Plot Designer — Main Dialog (Phase 1).

Tab 1: Area & Stratification
Tab 2: Sample Size Calculator

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

import os

from qgis.core import (
    QgsProject, QgsMapLayerProxyModel, QgsDistanceArea, QgsUnitTypes
)
from qgis.PyQt.QtCore import Qt
from qgis.PyQt.QtGui import QIcon, QFont, QColor
from qgis.PyQt.QtWidgets import (
    QDialog, QVBoxLayout, QHBoxLayout, QLabel,
    QPushButton, QTabWidget, QWidget, QGroupBox,
    QGridLayout, QFormLayout, QComboBox, QDoubleSpinBox,
    QTableWidget, QTableWidgetItem, QHeaderView, QMessageBox,
    QFrame, QAbstractItemView
)
from qgis.gui import QgsMapLayerComboBox

from .sample_calculator import (
    StratumConfig, compute_all_strata, T_SQUARED, DEFAULT_ERROR_PCT,
    DEFAULT_CV_PCT
)


def _is_vi(lang):
    return lang == 'vi'


class ForestPlotDialog(QDialog):
    """Forest Inventory Plot Designer — Phase 1 dialog."""

    # Default strata (TT16/2023)
    DEFAULT_STRATA = [
        ("Rừng lá rộng TX giàu", "Rich evergreen broadleaf", "TXG"),
        ("Rừng lá rộng TX trung bình", "Medium evergreen broadleaf", "TXB"),
        ("Rừng lá rộng TX nghèo", "Poor evergreen broadleaf", "TXN"),
        ("Rừng lá rộng TX phục hồi", "Restored evergreen broadleaf", "TXP"),
        ("Rừng rụng lá giàu", "Rich deciduous", "RLG"),
        ("Rừng rụng lá trung bình", "Medium deciduous", "RLB"),
    ]

    def __init__(self, iface, lang='vi', parent=None):
        super().__init__(parent)
        self.iface = iface
        self.lang = lang
        self.plugin_dir = os.path.dirname(
            os.path.dirname(os.path.dirname(__file__)))
        self._results = []
        self._summary = {}
        self._setup_ui()

    # ── Icon helper ──────────────────────────────────────────────
    def _icon(self, name):
        p = os.path.join(self.plugin_dir, 'icons', name)
        return QIcon(p) if os.path.isfile(p) else QIcon()

    # ── Main UI ──────────────────────────────────────────────────
    def _setup_ui(self):
        vi = _is_vi(self.lang)
        self.setWindowTitle(
            '🌲 Ô tiêu chuẩn điều tra rừng — LVT4U' if vi
            else '🌲 Forest Inventory Plot — LVT4U')
        self.setMinimumSize(900, 620)
        self.setWindowIcon(self._icon('bio_forest_plot.svg'))

        root = QVBoxLayout(self)

        # Header
        hdr = QFrame()
        hdr.setStyleSheet(
            "QFrame{background:qlineargradient(x1:0,y1:0,x2:1,y2:0,"
            "stop:0 #1B5E20,stop:1 #2E7D32);border-radius:8px;padding:10px}")
        hl = QHBoxLayout(hdr)
        ic = QLabel()
        ic.setPixmap(self._icon('bio_forest_plot.svg').pixmap(40, 40))
        hl.addWidget(ic)
        t = QLabel('🌲 ' + (
            'Thiết lập ô tiêu chuẩn điều tra rừng' if vi
            else 'Forest Inventory Plot Designer'))
        t.setFont(QFont('Segoe UI', 14, QFont.Bold))
        t.setStyleSheet('color:white')
        hl.addWidget(t, 1)
        root.addWidget(hdr)

        # Tabs
        self.tabs = QTabWidget()
        self.tabs.setStyleSheet(
            "QTabBar::tab{padding:8px 20px;font-size:12px}"
            "QTabBar::tab:selected{background:#E8F5E9;font-weight:bold}")

        self.tab1 = QWidget()
        self.tab2 = QWidget()
        self.tabs.addTab(self.tab1,
                         '📍 Khu vực & Phân tầng' if vi
                         else '📍 Area & Stratification')
        self.tabs.addTab(self.tab2,
                         '📊 Dung lượng mẫu' if vi
                         else '📊 Sample Size')
        root.addWidget(self.tabs, 1)

        self._build_tab1(vi)
        self._build_tab2(vi)

        # Bottom buttons
        blay = QHBoxLayout()
        blay.addStretch()
        self.btn_calc = QPushButton(
            '🔄 Tính toán' if vi else '🔄 Calculate')
        self.btn_calc.setMinimumHeight(36)
        self.btn_calc.setStyleSheet(
            "QPushButton{background:#4CAF50;color:white;border-radius:6px;"
            "padding:6px 24px;font-weight:bold}"
            "QPushButton:hover{background:#388E3C}")
        self.btn_calc.clicked.connect(self._on_calculate)
        blay.addWidget(self.btn_calc)

        self.btn_close = QPushButton('Đóng' if vi else 'Close')
        self.btn_close.setMinimumHeight(36)
        self.btn_close.clicked.connect(self.close)
        blay.addWidget(self.btn_close)
        root.addLayout(blay)

    # ── Tab 1: Area & Stratification ─────────────────────────────
    def _build_tab1(self, vi):
        lay = QVBoxLayout(self.tab1)

        # Layer selection
        g1 = QGroupBox('Khu vực điều tra' if vi else 'Survey Area')
        g1.setStyleSheet(
            "QGroupBox{font-weight:bold;border:1px solid #C8E6C9;"
            "border-radius:6px;margin-top:8px;padding-top:16px}"
            "QGroupBox::title{subcontrol-origin:margin;left:12px}")
        fl = QFormLayout(g1)

        self.cmb_layer = QgsMapLayerComboBox()
        self.cmb_layer.setFilters(QgsMapLayerProxyModel.PolygonLayer)
        self.cmb_layer.setAllowEmptyLayer(True)
        self.cmb_layer.setShowCrs(True)
        fl.addRow('Layer polygon:' if vi else 'Polygon layer:', self.cmb_layer)

        self.lbl_area = QLabel('—')
        self.lbl_area.setStyleSheet('font-weight:bold;color:#1B5E20')
        fl.addRow('Tổng diện tích:' if vi else 'Total area:', self.lbl_area)

        self.lbl_crs = QLabel('—')
        fl.addRow('CRS:', self.lbl_crs)

        self.cmb_layer.layerChanged.connect(self._on_layer_changed)
        lay.addWidget(g1)

        # Strata table
        g2 = QGroupBox(
            'Phân tầng trạng thái rừng' if vi else 'Forest Strata')
        g2.setStyleSheet(g1.styleSheet())
        v2 = QVBoxLayout(g2)

        # Toolbar
        tb = QHBoxLayout()
        self.btn_add = QPushButton('➕')
        self.btn_add.setFixedSize(32, 32)
        self.btn_add.setToolTip('Thêm trạng thái' if vi else 'Add stratum')
        self.btn_add.clicked.connect(self._add_stratum_row)
        tb.addWidget(self.btn_add)

        self.btn_del = QPushButton('➖')
        self.btn_del.setFixedSize(32, 32)
        self.btn_del.setToolTip('Xóa trạng thái' if vi else 'Remove stratum')
        self.btn_del.clicked.connect(self._del_stratum_row)
        tb.addWidget(self.btn_del)

        self.btn_default = QPushButton(
            '📋 Mẫu TT16' if vi else '📋 TT16 Template')
        self.btn_default.setToolTip(
            'Nạp trạng thái mẫu theo TT16 / 2023' if vi
            else 'Load TT16 / 2023 template strata')
        self.btn_default.clicked.connect(self._load_default_strata)
        tb.addWidget(self.btn_default)
        tb.addStretch()
        v2.addLayout(tb)

        # Table
        cols = ['Tên trạng thái', 'Ký hiệu', 'DT (ha)', 'S% (CV)',
                'Loại rừng'] if vi else [
            'Stratum Name', 'Code', 'Area (ha)', 'CV (%)', 'Forest Type']
        self.tbl_strata = QTableWidget(0, 5)
        self.tbl_strata.setHorizontalHeaderLabels(cols)
        self.tbl_strata.horizontalHeader().setSectionResizeMode(
            0, QHeaderView.Stretch)
        for c in range(1, 5):
            self.tbl_strata.horizontalHeader().setSectionResizeMode(
                c, QHeaderView.ResizeToContents)
        self.tbl_strata.setAlternatingRowColors(True)
        self.tbl_strata.setStyleSheet(
            "QTableWidget{gridline-color:#E0E0E0}"
            "QTableWidget::item{padding:4px}")
        v2.addWidget(self.tbl_strata, 1)
        lay.addWidget(g2, 1)

        # Parameters
        g3 = QGroupBox('Tham số' if vi else 'Parameters')
        g3.setStyleSheet(g1.styleSheet())
        fl3 = QFormLayout(g3)

        self.spn_t2 = QDoubleSpinBox()
        self.spn_t2.setRange(1, 16)
        self.spn_t2.setValue(T_SQUARED)
        self.spn_t2.setDecimals(1)
        fl3.addRow('t² (độ tin cậy):' if vi else 't² (confidence):', self.spn_t2)

        self.spn_err = QDoubleSpinBox()
        self.spn_err.setRange(1, 50)
        self.spn_err.setValue(DEFAULT_ERROR_PCT)
        self.spn_err.setSuffix(' %')
        fl3.addRow('Δ% (sai số):' if vi else 'Δ% (error):', self.spn_err)

        lay.addWidget(g3)

    # ── Tab 2: Sample Size Results ───────────────────────────────
    def _build_tab2(self, vi):
        lay = QVBoxLayout(self.tab2)

        # Results table
        g = QGroupBox(
            'Kết quả dung lượng mẫu' if vi else 'Sample Size Results')
        g.setStyleSheet(
            "QGroupBox{font-weight:bold;border:1px solid #C8E6C9;"
            "border-radius:6px;margin-top:8px;padding-top:16px}"
            "QGroupBox::title{subcontrol-origin:margin;left:12px}")
        vg = QVBoxLayout(g)

        rcols = [
            'TT', 'Trạng thái', 'Ký hiệu', 'DT (ha)', 'PP rút mẫu',
            'S%', 'Số ô', 'DT điều tra (ha)', 'Tỷ lệ (%)', 'Công thức'
        ] if vi else [
            '#', 'Stratum', 'Code', 'Area (ha)', 'Method',
            'CV%', 'Plots', 'Survey (ha)', 'Rate (%)', 'Formula'
        ]
        self.tbl_results = QTableWidget(0, 10)
        self.tbl_results.setHorizontalHeaderLabels(rcols)
        self.tbl_results.horizontalHeader().setSectionResizeMode(
            1, QHeaderView.Stretch)
        self.tbl_results.horizontalHeader().setSectionResizeMode(
            9, QHeaderView.Stretch)
        self.tbl_results.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tbl_results.setAlternatingRowColors(True)
        self.tbl_results.setStyleSheet(
            "QTableWidget{gridline-color:#E0E0E0}"
            "QTableWidget::item{padding:4px}")
        vg.addWidget(self.tbl_results, 1)
        lay.addWidget(g, 1)

        # Summary panel
        gs = QGroupBox('Tổng hợp' if vi else 'Summary')
        gs.setStyleSheet(g.styleSheet())
        grid = QGridLayout(gs)

        labels = [
            ('Tổng diện tích:', 'Total area:'),
            ('Tổng số ô mẫu:', 'Total plots:'),
            ('DT điều tra:', 'Survey area:'),
            ('Tỷ lệ rút mẫu:', 'Sampling rate:'),
            ('Ước tính ngày công:', 'Est. work days:'),
            ('Số nhóm × người:', 'Crews × size:'),
        ]
        self.lbl_summary = []
        for i, (lv, le) in enumerate(labels):
            lb = QLabel(lv if vi else le)
            lb.setStyleSheet('font-weight:bold')
            val = QLabel('—')
            val.setStyleSheet('color:#1B5E20;font-size:13px')
            grid.addWidget(lb, i // 3, (i % 3) * 2)
            grid.addWidget(val, i // 3, (i % 3) * 2 + 1)
            self.lbl_summary.append(val)

        lay.addWidget(gs)

    # ── Callbacks ────────────────────────────────────────────────
    def _on_layer_changed(self, layer):
        if not layer:
            self.lbl_area.setText('—')
            self.lbl_crs.setText('—')
            return
        crs = layer.crs()
        self.lbl_crs.setText(f'{crs.authid()} — {crs.description()}')

        da = QgsDistanceArea()
        da.setSourceCrs(crs, QgsProject.instance().transformContext())
        da.setEllipsoid(QgsProject.instance().ellipsoid())

        total = 0.0
        for f in layer.getFeatures():
            geom = f.geometry()
            if not geom.isNull():
                total += da.measureArea(geom)
        total_ha = da.convertAreaMeasurement(
            total, QgsUnitTypes.AreaHectares)
        self.lbl_area.setText(f'{total_ha:,.2f} ha')

    def _add_stratum_row(self):
        r = self.tbl_strata.rowCount()
        self.tbl_strata.insertRow(r)
        self.tbl_strata.setItem(r, 0, QTableWidgetItem(''))
        self.tbl_strata.setItem(r, 1, QTableWidgetItem(''))
        self.tbl_strata.setItem(r, 2, QTableWidgetItem('0'))

        spn = QDoubleSpinBox()
        spn.setRange(1, 100)
        spn.setValue(DEFAULT_CV_PCT)
        spn.setSuffix('%')
        self.tbl_strata.setCellWidget(r, 3, spn)

        cmb = QComboBox()
        vi = _is_vi(self.lang)
        cmb.addItems([
            'Rừng gỗ TN' if vi else 'Natural timber',
            'Tre nứa mọc tản' if vi else 'Bamboo (scattered)',
            'Tre nứa mọc cụm' if vi else 'Bamboo (clump)',
            'Rừng trồng (TT05)' if vi else 'Plantation (TT05)',
            'ĐT tăng trưởng HGĐ (TT33)' if vi else 'Growth Survey (TT33)',
        ])
        self.tbl_strata.setCellWidget(r, 4, cmb)

    def _del_stratum_row(self):
        row = self.tbl_strata.currentRow()
        if row >= 0:
            self.tbl_strata.removeRow(row)

    def _load_default_strata(self):
        self.tbl_strata.setRowCount(0)
        vi = _is_vi(self.lang)
        for name_vi, name_en, code in self.DEFAULT_STRATA:
            self._add_stratum_row()
            r = self.tbl_strata.rowCount() - 1
            self.tbl_strata.item(r, 0).setText(name_vi if vi else name_en)
            self.tbl_strata.item(r, 1).setText(code)
            self.tbl_strata.item(r, 2).setText('0')

    def _read_strata(self):
        """Read strata from table into StratumConfig list."""
        strata = []
        ft_map = {0: 'timber', 1: 'bamboo_scattered',
                  2: 'bamboo_clump', 3: 'plantation',
                  4: 'growth_plantation'}
        for r in range(self.tbl_strata.rowCount()):
            name = (self.tbl_strata.item(r, 0).text()
                    if self.tbl_strata.item(r, 0) else '')
            code = (self.tbl_strata.item(r, 1).text()
                    if self.tbl_strata.item(r, 1) else '')
            try:
                area = float(self.tbl_strata.item(r, 2).text())
            except (ValueError, AttributeError):
                area = 0.0

            cv_w = self.tbl_strata.cellWidget(r, 3)
            cv = cv_w.value() if cv_w else DEFAULT_CV_PCT

            ft_w = self.tbl_strata.cellWidget(r, 4)
            ft = ft_map.get(ft_w.currentIndex() if ft_w else 0, 'timber')

            if name or code:
                strata.append(StratumConfig(name, code, area, cv, ft))
        return strata

    def _on_calculate(self):
        strata = self._read_strata()
        if not strata:
            vi = _is_vi(self.lang)
            QMessageBox.warning(self,
                                'Cảnh báo' if vi else 'Warning',
                                'Chưa có trạng thái rừng nào!'
                                if vi else 'No strata defined!')
            return

        t2 = self.spn_t2.value()
        err = self.spn_err.value()
        results, summary = compute_all_strata(strata, t2, err)
        self._results = results
        self._summary = summary
        self._fill_results_table(results, summary)
        self.tabs.setCurrentIndex(1)

    def _fill_results_table(self, results, summary):
        vi = _is_vi(self.lang)
        self.tbl_results.setRowCount(len(results))

        method_map = {
            'random': 'Ngẫu nhiên' if vi else 'Random',
            'typical': 'Điển hình' if vi else 'Typical',
            'plantation': 'Rừng trồng' if vi else 'Plantation',
            'growth': 'Tăng trưởng (TT33)' if vi else 'Growth (TT33)',
            'n / a': '—',
        }

        for i, r in enumerate(results):
            vals = [
                str(i + 1),
                r['stratum_name'],
                r['stratum_code'],
                f"{r['area_ha']:,.1f}",
                method_map.get(r['method'], '—'),
                f"{r['cv_pct']:.0f}",
                str(r['n_plots']),
                f"{r['survey_area_ha']:.2f}",
                f"{r['sampling_rate_pct']:.3f}",
                r['formula_display'],
            ]
            for j, v in enumerate(vals):
                item = QTableWidgetItem(v)
                if j in (3, 5, 6, 7, 8):
                    item.setTextAlignment(
                        Qt.AlignRight | Qt.AlignVCenter)
                self.tbl_results.setItem(i, j, item)

            # Highlight plot count
            pc = self.tbl_results.item(i, 6)
            if pc:
                pc.setBackground(QColor('#E8F5E9'))
                pc.setFont(QFont('Segoe UI', 10, QFont.Bold))

        # Summary
        s = summary
        vals = [
            f"{s['total_area_ha']:,.2f} ha",
            f"{s['total_plots']} ô",
            f"{s['total_survey_ha']:.2f} ha",
            f"{s['overall_rate_pct']:.3f} %",
            f"{s['est_work_days']} ngày" if vi
            else f"{s['est_work_days']} days",
            f"{s['crews']} × {s['crew_size']}",
        ]
        for i, v in enumerate(vals):
            if i < len(self.lbl_summary):
                self.lbl_summary[i].setText(v)
