import { Component, OnInit, inject, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { FormBuilder, FormArray, ReactiveFormsModule, Validators } from '@angular/forms';
import { MatCardModule } from '@angular/material/card';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { PageHeaderComponent } from '../../../shared/components/page-header/page-header.component';
import { WorkflowService } from '../services/workflow.service';
import { DepartmentService } from '../../departments/services/department.service';
import { NotificationService } from '../../../core/services/notification.service';
import { DepartmentResponseDto } from '../../../api/models';

@Component({
  selector: 'app-workflow-form',
  standalone: true,
  imports: [
    CommonModule,
    RouterModule,
    ReactiveFormsModule,
    MatCardModule,
    MatFormFieldModule,
    MatInputModule,
    MatSelectModule,
    MatButtonModule,
    MatIconModule,
    MatCheckboxModule,
    MatProgressSpinnerModule,
    PageHeaderComponent,
  ],
  template: `
    <div class="page-container">
      <app-page-header
        [title]="isEditMode() ? 'Edit Workflow' : 'Create Workflow'"
        [subtitle]="isEditMode() ? 'Update workflow configuration' : 'Define a new approval workflow'"
      >
        <button mat-button routerLink="/workflows">
          <mat-icon>arrow_back</mat-icon>
          Back
        </button>
      </app-page-header>

      <mat-card class="form-card">
        <mat-card-content>
          @if (loading()) {
            <div class="loading-container">
              <mat-spinner diameter="48"></mat-spinner>
            </div>
          } @else {
            <form [formGroup]="form" (ngSubmit)="onSubmit()">
              <div class="form-section">
                <h3>Basic Information</h3>
                <div class="form-grid">
                  <mat-form-field appearance="outline">
                    <mat-label>Workflow Name</mat-label>
                    <input matInput formControlName="name" placeholder="e.g., Resort License Workflow" />
                    @if (form.controls.name.hasError('required')) {
                      <mat-error>Name is required</mat-error>
                    }
                  </mat-form-field>

                  <mat-form-field appearance="outline">
                    <mat-label>Request Type</mat-label>
                    <mat-select formControlName="requestType">
                      <mat-option value="NEW_LICENSE">New License</mat-option>
                      <mat-option value="RENEWAL">Renewal</mat-option>
                      <mat-option value="AMENDMENT">Amendment</mat-option>
                    </mat-select>
                  </mat-form-field>

                  <mat-form-field appearance="outline" class="full-width">
                    <mat-label>Description</mat-label>
                    <textarea matInput formControlName="description" rows="2"></textarea>
                  </mat-form-field>
                </div>
              </div>

              <div class="form-section">
                <div class="section-header">
                  <h3>Approval Stages</h3>
                  <button mat-button type="button" color="primary" (click)="addStage()">
                    <mat-icon>add</mat-icon>
                    Add Stage
                  </button>
                </div>

                <div formArrayName="stages" class="stages-list">
                  @for (stage of stagesArray.controls; track $index; let i = $index) {
                    <mat-card class="stage-card" [formGroupName]="i">
                      <div class="stage-header">
                        <span class="stage-number">Stage {{ i + 1 }}</span>
                        <button mat-icon-button type="button" (click)="removeStage(i)" [disabled]="stagesArray.length <= 1">
                          <mat-icon>delete</mat-icon>
                        </button>
                      </div>
                      <div class="stage-form">
                        <mat-form-field appearance="outline">
                          <mat-label>Stage Name</mat-label>
                          <input matInput formControlName="name" />
                        </mat-form-field>
                        <mat-form-field appearance="outline">
                          <mat-label>Department</mat-label>
                          <mat-select formControlName="departmentId">
                            @for (dept of departments(); track dept.id) {
                              <mat-option [value]="dept.id">{{ dept.name }}</mat-option>
                            }
                          </mat-select>
                        </mat-form-field>
                        <mat-checkbox formControlName="isRequired">Required</mat-checkbox>
                      </div>
                    </mat-card>
                  }
                </div>
              </div>

              <div class="form-actions">
                <button mat-button type="button" routerLink="/workflows">Cancel</button>
                <button
                  mat-raised-button
                  color="primary"
                  type="submit"
                  [disabled]="form.invalid || submitting()"
                >
                  @if (submitting()) {
                    <mat-spinner diameter="20"></mat-spinner>
                  } @else {
                    {{ isEditMode() ? 'Update' : 'Create' }}
                  }
                </button>
              </div>
            </form>
          }
        </mat-card-content>
      </mat-card>
    </div>
  `,
  styles: [
    `
      .form-card {
        max-width: 900px;
      }

      .loading-container {
        display: flex;
        justify-content: center;
        padding: 48px;
      }

      .form-section {
        margin-bottom: 32px;

        h3 {
          margin: 0 0 16px;
          font-size: 1.125rem;
          font-weight: 500;
        }
      }

      .section-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 16px;

        h3 {
          margin: 0;
        }
      }

      .form-grid {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 16px;
      }

      .full-width {
        grid-column: 1 / -1;
      }

      .stages-list {
        display: flex;
        flex-direction: column;
        gap: 16px;
      }

      .stage-card {
        padding: 16px;
      }

      .stage-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 16px;
      }

      .stage-number {
        font-weight: 500;
        color: #1976d2;
      }

      .stage-form {
        display: grid;
        grid-template-columns: 1fr 1fr auto;
        gap: 16px;
        align-items: center;
      }

      .form-actions {
        display: flex;
        gap: 12px;
        justify-content: flex-end;
        padding-top: 16px;
        border-top: 1px solid #eee;
      }
    `,
  ],
})
export class WorkflowFormComponent implements OnInit {
  private readonly fb = inject(FormBuilder);
  private readonly route = inject(ActivatedRoute);
  private readonly router = inject(Router);
  private readonly workflowService = inject(WorkflowService);
  private readonly departmentService = inject(DepartmentService);
  private readonly notification = inject(NotificationService);

  readonly loading = signal(false);
  readonly submitting = signal(false);
  readonly isEditMode = signal(false);
  readonly departments = signal<DepartmentResponseDto[]>([]);
  private workflowId: string | null = null;

  readonly form = this.fb.nonNullable.group({
    name: ['', [Validators.required]],
    description: [''],
    requestType: ['NEW_LICENSE', [Validators.required]],
    stages: this.fb.array([this.createStageGroup()]),
  });

  get stagesArray(): FormArray {
    return this.form.get('stages') as FormArray;
  }

  ngOnInit(): void {
    this.loadDepartments();
    this.workflowId = this.route.snapshot.paramMap.get('id');
    if (this.workflowId) {
      this.isEditMode.set(true);
      this.loadWorkflow();
    }
  }

  private loadDepartments(): void {
    this.departmentService.getDepartments(1, 100).subscribe({
      next: (response) => {
        this.departments.set(response.data);
      },
    });
  }

  private loadWorkflow(): void {
    if (!this.workflowId) return;

    this.loading.set(true);
    this.workflowService.getWorkflow(this.workflowId).subscribe({
      next: (workflow) => {
        this.form.patchValue({
          name: workflow.name,
          description: workflow.description || '',
          requestType: workflow.requestType,
        });

        this.stagesArray.clear();
        workflow.stages.forEach((stage) => {
          this.stagesArray.push(
            this.fb.group({
              id: [stage.id],
              name: [stage.name, Validators.required],
              departmentId: [stage.departmentId, Validators.required],
              order: [stage.order],
              isRequired: [stage.isRequired],
            })
          );
        });

        this.loading.set(false);
      },
      error: () => {
        this.notification.error('Failed to load workflow');
        this.router.navigate(['/workflows']);
      },
    });
  }

  private createStageGroup() {
    return this.fb.group({
      id: [''],
      name: ['', Validators.required],
      departmentId: ['', Validators.required],
      order: [1],
      isRequired: [true],
    });
  }

  addStage(): void {
    const order = this.stagesArray.length + 1;
    const group = this.createStageGroup();
    group.patchValue({ order });
    this.stagesArray.push(group);
  }

  removeStage(index: number): void {
    if (this.stagesArray.length > 1) {
      this.stagesArray.removeAt(index);
      this.updateStageOrders();
    }
  }

  private updateStageOrders(): void {
    this.stagesArray.controls.forEach((control, index) => {
      control.patchValue({ order: index + 1 });
    });
  }

  onSubmit(): void {
    if (this.form.invalid) return;

    this.submitting.set(true);
    const values = this.form.getRawValue();

    const dto = {
      name: values.name!,
      description: values.description || undefined,
      requestType: values.requestType!,
      stages: values.stages.map((s, i) => ({
        id: s.id || `stage-${i + 1}`,
        name: s.name || `Stage ${i + 1}`,
        departmentId: s.departmentId || '',
        isRequired: s.isRequired ?? true,
        order: i + 1,
      })),
    };

    const action$ = this.isEditMode()
      ? this.workflowService.updateWorkflow(this.workflowId!, dto)
      : this.workflowService.createWorkflow(dto);

    action$.subscribe({
      next: (result) => {
        this.notification.success(
          this.isEditMode() ? 'Workflow updated' : 'Workflow created'
        );
        this.router.navigate(['/workflows', result.id]);
      },
      error: () => {
        this.submitting.set(false);
      },
    });
  }
}
