/** Dialog for creating/editing a maintenance group. */

import { css, html, LitElement, nothing } from "lit";
import { property, state } from "lit/decorators.js";

import { t, langOf } from "../styles";
import { describeWsError } from "../ws-errors";
import "./ms-textfield";
import type {
  GroupTaskRef,
  HomeAssistant,
  MaintenanceGroup,
  MaintenanceObjectResponse,
} from "../types";

export class MaintenanceGroupDialog extends LitElement {
  @property({ attribute: false }) public hass!: HomeAssistant;
  @property({ attribute: false }) public objects: MaintenanceObjectResponse[] = [];

  @state() private _open = false;
  @state() private _loading = false;
  @state() private _error = "";
  @state() private _groupId: string | null = null; // null = create
  @state() private _name = "";
  @state() private _description = "";
  @state() private _selected: Set<string> = new Set(); // "entry_id:task_id"

  private get _lang(): string {
    return langOf(this.hass);
  }

  public openCreate(): void {
    this._reset();
    this._open = true;
  }

  public openEdit(groupId: string, group: MaintenanceGroup): void {
    this._reset();
    this._groupId = groupId;
    this._name = group.name;
    this._description = group.description || "";
    this._selected = new Set(group.task_refs.map((r) => `${r.entry_id}:${r.task_id}`));
    this._open = true;
  }

  private _reset(): void {
    this._groupId = null;
    this._name = "";
    this._description = "";
    this._selected = new Set();
    this._error = "";
  }

  private _close(): void {
    this._open = false;
  }

  private _toggleTask = (entryId: string, taskId: string): void => {
    const key = `${entryId}:${taskId}`;
    const next = new Set(this._selected);
    if (next.has(key)) next.delete(key);
    else next.add(key);
    this._selected = next;
  };

  private _buildTaskRefs(): GroupTaskRef[] {
    return [...this._selected].map((k) => {
      const [entry_id, task_id] = k.split(":", 2);
      return { entry_id, task_id };
    });
  }

  private _save = async (): Promise<void> => {
    const name = this._name.trim();
    if (!name) {
      this._error = t("group_name_required", this._lang);
      return;
    }
    this._loading = true;
    this._error = "";
    try {
      const task_refs = this._buildTaskRefs();
      if (this._groupId) {
        await this.hass.connection.sendMessagePromise({
          type: "maintenance_supporter/group/update",
          group_id: this._groupId,
          name,
          description: this._description,
          task_refs,
        });
      } else {
        await this.hass.connection.sendMessagePromise({
          type: "maintenance_supporter/group/create",
          name,
          description: this._description,
          task_refs,
        });
      }
      this._open = false;
      this.dispatchEvent(new CustomEvent("group-saved"));
    } catch (e) {
      this._error = describeWsError(e, this._lang, t("save_error", this._lang));
    } finally {
      this._loading = false;
    }
  };

  render() {
    if (!this._open) return html``;
    const L = this._lang;
    const title = this._groupId ? t("edit_group", L) : t("new_group", L);

    return html`
      <ha-dialog open @closed=${this._close} heading="${title}">
        <div class="content">
          ${this._error ? html`<div class="error">${this._error}</div>` : nothing}
          <ms-textfield
            label="${t("name", L)}"
            required
            .value=${this._name}
            @input=${(e: Event) => (this._name = (e.target as HTMLInputElement).value)}
          ></ms-textfield>
          <ms-textfield
            label="${t("description_optional", L)}"
            .value=${this._description}
            @input=${(e: Event) => (this._description = (e.target as HTMLInputElement).value)}
          ></ms-textfield>

          <div class="section-title">${t("group_select_tasks", L)}</div>
          ${this.objects.length === 0
            ? html`<div class="hint">${t("no_objects", L)}</div>`
            : html`
              <div class="objects">
                ${[...this.objects]
                  .sort((a, b) => a.object.name.localeCompare(b.object.name))
                  .map((obj) => html`
                  <div class="object-block">
                    <div class="object-name">${obj.object.name}</div>
                    ${obj.tasks.length === 0
                      ? html`<div class="hint small">${t("no_tasks_short", L)}</div>`
                      : [...obj.tasks]
                          .sort((a, b) => a.name.localeCompare(b.name))
                          .map((task) => {
                        const key = `${obj.entry_id}:${task.id}`;
                        const checked = this._selected.has(key);
                        return html`
                          <label class="task-row">
                            <input type="checkbox"
                              .checked=${checked}
                              @change=${() => this._toggleTask(obj.entry_id, task.id)} />
                            <span>${task.name}</span>
                          </label>
                        `;
                      })}
                  </div>
                `)}
              </div>
            `}
          <div class="selected-count">
            ${t("selected", L)}: ${this._selected.size}
          </div>
        </div>
        <div class="dialog-actions">
          <ha-button appearance="plain" @click=${this._close}>
            ${t("cancel", L)}
          </ha-button>
          <ha-button @click=${this._save} .disabled=${this._loading || !this._name.trim()}>
            ${this._loading ? t("saving", L) : t("save", L)}
          </ha-button>
        </div>
      </ha-dialog>
    `;
  }

  static styles = css`
    .content {
      display: flex;
      flex-direction: column;
      gap: 12px;
      min-width: min(360px, calc(100vw - 24px));
      max-width: 520px;
      max-height: 60vh;
      overflow-y: auto;
    }
    @media (max-width: 600px) {
      .content {
        min-width: 0;
        max-width: none;
        max-height: none;
      }
    }
    ha-textfield { display: block; }
    .error {
      color: var(--error-color, #f44336);
      font-size: 13px;
    }
    .section-title {
      font-size: 14px;
      font-weight: 500;
      margin-top: 8px;
      padding-bottom: 4px;
      border-bottom: 1px solid var(--divider-color);
    }
    .hint {
      color: var(--secondary-text-color);
      font-size: 13px;
    }
    .hint.small { font-size: 12px; padding-left: 12px; }
    .objects { display: flex; flex-direction: column; gap: 8px; }
    .object-block {
      border: 1px solid var(--divider-color);
      border-radius: 6px;
      padding: 8px;
    }
    .object-name {
      font-weight: 500;
      font-size: 13px;
      margin-bottom: 4px;
    }
    .task-row {
      display: flex;
      align-items: center;
      gap: 8px;
      padding: 3px 0;
      font-size: 13px;
      cursor: pointer;
    }
    .task-row input { cursor: pointer; }
    .selected-count {
      font-size: 12px;
      color: var(--secondary-text-color);
    }
    .dialog-actions {
      display: flex;
      justify-content: flex-end;
      gap: 8px;
      padding-top: 16px;
    }
  `;
}

if (!customElements.get("maintenance-group-dialog")) {
  customElements.define("maintenance-group-dialog", MaintenanceGroupDialog);
}
