import { Component, Input, OnInit, ViewChild } from '@angular/core'; import { DialogRef, DialogContentBase, DialogService } from '@progress/kendo-angular-dialog'; import { GridComponent, GridDataResult } from '@progress/kendo-angular-grid'; import { State } from '@progress/kendo-data-query'; import { first } from 'rxjs/operators'; import { BossFightProfile, BossFightPhaseBuff } from '../../massive-darkness2.db.model'; import { MobSkillType } from '../../massive-darkness2.model.boss'; import { MD2BossFightProfileService, MD2PhaseBuffService } from '../../service/massive-darkness2.service'; import { MsgBoxService } from '../../../../services/msg-box.service'; import { MD2PhaseBuffEditorComponent } from '../md2-phase-buff-editor/md2-phase-buff-editor.component'; import { MD2IconPickerDlgComponent } from '../../md2-html-editor/md2-icon-picker-dlg.component'; @Component({ selector: 'ngx-md2-boss-fight-editor', templateUrl: './md2-boss-fight-editor.component.html', styleUrls: ['./md2-boss-fight-editor.component.scss'] }) export class MD2BossFightEditorComponent extends DialogContentBase implements OnInit { @Input() public data: BossFightProfile; @Input() public mobInfoId: string; @ViewChild('phaseBuffsGrid') phaseBuffsGrid: GridComponent; public model: BossFightProfile; public phaseBuffs: BossFightPhaseBuff[] = []; public phaseBuffsData: GridDataResult = { data: [], total: 0 }; public phaseBuffsState: State = { skip: 0, take: 10, sort: [], filter: { logic: 'and', filters: [] } }; public isLoading: boolean = false; public processing: boolean = false; constructor( public dialog: DialogRef, private dialogService: DialogService, private bossFightProfileService: MD2BossFightProfileService, private phaseBuffService: MD2PhaseBuffService, private msgBoxService: MsgBoxService ) { super(dialog); } ngOnInit(): void { this.initializeModel(); } public initializeModel(): void { this.model = { id: this.data?.id || '', mobInfoId: this.mobInfoId || this.data?.mobInfoId || '', prerequisite: this.data?.prerequisite || '', objective: this.data?.objective || '', specialRules: this.data?.specialRules || '', extraTokenName: this.data?.extraTokenName || '', extraTokenHtml: this.data?.extraTokenHtml || '', extraTokenName2: this.data?.extraTokenName2 || '', extraTokenHtml2: this.data?.extraTokenHtml2 || '', phaseBuffs: this.data?.phaseBuffs || [] }; this.phaseBuffs = this.model.phaseBuffs || []; this.loadPhaseBuffs(); } public loadPhaseBuffs(): void { this.phaseBuffsData = { data: this.phaseBuffs.sort((a, b) => a.phase - b.phase), total: this.phaseBuffs.length }; } public addPhaseBuffHandler(): void { if (!this.model) return; const lastPhaseBuff = this.phaseBuffs.length > 0 ? this.phaseBuffs.reduce((prev, current) => (prev.phase > current.phase) ? prev : current) : null; const nextPhase = lastPhaseBuff ? lastPhaseBuff.phase + 1 : 1; const newPhaseBuff: BossFightPhaseBuff = { id: this.generatePhaseBuffId(), bossFightProfileId: this.model.id, phase: nextPhase, extraAction: 0, extraAttackDice: { type: MobSkillType.Attack, yellow: null, orange: null, red: null, blue: null, green: null, black: null }, extraDefenceDice: { type: MobSkillType.Defense, yellow: null, orange: null, red: null, blue: null, green: null, black: null }, extraHp: 0, extraTokenCount: 0, extraTokenCount2: 0, enableExtraBuffDescription: false, extraBuffDescription: '' }; this.openPhaseBuffEditor(newPhaseBuff, true); } public editPhaseBuffHandler(dataItem: BossFightPhaseBuff): void { if (!this.model) return; const phaseBuffCopy: BossFightPhaseBuff = JSON.parse(JSON.stringify(dataItem)); this.openPhaseBuffEditor(phaseBuffCopy, false); } private openPhaseBuffEditor(phaseBuff: BossFightPhaseBuff, isNew: boolean): void { if (!this.model) return; const dialogRef = this.dialogService.open({ title: isNew ? 'Add New Phase Buff' : 'Edit Phase Buff', content: MD2PhaseBuffEditorComponent, width: '80vw', height: 700 }); const editor = dialogRef.content.instance as MD2PhaseBuffEditorComponent; editor.isAdding = isNew; editor.data = phaseBuff; editor.bossFightProfileId = this.model.id; setTimeout(() => { editor.initializeModel(); }, 0); dialogRef.result.subscribe(result => { if (result && typeof result === 'object' && 'id' in result) { this.handlePhaseBuffSaved(result as BossFightPhaseBuff, isNew); } }); } private handlePhaseBuffSaved(result: BossFightPhaseBuff, isNew: boolean): void { if (!this.model) return; if (isNew) { if (!this.phaseBuffs) { this.phaseBuffs = []; } this.phaseBuffs.push(result); } else { const index = this.phaseBuffs.findIndex(p => p.id === result.id); if (index !== -1) { this.phaseBuffs[index] = result; } } this.model.phaseBuffs = this.phaseBuffs; this.loadPhaseBuffs(); } public removePhaseBuffHandler({ dataItem }: { dataItem: BossFightPhaseBuff }): void { this.msgBoxService.showConfirmDeleteBox().pipe(first()).subscribe(answer => { if (answer === true) { this.isLoading = true; this.phaseBuffService.delete(dataItem.id).pipe(first()).subscribe(result => { const index = this.phaseBuffs.findIndex(p => p.id === dataItem.id); if (index !== -1) { this.phaseBuffs.splice(index, 1); this.model.phaseBuffs = this.phaseBuffs; this.loadPhaseBuffs(); } this.isLoading = false; }); } }); } private generatePhaseBuffId(): string { return 'phasebuff_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9); } public close(): void { this.dialog.close(); } public save(): void { if (!this.processing && this.model) { this.processing = true; this.model.phaseBuffs = this.phaseBuffs; this.model.mobInfoId = this.mobInfoId || this.model.mobInfoId; this.bossFightProfileService.createOrUpdate(this.model).pipe(first()).subscribe(result => { this.processing = false; this.dialog.close(result); }, error => { this.processing = false; console.error('Error saving boss fight profile:', error); }); } } showInsertMD2Icon(attributeName: string) { this.dialogService.open({ title: 'Select MD2 Icon', content: MD2IconPickerDlgComponent, width: '800px', height: 600 }).result.subscribe((html: string) => { if (html && typeof html === 'string') { this.model[attributeName] = html; } else { this.model[attributeName] = ''; } }); } public get isValid(): boolean { if (!this.model) { return false; } return this.model.mobInfoId !== ''; } }