"""Single source of truth for every canvas color the plugin draws.

The color language, shared by every TerraLab plugin that draws on canvas:
BLUE = AI output, editable/pending. AMBER = the one object being edited now.
GREEN = kept/validated this session. RED = committed to a layer.
CHROME_* = zone/grid/badge scaffolding, a distinct blue tone from data,
never filling large areas. Width is a second cue (active=3) so color is
never the only signal (colorblind safety).

Layering: the QGIS renderer STRINGS ("r,g,b,a") that describe a saved or
under-review layer live in core/layer_conventions.py (core must not import
ui). This module (ui) imports and re-exports them so ui code has one place
to reach for every canvas color, and holds every QColor constant itself.
"""
from __future__ import annotations

from qgis.PyQt.QtGui import QColor

from ..core.layer_conventions import (
    _COMMITTED_RED as _COMMITTED_RED,
)
from ..core.layer_conventions import (
    _REVIEW_FILL as _REVIEW_FILL,
)
from ..core.layer_conventions import (
    _REVIEW_OUTLINE as _REVIEW_OUTLINE,
)

# Data states. Two-color language on the canvas: blue = editable (pending, not
# yet saved), green = validated. The object currently open for editing reuses
# pending-blue and leans on a bolder outline for emphasis, so there is no third
# hue (an earlier amber "active" state read as an unrelated random colour).
PENDING_FILL = QColor(0, 120, 255, 100)
PENDING_STROKE = QColor(0, 80, 200, 255)
PENDING_WIDTH = 2

KEPT_FILL = QColor(0, 200, 100, 60)
KEPT_STROKE = QColor(0, 200, 100, 180)
KEPT_WIDTH = 2

# Renderer strings (QGIS symbol layer properties want "r,g,b,a" strings).
# The three under-review / committed strings are re-exported from core so the
# meaning lives in one place; the outline-display-mode red is a ui-only review
# concern and is defined here.
REVIEW_FILL_STR = _REVIEW_FILL
REVIEW_OUTLINE_STR = _REVIEW_OUTLINE
COMMITTED_OUTLINE_STR = _COMMITTED_RED
OUTLINE_MODE_STROKE_STR = "227,26,28,255"

# Chrome (zone / grid / badge / draw tool)
CHROME_BLUE = QColor(66, 133, 244)
ZONE_FILL = QColor(66, 133, 244, 18)
ZONE_STROKE = QColor(66, 133, 244, 200)
ZONE_DRAW_FILL = QColor(66, 133, 244, 55)
ZONE_DRAW_LINE = QColor(66, 133, 244, 235)
GRID_LINE = QColor(40, 99, 196, 210)
# Ground a run is re-reading at a finer scale right now. Its objects are held
# back until that finer read lands, so without this the densest part of a zone
# is bare while the run works hardest on it. Chrome blue, well under the zone
# fill: it marks work in progress, it must not read as a detection.
RESCAN_FILL = QColor(66, 133, 244, 34)
RESCAN_STROKE = QColor(66, 133, 244, 120)
BADGE_FILL = QColor(66, 133, 244)
BADGE_FILL_DISABLED = QColor(66, 133, 244, 115)
BADGE_FILL_HOVER = QColor(211, 47, 47)          # BRAND_RED on hover = deletion affordance
BADGE_X = QColor(255, 255, 255)
CLOSE_DOT_OK = QColor(34, 197, 94)
CLOSE_DOT_WARN = QColor(255, 213, 0)

# Setup-time helpers
EXEMPLAR_FILL = QColor(67, 160, 71, 60)
EXEMPLAR_STROKE = QColor(67, 160, 71)
EXCLUDE_FILL = QColor(229, 57, 53, 60)
EXCLUDE_STROKE = QColor(229, 57, 53)

# Hand edits in the review's Correct step (merge picks, the split cut line).
# The shared language's AMBER: it marks the object being edited RIGHT NOW, and
# it is wider (3) so the cue is never colour alone. It lives only while the
# gesture is armed, so this stays a transient state, not the persistent amber
# that was rejected above.
SHAPE_HOVER_STROKE = QColor(66, 133, 244)
SHAPE_HOVER_WIDTH = 3
SHAPE_EDIT_STROKE = QColor(255, 179, 0)
SHAPE_EDIT_WIDTH = 3
# Fill of the small vertex dots on the split cut line. White reads on any
# basemap under the amber outline; a named constant keeps it out of the tool.
SHAPE_EDIT_MARKER_FILL = QColor(255, 255, 255)

# The polygons a correction session is NOT working on. While one polygon is
# open for a fix, every other one on the review layer drops to this grey and
# stops answering clicks, so the map holds one thing to look at. Grey rather
# than hidden: the neighbours are the context needed to judge the shape being
# fixed, they just stop competing with it. The alphas are a floor, not a taste:
# under about 60 the fill washes out on dark imagery and the polygon reads as
# deleted. Renderer strings, because the layers that wear them take QGIS symbol
# properties.
SESSION_DIM_FILL_STR = "150,150,150,90"
SESSION_DIM_STROKE_STR = "230,230,230,190"

# The outline that follows the cursor before any click. Pending-blue, because
# it is the same AI output the click keeps, one step earlier. Well under
# PENDING_FILL on purpose: nothing has been chosen yet, so it must read as a
# ghost of a suggestion, with the imagery still legible through it, never as a
# selection the user made. The alpha sits at the dim-fill floor above which a
# tint still reads on dark imagery; below it the rim alone would carry the
# shape. The edge is a light pending-family stroke, so the shape stays readable
# over dark imagery where the fill alone washes out. Its alpha sits one step
# above the fill's old rim because the dashed stroke below carries less ink
# than a solid line.
HOVER_PREVIEW_FILL = QColor(0, 120, 255, 60)
HOVER_PREVIEW_EDGE = QColor(120, 200, 255, 235)
# Every stroked ghost outline is DASHED: the broken line is the "not saved
# yet" cue, against the solid stroke every kept shape wears. The pattern is in
# pen widths (Qt's dash unit), 3 on then 2 off, so at the 2 px cosmetic width
# below a dash is 6 px and a gap 4 px: broken at a glance, still one shape.
HOVER_PREVIEW_DASH_PATTERN = (3.0, 2.0)
HOVER_PREVIEW_OUTLINE_WIDTH = 2.0

# Click markers (manual maptool)
MARKER_POSITIVE = QColor(0, 200, 0)
MARKER_NEGATIVE = QColor(220, 0, 0)
