/** * EntitySelectionStep.vue - Entity selection step component * * Extracted
from GiftedDialog.vue to handle the complete step 1 * entity selection interface
with dynamic labeling and grid display. * * Features: * - Dynamic step labeling
based on context * - EntityGrid integration for unified entity display * -
Conflict detection and prevention * - Special entity handling (You, Unnamed) * -
Cancel functionality * - Event delegation for entity selection * - Warning
notifications for conflicted entities * - Template streamlined with computed CSS
properties * * @author Matthew Raymer */
<template>
  <div id="sectionGiftedGiver">
    <label class="block font-bold mb-1">
      {{ stepLabel }}
    </label>
    <!-- Toggle link for entity type selection -->
    <div class="text-right mb-4">
      <button
        type="button"
        class="text-sm text-blue-600 hover:text-blue-800 underline font-medium"
        @click="handleToggleEntityType"
      >
        {{ toggleLinkText }}
      </button>
    </div>

    <EntityGrid
      :entity-type="shouldShowProjects ? 'projects' : 'people'"
      :entities="shouldShowProjects ? projects || undefined : allContacts"
      :active-did="activeDid"
      :all-my-dids="allMyDids"
      :all-contacts="allContacts"
      :conflict-checker="conflictChecker"
      :you-selectable="youSelectable"
      :notify="notify"
      :conflict-context="conflictContext"
      @entity-selected="handleEntitySelected"
    />

    <button :class="cancelButtonClasses" @click="handleCancel">Cancel</button>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue, Emit } from "vue-facing-decorator";
import EntityGrid from "./EntityGrid.vue";
import { Contact } from "../db/tables/contacts";
import { PlanData } from "../interfaces/records";
import { NotificationIface } from "../constants/app";

/**
 * Entity data interface for giver/receiver
 */
interface EntityData {
  did?: string;
  handleId?: string;
  name?: string;
  image?: string;
}

/**
 * Entity selection event data structure
 */
interface EntitySelectionEvent {
  type: "person" | "project";
  data: Contact | PlanData;
}

/**
 * EntitySelectionStep - Complete step 1 entity selection interface
 *
 * Features:
 * - Dynamic step labeling based on context
 * - EntityGrid integration for unified entity display
 * - Conflict detection and prevention
 * - Special entity handling (You, Unnamed)
 * - Cancel functionality
 * - Event delegation for entity selection
 * - Warning notifications for conflicted entities
 * - Template streamlined with computed CSS properties
 */
@Component({
  components: {
    EntityGrid,
  },
})
export default class EntitySelectionStep extends Vue {
  /** Type of step: 'giver' or 'recipient' */
  @Prop({ required: true })
  stepType!: "giver" | "recipient";

  /** Array of available projects (optional - EntityGrid loads internally if not provided) */
  @Prop({ required: false })
  projects?: PlanData[];

  /** Array of available contacts */
  @Prop({ required: true })
  allContacts!: Contact[];

  /** Active user's DID */
  @Prop({ required: true })
  activeDid!: string;

  /** All user's DIDs */
  @Prop({ required: true })
  allMyDids!: string[];

  /** Function to check if a DID would create a conflict */
  @Prop({ required: true })
  conflictChecker!: (did: string) => boolean;

  /** Project ID for context (giver) */
  @Prop({ default: "" })
  fromProjectId!: string;

  /** Project ID for context (recipient) */
  @Prop({ default: "" })
  toProjectId!: string;

  /** Current giver entity for context */
  @Prop()
  giver?: EntityData | null;

  /** Current receiver entity for context */
  @Prop()
  receiver?: EntityData | null;

  /** Form field values to preserve when navigating to "Show All" */
  @Prop({ default: "" })
  description!: string;

  @Prop({ default: "0" })
  amountInput!: string;

  @Prop({ default: "HUR" })
  unitCode!: string;

  /** Offer ID for context when fulfilling an offer */
  @Prop({ default: "" })
  offerId!: string;

  /** Notification function from parent component */
  @Prop()
  notify?: (notification: NotificationIface, timeout?: number) => void;

  // initializing based on a Prop doesn't work here; see "mounted()"
  newGiverEntityType: "person" | "project" = "person";
  newRecipientEntityType: "person" | "project" = "person";

  /**
   * CSS classes for the cancel button
   */
  get cancelButtonClasses(): string {
    return "block w-full text-center text-md uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-lg";
  }

  /**
   * Computed step label based on context
   */
  get stepLabel(): string {
    if (this.stepType === "recipient") {
      if (this.shouldShowProjects) {
        return "Choose recipient project";
      } else {
        return "Choose recipient person";
      }
    } else {
      // this.stepType === "giver"
      if (this.shouldShowProjects) {
        return "Choose giving project";
      } else {
        return "Choose giving person";
      }
    }
  }

  /**
   * Computed conflict context for better error messages
   */
  get conflictContext(): string {
    if (this.stepType === "giver") {
      return "recipient";
    } else {
      return "giver";
    }
  }

  /**
   * Whether to show projects in the grid
   */
  get shouldShowProjects(): boolean {
    if (this.stepType === "giver") {
      return this.newGiverEntityType === "project";
    } else if (this.stepType === "recipient") {
      return this.newRecipientEntityType === "project";
    }
    return false;
  }

  /**
   * Whether the "You" entity is selectable
   */
  get youSelectable(): boolean {
    return !this.conflictChecker(this.activeDid);
  }

  /**
   * Text for the toggle link
   */
  get toggleLinkText(): string {
    if (this.shouldShowProjects) {
      return "... or choose a person instead →";
    } else {
      return "... or choose a project instead →";
    }
  }

  async mounted(): Promise<void> {
    this.newGiverEntityType = this.giver?.handleId ? "project" : "person";
    this.newRecipientEntityType = this.receiver?.handleId
      ? "project"
      : "person";
  }

  /**
   * Handle entity selection from EntityGrid
   */
  handleEntitySelected(event: EntitySelectionEvent): void {
    this.emitEntitySelected({
      stepType: this.stepType,
      ...event,
    });
  }

  /**
   * Handle toggle entity type button click
   */
  handleToggleEntityType(): void {
    if (this.stepType === "giver") {
      this.newGiverEntityType =
        this.newGiverEntityType === "person" ? "project" : "person";
    } else if (this.stepType === "recipient") {
      this.newRecipientEntityType =
        this.newRecipientEntityType === "person" ? "project" : "person";
    }
  }

  /**
   * Handle cancel button click
   */
  handleCancel(): void {
    this.emitCancel();
  }

  // Emit methods using @Emit decorator

  @Emit("entity-selected")
  emitEntitySelected(
    data: EntitySelectionEvent & { stepType: string },
  ): EntitySelectionEvent & { stepType: string } {
    return data;
  }

  @Emit("cancel")
  emitCancel(): void {
    // No return value needed
  }
}
</script>

<style scoped>
/* Component-specific styles if needed */
</style>
