import { Component, OnInit, inject, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { FormBuilder, 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 { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
import { PageHeaderComponent } from '../../../shared/components/page-header/page-header.component';
import { ConfirmDialogComponent } from '../../../shared/components/confirm-dialog/confirm-dialog.component';
import { DepartmentService } from '../services/department.service';
import { NotificationService } from '../../../core/services/notification.service';
import {
  INPUT_LIMITS,
  noScriptValidator,
  noNullBytesValidator,
  notOnlyWhitespaceValidator,
  phoneValidator,
  strictUrlValidator,
  normalizeWhitespace,
} from '../../../shared/utils/form-validators';
import { createSubmitDebounce } from '../../../shared/utils/form-utils';

@Component({
  selector: 'app-department-form',
  standalone: true,
  imports: [
    CommonModule,
    RouterModule,
    ReactiveFormsModule,
    MatCardModule,
    MatFormFieldModule,
    MatInputModule,
    MatButtonModule,
    MatIconModule,
    MatProgressSpinnerModule,
    MatDialogModule,
    PageHeaderComponent,
  ],
  template: `
    <div class="page-container">
      <app-page-header
        [title]="isEditMode() ? 'Edit Department' : 'Create Department'"
        [subtitle]="isEditMode() ? 'Update department details' : 'Add a new government department'"
      >
        <button mat-button routerLink="/departments">
          <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-grid">
                <mat-form-field appearance="outline">
                  <mat-label>Department Code</mat-label>
                  <input
                    matInput
                    formControlName="code"
                    placeholder="e.g., FIRE_DEPT"
                    [readonly]="isEditMode()"
                    [maxlength]="limits.CODE_MAX"
                  />
                  @if (form.controls.code.hasError('required')) {
                    <mat-error>Code is required</mat-error>
                  }
                  @if (form.controls.code.hasError('pattern')) {
                    <mat-error>Use uppercase letters, numbers, and underscores only</mat-error>
                  }
                  @if (form.controls.code.hasError('maxlength')) {
                    <mat-error>Maximum {{ limits.CODE_MAX }} characters allowed</mat-error>
                  }
                  <mat-hint>Unique identifier ({{ form.controls.code.value?.length || 0 }}/{{ limits.CODE_MAX }})</mat-hint>
                </mat-form-field>

                <mat-form-field appearance="outline">
                  <mat-label>Department Name</mat-label>
                  <input matInput formControlName="name" placeholder="Full department name" [maxlength]="limits.NAME_MAX" />
                  @if (form.controls.name.hasError('required')) {
                    <mat-error>Name is required</mat-error>
                  }
                  @if (form.controls.name.hasError('minlength')) {
                    <mat-error>Minimum {{ limits.NAME_MIN }} characters required</mat-error>
                  }
                  @if (form.controls.name.hasError('maxlength')) {
                    <mat-error>Maximum {{ limits.NAME_MAX }} characters allowed</mat-error>
                  }
                  @if (form.controls.name.hasError('dangerousContent')) {
                    <mat-error>Invalid characters detected</mat-error>
                  }
                </mat-form-field>

                <mat-form-field appearance="outline" class="full-width">
                  <mat-label>Description</mat-label>
                  <textarea
                    matInput
                    formControlName="description"
                    rows="3"
                    placeholder="Brief description of the department"
                    [maxlength]="limits.DESCRIPTION_MAX"
                  ></textarea>
                  @if (form.controls.description.hasError('maxlength')) {
                    <mat-error>Maximum {{ limits.DESCRIPTION_MAX }} characters allowed</mat-error>
                  }
                  @if (form.controls.description.hasError('dangerousContent')) {
                    <mat-error>Invalid characters detected</mat-error>
                  }
                  <mat-hint align="end">{{ form.controls.description.value?.length || 0 }}/{{ limits.DESCRIPTION_MAX }}</mat-hint>
                </mat-form-field>

                <mat-form-field appearance="outline">
                  <mat-label>Contact Email</mat-label>
                  <input
                    matInput
                    formControlName="contactEmail"
                    type="email"
                    placeholder="department@goa.gov.in"
                    [maxlength]="limits.EMAIL_MAX"
                  />
                  @if (form.controls.contactEmail.hasError('email')) {
                    <mat-error>Enter a valid email address</mat-error>
                  }
                  @if (form.controls.contactEmail.hasError('maxlength')) {
                    <mat-error>Email is too long</mat-error>
                  }
                </mat-form-field>

                <mat-form-field appearance="outline">
                  <mat-label>Contact Phone</mat-label>
                  <input
                    matInput
                    formControlName="contactPhone"
                    type="tel"
                    placeholder="+91-XXX-XXXXXXX"
                    [maxlength]="limits.PHONE_MAX"
                  />
                  @if (form.controls.contactPhone.hasError('invalidPhone')) {
                    <mat-error>Enter a valid phone number (6-15 digits)</mat-error>
                  }
                </mat-form-field>

                <mat-form-field appearance="outline" class="full-width">
                  <mat-label>Webhook URL</mat-label>
                  <input
                    matInput
                    formControlName="webhookUrl"
                    placeholder="https://example.com/webhook"
                    [maxlength]="limits.URL_MAX"
                  />
                  @if (form.controls.webhookUrl.hasError('pattern') || form.controls.webhookUrl.hasError('invalidUrl')) {
                    <mat-error>Enter a valid URL (http:// or https://)</mat-error>
                  }
                  @if (form.controls.webhookUrl.hasError('dangerousUrl')) {
                    <mat-error>URL contains unsafe content</mat-error>
                  }
                  @if (form.controls.webhookUrl.hasError('urlTooLong')) {
                    <mat-error>URL is too long (max {{ limits.URL_MAX }} characters)</mat-error>
                  }
                  <mat-hint>URL to receive event notifications</mat-hint>
                </mat-form-field>
              </div>

              <div class="form-actions">
                <button mat-button type="button" routerLink="/departments">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: 800px;
      }

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

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

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

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

  /** Debounce handler to prevent double-click submissions */
  private readonly submitDebounce = createSubmitDebounce(500);

  readonly loading = signal(false);
  readonly submitting = signal(false);
  readonly isEditMode = signal(false);
  private departmentId: string | null = null;

  /** Input limits exposed for template binding */
  readonly limits = INPUT_LIMITS;

  readonly form = this.fb.nonNullable.group({
    code: ['', [
      Validators.required,
      Validators.pattern(/^[A-Z0-9_]+$/),
      Validators.maxLength(INPUT_LIMITS.CODE_MAX),
    ]],
    name: ['', [
      Validators.required,
      Validators.minLength(INPUT_LIMITS.NAME_MIN),
      Validators.maxLength(INPUT_LIMITS.NAME_MAX),
      noScriptValidator(),
      noNullBytesValidator(),
      notOnlyWhitespaceValidator(),
    ]],
    description: ['', [
      Validators.maxLength(INPUT_LIMITS.DESCRIPTION_MAX),
      noScriptValidator(),
      noNullBytesValidator(),
    ]],
    contactEmail: ['', [
      Validators.email,
      Validators.maxLength(INPUT_LIMITS.EMAIL_MAX),
    ]],
    contactPhone: ['', [
      Validators.maxLength(INPUT_LIMITS.PHONE_MAX),
      phoneValidator(),
    ]],
    webhookUrl: ['', [
      strictUrlValidator(false),
    ]],
  });

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

  private loadDepartment(): void {
    if (!this.departmentId) return;

    this.loading.set(true);
    this.departmentService.getDepartment(this.departmentId).subscribe({
      next: (dept) => {
        this.form.patchValue({
          code: dept.code,
          name: dept.name,
          description: dept.description || '',
          contactEmail: dept.contactEmail || '',
          contactPhone: dept.contactPhone || '',
          webhookUrl: dept.webhookUrl || '',
        });
        this.loading.set(false);
      },
      error: () => {
        this.notification.error('Failed to load department');
        this.router.navigate(['/departments']);
      },
    });
  }

  onSubmit(): void {
    // Debounce to prevent double-click submissions
    this.submitDebounce(() => this.performSubmit());
  }

  private performSubmit(): void {
    // Prevent submission if already in progress
    if (this.submitting()) {
      return;
    }

    if (this.form.invalid) {
      this.form.markAllAsTouched();
      return;
    }

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

    // Normalize whitespace in text fields
    const values = {
      code: rawValues.code.trim().toUpperCase(),
      name: normalizeWhitespace(rawValues.name),
      description: normalizeWhitespace(rawValues.description),
      contactEmail: rawValues.contactEmail.trim().toLowerCase(),
      contactPhone: rawValues.contactPhone.trim(),
      webhookUrl: rawValues.webhookUrl.trim(),
    };

    if (this.isEditMode() && this.departmentId) {
      this.departmentService.updateDepartment(this.departmentId, values).subscribe({
        next: () => {
          this.notification.success('Department updated successfully');
          this.router.navigate(['/departments', this.departmentId]);
        },
        error: (err) => {
          this.submitting.set(false);
          this.notification.error(err?.error?.message || 'Failed to update department. Please try again.');
        },
      });
    } else {
      this.departmentService.createDepartment(values).subscribe({
        next: (result) => {
          this.notification.success('Department created successfully');
          // Show credentials dialog
          this.showCredentialsDialog(result.apiKey, result.apiSecret, result.department.id);
        },
        error: (err) => {
          this.submitting.set(false);
          this.notification.error(err?.error?.message || 'Failed to create department. Please try again.');
        },
      });
    }
  }

  private showCredentialsDialog(apiKey: string, apiSecret: string, departmentId: string): void {
    const dialogRef = this.dialog.open(ConfirmDialogComponent, {
      data: {
        title: 'Department Created - Save Your Credentials',
        message: `Please save these credentials securely. The API Secret will not be shown again.\n\n` +
                 `API Key: ${apiKey}\n\n` +
                 `API Secret: ${apiSecret}`,
        confirmText: 'I have saved these credentials',
        confirmColor: 'primary',
        hideCancel: true,
      },
      disableClose: true,
      width: '500px',
    });

    dialogRef.afterClosed().subscribe(() => {
      this.router.navigate(['/departments', departmentId]);
    });
  }
}
