"use client";

import { IndicatorParameterForm } from "@/components/chart/IndicatorParameterForm";
import { getIndicator } from "@/lib/indicators/registry";
import type { IndicatorInstance, IndicatorInstanceScope } from "@/lib/indicators/instances/types";
import {
  LEGACY_ANNOTATION_FIXTURE_INSTANCE_ID,
  LEGACY_SMA_INSTANCE_ID,
  LEGACY_SR_FINDER_INSTANCE_ID,
} from "@/lib/indicators/instances/legacy-slots";
import { upsertLegacySlotInstance } from "@/lib/indicators/instances/manager";
import { ANNOTATION_FIXTURE_ID } from "@/lib/indicators/reference/annotation-fixture";
import { SMA_INDICATOR_ID } from "@/lib/indicators/reference/sma";
import { SR_FINDER_2_1_ID } from "@/lib/indicators/tradingbite/sr-finder-2_1";
import { CreateIndicatorAlertModal } from "@/components/alerts/CreateIndicatorAlertModal";
import type { ChartLayoutId } from "@/lib/chart/layout-profile";
import { useCallback, useMemo, useState } from "react";

type ChartIndicatorPanelProps = {
  scope: IndicatorInstanceScope;
  instances: IndicatorInstance[];
  patchInstance: (
    instanceId: string,
    patch: Partial<Pick<IndicatorInstance, "enabled" | "visible" | "parameters">>,
  ) => void;
  replaceInstances: (next: IndicatorInstance[]) => void;
  onIndicatorError?: (message: string | null) => void;
  onOpenCatalog?: () => void;
};

function instanceTitle(inst: IndicatorInstance): string {
  const def = getIndicator(inst.definitionId);
  return def?.name ?? inst.definitionId;
}

export function ChartIndicatorPanel({
  scope,
  instances,
  patchInstance,
  replaceInstances,
  onIndicatorError,
  onOpenCatalog,
}: ChartIndicatorPanelProps) {
  const [expandedId, setExpandedId] = useState<string | null>(null);
  const [alertInstance, setAlertInstance] = useState<IndicatorInstance | null>(null);
  const sorted = useMemo(
    () => [...instances].sort((a, b) => a.createdAt.localeCompare(b.createdAt)),
    [instances],
  );

  const addLegacy = useCallback(
    (
      instanceId: string,
      definitionId: string,
      parameters?: Record<string, unknown>,
    ) => {
      const next = upsertLegacySlotInstance(instances, scope, instanceId, definitionId, {
        enabled: true,
        parameters,
      });
      if ("error" in next) {
        onIndicatorError?.(next.error);
        return;
      }
      onIndicatorError?.(null);
      replaceInstances(next);
      setExpandedId(instanceId);
    },
    [instances, onIndicatorError, replaceInstances, scope],
  );

  return (
    <aside className="chart-indicator-panel" aria-label="Indicators">
      <div className="chart-indicator-panel-head">
        <h2 className="chart-indicator-panel-title">Indicators</h2>
        <button
          type="button"
          className="chart-indicator-panel-link chart-indicator-panel-link-btn"
          onClick={() => onOpenCatalog?.()}
        >
          Catalog
        </button>
      </div>
      <div className="chart-indicator-quick-add">
        <button
          type="button"
          className="toolbar-btn toolbar-btn-sm"
          onClick={() => addLegacy(LEGACY_SMA_INSTANCE_ID, SMA_INDICATOR_ID, { period: 20 })}
        >
          + SMA
        </button>
        <button
          type="button"
          className="toolbar-btn toolbar-btn-sm"
          onClick={() =>
            addLegacy(LEGACY_SR_FINDER_INSTANCE_ID, SR_FINDER_2_1_ID, { useMtf: false })
          }
        >
          + S/R
        </button>
        <button
          type="button"
          className="toolbar-btn toolbar-btn-sm"
          onClick={() =>
            addLegacy(LEGACY_ANNOTATION_FIXTURE_INSTANCE_ID, ANNOTATION_FIXTURE_ID, {
              enabled: true,
            })
          }
        >
          + Annot
        </button>
      </div>
      {sorted.length === 0 ? (
        <p className="chart-indicator-empty">No indicators on this chart. Add from quick actions or the catalog.</p>
      ) : (
        <ul className="chart-indicator-list">
          {sorted.map((inst) => {
            const def = getIndicator(inst.definitionId);
            const open = expandedId === inst.instanceId;
            return (
              <li key={inst.instanceId} className="chart-indicator-item">
                <div className="chart-indicator-item-head">
                  <button
                    type="button"
                    className="chart-indicator-expand"
                    aria-expanded={open}
                    onClick={() =>
                      setExpandedId((id) => (id === inst.instanceId ? null : inst.instanceId))
                    }
                  >
                    <span className="chart-indicator-chevron">{open ? "▾" : "▸"}</span>
                    <span className="chart-indicator-name">{instanceTitle(inst)}</span>
                  </button>
                  <div className="chart-indicator-toggles">
                    <label className="chart-indicator-toggle" title="Enable calculations">
                      <input
                        type="checkbox"
                        checked={inst.enabled}
                        onChange={(e) => {
                          const enabled = e.target.checked;
                          patchInstance(inst.instanceId, {
                            enabled,
                            visible: enabled ? inst.visible : false,
                          });
                        }}
                        aria-label={`Enable ${instanceTitle(inst)}`}
                      />
                      <span>On</span>
                    </label>
                    <label className="chart-indicator-toggle" title="Show on chart">
                      <input
                        type="checkbox"
                        checked={inst.visible}
                        disabled={!inst.enabled}
                        onChange={(e) =>
                          patchInstance(inst.instanceId, { visible: e.target.checked })
                        }
                        aria-label={`Show ${instanceTitle(inst)}`}
                      />
                      <span>Show</span>
                    </label>
                  </div>
                </div>
                {open && def ? (
                  <div className="chart-indicator-item-body">
                    {def.alertConditions?.length ? (
                      <p className="indicator-alert-help">
                        Indicator alerts: enable the indicator, turn on alert conditions in settings
                        (e.g. UHV), then create an alert rule below. Fires while the app is open with
                        sound + notifications.
                      </p>
                    ) : null}
                    {def.alertConditions?.length ? (
                      <button
                        type="button"
                        className="toolbar-btn toolbar-btn-sm"
                        disabled={!inst.enabled}
                        onClick={() => setAlertInstance(inst)}
                      >
                        Create indicator alert
                      </button>
                    ) : null}
                    <IndicatorParameterForm
                      schemas={def.parameters}
                      values={inst.parameters}
                      onChange={(key, value) =>
                        patchInstance(inst.instanceId, {
                          parameters: { ...inst.parameters, [key]: value },
                        })
                      }
                    />
                  </div>
                ) : null}
              </li>
            );
          })}
        </ul>
      )}
      {alertInstance ? (
        <CreateIndicatorAlertModal
          open
          instance={alertInstance}
          layoutId={(scope.layoutId ?? "layout-a") as ChartLayoutId}
          symbol={scope.symbol}
          timeframe={scope.timeframe}
          onClose={() => setAlertInstance(null)}
        />
      ) : null}
    </aside>
  );
}
