/**
 * 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)
 * - Show All navigation with context preservation
 * - 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-4">
      {{ stepLabel }}
    </label>

    <EntityGrid
      :entity-type="shouldShowProjects ? 'projects' : 'people'"
      :entities="shouldShowProjects ? projects : allContacts"
      :max-items="10"
      :active-did="activeDid"
      :all-my-dids="allMyDids"
      :all-contacts="allContacts"
      :conflict-checker="conflictChecker"
      :show-you-entity="shouldShowYouEntity"
      :you-selectable="youSelectable"
      :show-all-route="showAllRoute"
      :show-all-query-params="showAllQueryParams"
      :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" | "special";
  entityType?: string;
  data: Contact | PlanData | EntityData;
}

/**
 * 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)
 * - Show All navigation with context preservation
 * - 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";

  /** Type of giver entity: 'person' or 'project' */
  @Prop({ required: true })
  giverEntityType!: "person" | "project";

  /** Type of recipient entity: 'person' or 'project' */
  @Prop({ required: true })
  recipientEntityType!: "person" | "project";

  /** Whether to show projects instead of people */
  @Prop({ default: false })
  showProjects!: boolean;

  /** Whether this is from a project view */
  @Prop({ default: false })
  isFromProjectView!: boolean;

  /** Array of available projects */
  @Prop({ required: true })
  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;

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

  /**
   * 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") {
      return "Choose who received the gift:";
    } else if (this.stepType === "giver") {
      if (this.shouldShowProjects) {
        return "Choose a project benefitted from:";
      } else {
        return "Choose a person received from:";
      }
    }
    return "Choose entity:";
  }

  /**
   * 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 {
    // When editing an entity, show the appropriate entity type for that entity
    if (this.stepType === "giver") {
      return this.giverEntityType === "project";
    } else if (this.stepType === "recipient") {
      return this.recipientEntityType === "project";
    }
    return false;
  }

  /**
   * Whether to show the "You" entity
   */
  get shouldShowYouEntity(): boolean {
    return (
      this.stepType === "recipient" ||
      (this.stepType === "giver" && this.isFromProjectView)
    );
  }

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

  /**
   * Route name for "Show All" navigation
   */
  get showAllRoute(): string {
    if (this.shouldShowProjects) {
      return "discover";
    } else if (this.allContacts.length > 0) {
      return "contact-gift";
    }
    return "";
  }

  /**
   * Query parameters for "Show All" navigation
   */
  get showAllQueryParams(): Record<string, string> {
    if (this.shouldShowProjects) {
      return {};
    }

    return {
      stepType: this.stepType,
      giverEntityType: this.giverEntityType,
      recipientEntityType: this.recipientEntityType,
      ...(this.stepType === "giver"
        ? {
            recipientProjectId: this.toProjectId || "",
            recipientProjectName: this.receiver?.name || "",
            recipientProjectImage: this.receiver?.image || "",
            recipientProjectHandleId: this.receiver?.handleId || "",
            recipientDid: this.receiver?.did || "",
          }
        : {
            giverProjectId: this.fromProjectId || "",
            giverProjectName: this.giver?.name || "",
            giverProjectImage: this.giver?.image || "",
            giverProjectHandleId: this.giver?.handleId || "",
            giverDid: this.giver?.did || "",
          }),
      fromProjectId: this.fromProjectId,
      toProjectId: this.toProjectId,
      showProjects: this.showProjects.toString(),
      isFromProjectView: this.isFromProjectView.toString(),
    };
  }

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

  /**
   * 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>
