import { Component, inject, signal, computed, OnInit, OnDestroy } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { HttpClient } from '@angular/common/http';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { Subject, debounceTime, Subscription } from 'rxjs';
import { ButtonModule } from 'primeng/button';
import { DialogModule } from 'primeng/dialog';
import { InputTextModule } from 'primeng/inputtext';
import { InputNumberModule } from 'primeng/inputnumber';
import { TextareaModule } from 'primeng/textarea';
import { SelectModule } from 'primeng/select';
import { TabsModule } from 'primeng/tabs';
import { ToggleSwitchModule } from 'primeng/toggleswitch';
import { ToastModule } from 'primeng/toast';
import { ConfirmDialogModule } from 'primeng/confirmdialog';
import { TagModule } from 'primeng/tag';
import { TooltipModule } from 'primeng/tooltip';
import { MessageService, ConfirmationService } from 'primeng/api';
import { Store } from '@ngrx/store';
import { DashboardActions, selectDashboardCompany } from '../../../core/store';
import { PageHeaderComponent } from '../../components/page-header/page-header.component';
import { PrintService } from '../print.service';
import { GENERIC_TEMPLATES, buildFromConfig } from '../print-templates';
import {
  DocumentPrintConfig,
  CustomTemplate,
  CustomTemplateConfig,
  DEFAULT_TEMPLATE_CONFIG,
} from '../print.interfaces';
import { LanguageService } from '../../../core/services/language.service';

// Import all document print configs
import { INVOICE_PRINT_CONFIG } from '../../../features/sales/invoices/invoice-print.config';
import { QUOTATION_PRINT_CONFIG } from '../../../features/sales/quotations/quotation-print.config';
import { ORDER_PRINT_CONFIG } from '../../../features/sales/orders/order-print.config';
import { RETURN_PRINT_CONFIG } from '../../../features/sales/returns/return-print.config';
import { DELIVERY_NOTE_PRINT_CONFIG } from '../../../features/sales/delivery-notes/delivery-note-print.config';
import { PURCHASE_BILL_PRINT_CONFIG } from '../../../features/purchases/bills/bill-print.config';
import { PURCHASE_ORDER_PRINT_CONFIG } from '../../../features/purchases/orders/order-print.config';
import { PURCHASE_RETURN_PRINT_CONFIG } from '../../../features/purchases/returns/return-print.config';
import { PURCHASE_GRN_PRINT_CONFIG } from '../../../features/purchases/grns/grn-print.config';
import { RECEIPT_VOUCHER_PRINT_CONFIG } from '../../../features/accounting/receipt-voucher-print.config';
import { PAYMENT_VOUCHER_PRINT_CONFIG } from '../../../features/accounting/payment-voucher-print.config';
import { CUSTOMER_STATEMENT_PRINT_CONFIG } from '../../../features/sales/customer-statements/customer-statement-print.config';
import { SUPPLIER_STATEMENT_PRINT_CONFIG } from '../../../features/purchases/supplier-statements/supplier-statement-print.config';

interface TemplateCard {
  id: string;
  label_ar: string;
  label_en: string;
  builtIn: boolean;
  base?: string;
}

interface DocTypeGroup {
  labelAr: string;
  labelEn: string;
  icon: string;
  configs: DocumentPrintConfig[];
}

@Component({
  selector: 'app-print-settings',
  standalone: true,
  imports: [
    CommonModule,
    FormsModule,
    TranslateModule,
    ButtonModule,
    DialogModule,
    InputTextModule,
    InputNumberModule,
    TextareaModule,
    SelectModule,
    TabsModule,
    ToggleSwitchModule,
    ToastModule,
    ConfirmDialogModule,
    TagModule,
    TooltipModule,
    PageHeaderComponent,
  ],
  providers: [MessageService, ConfirmationService],
  templateUrl: './print-settings.component.html',
  styleUrl: './print-settings.component.scss',
})
export class PrintSettingsComponent implements OnInit, OnDestroy {
  private printService = inject(PrintService);
  private translate = inject(TranslateService);
  private langService = inject(LanguageService);
  private messageService = inject(MessageService);
  private confirmationService = inject(ConfirmationService);
  private sanitizer = inject(DomSanitizer);
  private store = inject(Store);
  private http = inject(HttpClient);

  // All doc type groups
  docTypeGroups: DocTypeGroup[] = [
    {
      labelAr: 'المبيعات',
      labelEn: 'Sales',
      icon: 'pi pi-shopping-cart',
      configs: [
        INVOICE_PRINT_CONFIG,
        QUOTATION_PRINT_CONFIG,
        ORDER_PRINT_CONFIG,
        RETURN_PRINT_CONFIG,
        DELIVERY_NOTE_PRINT_CONFIG,
        CUSTOMER_STATEMENT_PRINT_CONFIG,
      ],
    },
    {
      labelAr: 'المشتريات',
      labelEn: 'Purchases',
      icon: 'pi pi-truck',
      configs: [
        PURCHASE_BILL_PRINT_CONFIG,
        PURCHASE_ORDER_PRINT_CONFIG,
        PURCHASE_RETURN_PRINT_CONFIG,
        PURCHASE_GRN_PRINT_CONFIG,
        SUPPLIER_STATEMENT_PRINT_CONFIG,
      ],
    },
    {
      labelAr: 'المحاسبة',
      labelEn: 'Accounting',
      icon: 'pi pi-wallet',
      configs: [RECEIPT_VOUCHER_PRINT_CONFIG, PAYMENT_VOUCHER_PRINT_CONFIG],
    },
  ];

  activeDocType = signal<DocumentPrintConfig>(INVOICE_PRINT_CONFIG);
  customTemplates = signal<CustomTemplate[]>([]);
  activeTemplateId = signal<string>('classic');
  private rawPreviewHtml = signal('');
  previewHtml = computed(() => this.sanitizer.bypassSecurityTrustHtml(this.rawPreviewHtml()));
  loading = signal(false);
  saving = signal(false);
  companyInfo = signal<any>(null);
  editing = signal<CustomTemplate | null>(null);

  private previewSubject = new Subject<void>();
  private subs: Subscription[] = [];

  builtInTemplates: TemplateCard[] = Object.entries(GENERIC_TEMPLATES).map(([id, t]) => ({
    id,
    label_ar: t.label_ar,
    label_en: t.label_en,
    builtIn: true,
  }));

  selectedId = signal<string>('classic');

  allTemplates = computed(() => {
    const customs: TemplateCard[] = this.customTemplates().map((t) => ({
      id: t.id,
      label_ar: t.label_ar,
      label_en: t.label_en,
      builtIn: false,
      base: t.base,
    }));
    return [...this.builtInTemplates, ...customs];
  });

  baseOptions = Object.entries(GENERIC_TEMPLATES).map(([id, t]) => ({
    label: t.label_en + ' / ' + t.label_ar,
    value: id,
  }));

  fontOptions = [
    { label: 'Segoe UI', value: "'Segoe UI', Tahoma, Arial, sans-serif" },
    { label: 'Arial', value: 'Arial, Helvetica, sans-serif' },
    { label: 'Georgia', value: "Georgia, 'Times New Roman', serif" },
    { label: 'Courier New', value: "'Courier New', monospace" },
    { label: 'Tahoma', value: 'Tahoma, Geneva, sans-serif' },
    { label: 'Verdana', value: 'Verdana, Geneva, sans-serif' },
  ];

  paperOptions = [
    { label: 'A4', value: 'A4' },
    { label: 'A5', value: 'A5' },
    { label: 'Thermal (80mm)', value: 'Thermal' },
  ];

  // Editor model
  editLabelAr = '';
  editLabelEn = '';
  editBase = 'classic';
  editConfig: CustomTemplateConfig = { ...DEFAULT_TEMPLATE_CONFIG };
  editCustomCss = '';
  editCustomHtml = '';

  isAr = computed(() => this.translate.currentLang === 'ar');

  htmlPlaceholder = `<div class="header">\n  \u007B\u007Bcompany_logo\u007D\u007D\n  <h1>\u007B\u007Bcompany_name\u007D\u007D</h1>\n  <h2>\u007B\u007Bdocument_title\u007D\u007D \u007B\u007Bdocument_number\u007D\u007D</h2>\n</div>\n\u007B\u007Bmeta_grid\u007D\u007D\n\u007B\u007Bitems_table\u007D\u007D\n\u007B\u007Btotals\u007D\u007D`;

  get dialogVisible(): boolean {
    return this.editing() !== null;
  }
  set dialogVisible(val: boolean) {
    if (!val) this.editing.set(null);
  }

  get dialogTitle(): string {
    const e = this.editing();
    if (!e) return '';
    const isExisting = this.customTemplates().some((t) => t.id === e.id);
    return isExisting
      ? this.translate.instant('COMMON.EDIT')
      : this.translate.instant('PRINT_SETTINGS.NEW_TEMPLATE');
  }

  ngOnInit(): void {
    this.loading.set(true);
    this.store.dispatch(DashboardActions.loadCompany());
    this.subs.push(
      this.store.select(selectDashboardCompany).subscribe((c) => {
        if (c) {
          this.companyInfo.set(c);
          if (c.logo) this.loadLogoAsDataUrl(c.logo);
        }
      }),
    );

    this.loadDocTypeSettings(this.activeDocType());

    this.subs.push(
      this.previewSubject.pipe(debounceTime(300)).subscribe(() => this.regenerateEditorPreview()),
    );
  }

  ngOnDestroy(): void {
    this.subs.forEach((s) => s.unsubscribe());
  }

  selectDocType(config: DocumentPrintConfig): void {
    this.activeDocType.set(config);
    this.loadDocTypeSettings(config);
  }

  private loadDocTypeSettings(config: DocumentPrintConfig): void {
    this.loading.set(true);
    this.printService.getActiveTemplate(config.documentType).subscribe({
      next: (id) => {
        this.activeTemplateId.set(id);
        this.selectedId.set(id);
      },
      error: () => {},
    });

    this.printService.getCustomTemplates(config.documentType).subscribe({
      next: (templates) => {
        this.customTemplates.set(templates);
        this.loading.set(false);
        this.regeneratePreviewForId(this.selectedId());
      },
      error: () => this.loading.set(false),
    });
  }

  selectTemplate(id: string): void {
    this.selectedId.set(id);
    this.regeneratePreviewForId(id);
  }

  regeneratePreviewForId(id: string): void {
    const config = this.activeDocType();
    const company = this.companyInfo();
    const html = this.printService.renderPreview(config, id, this.customTemplates(), company);
    this.rawPreviewHtml.set(html);
  }

  private loadLogoAsDataUrl(url: string): void {
    this.http.get(url, { responseType: 'blob' }).subscribe({
      next: (blob) => {
        const reader = new FileReader();
        reader.onload = () => {
          const dataUrl = reader.result as string;
          const current = this.companyInfo();
          if (current) {
            this.companyInfo.set({ ...current, logo: dataUrl });
            this.regeneratePreviewForId(this.selectedId());
          }
        };
        reader.readAsDataURL(blob);
      },
      error: () => {
        const current = this.companyInfo();
        if (current) this.companyInfo.set({ ...current, logo: '' });
      },
    });
  }

  cloneTemplate(baseId: string): void {
    const base = GENERIC_TEMPLATES[baseId];
    const ct: CustomTemplate = {
      id: 'custom_' + Date.now(),
      label_ar: (base?.label_ar || baseId) + ' - نسخة',
      label_en: (base?.label_en || baseId) + ' - Copy',
      base: baseId,
      config: { ...DEFAULT_TEMPLATE_CONFIG },
      customCss: '',
      customBodyHtml: '',
    };
    this.openEditor(ct);
  }

  createNew(): void {
    const ct: CustomTemplate = {
      id: 'custom_' + Date.now(),
      label_ar: 'قالب مخصص',
      label_en: 'Custom Template',
      base: 'classic',
      config: { ...DEFAULT_TEMPLATE_CONFIG },
      customCss: '',
      customBodyHtml: '',
    };
    this.openEditor(ct);
  }

  editTemplate(id: string): void {
    const ct = this.customTemplates().find((t) => t.id === id);
    if (ct) this.openEditor({ ...ct, config: { ...ct.config } });
  }

  private openEditor(ct: CustomTemplate): void {
    this.editing.set(ct);
    this.editLabelAr = ct.label_ar;
    this.editLabelEn = ct.label_en;
    this.editBase = ct.base;
    this.editConfig = { ...ct.config };
    this.editCustomCss = ct.customCss;
    this.editCustomHtml = ct.customBodyHtml;
    this.triggerPreviewUpdate();
  }

  triggerPreviewUpdate(): void {
    this.previewSubject.next();
  }

  private regenerateEditorPreview(): void {
    const ct = this.editing();
    if (!ct) return;

    const current: CustomTemplate = {
      ...ct,
      label_ar: this.editLabelAr,
      label_en: this.editLabelEn,
      base: this.editBase,
      config: { ...this.editConfig },
      customCss: this.editCustomCss,
      customBodyHtml: this.editCustomHtml,
    };

    const config = this.activeDocType();
    const t = (key: string) => this.translate.instant(key);
    const isRtl = this.translate.currentLang === 'ar';
    const data = config.sampleData(t);
    data.dir = isRtl ? 'rtl' : 'ltr';
    data.lang = isRtl ? 'ar' : 'en';
    data.t = t;
    const company = this.companyInfo();
    if (company) data.company = company;

    const html = buildFromConfig(current, data, false);
    this.rawPreviewHtml.set(html);
  }

  saveTemplate(): void {
    const ct = this.editing();
    if (!ct) return;

    this.saving.set(true);
    const updated: CustomTemplate = {
      ...ct,
      label_ar: this.editLabelAr,
      label_en: this.editLabelEn,
      base: this.editBase,
      config: { ...this.editConfig },
      customCss: this.editCustomCss,
      customBodyHtml: this.editCustomHtml,
    };

    const list = [...this.customTemplates()];
    const idx = list.findIndex((t) => t.id === updated.id);
    if (idx >= 0) {
      list[idx] = updated;
    } else {
      list.push(updated);
    }

    this.printService
      .saveCustomTemplates(this.activeDocType().documentType, list)
      .subscribe({
        next: () => {
          this.customTemplates.set(list);
          this.editing.set(null);
          this.saving.set(false);
          this.selectedId.set(updated.id);
          this.regeneratePreviewForId(updated.id);
          this.messageService.add({
            severity: 'success',
            summary: this.translate.instant('COMMON.SUCCESS'),
            detail: this.translate.instant('COMMON.SAVED'),
          });
        },
        error: (err) => {
          this.saving.set(false);
          this.messageService.add({
            severity: 'error',
            summary: this.translate.instant('COMMON.ERROR'),
            detail: err.error?.message || 'Save failed',
          });
        },
      });
  }

  deleteTemplate(id: string): void {
    this.confirmationService.confirm({
      message: this.translate.instant('COMMON.CONFIRM_DELETE'),
      accept: () => {
        const list = this.customTemplates().filter((t) => t.id !== id);
        this.printService
          .saveCustomTemplates(this.activeDocType().documentType, list)
          .subscribe({
            next: () => {
              this.customTemplates.set(list);
              if (this.selectedId() === id) this.selectTemplate('classic');
              this.messageService.add({
                severity: 'success',
                summary: this.translate.instant('COMMON.SUCCESS'),
                detail: this.translate.instant('COMMON.DELETED'),
              });
            },
          });
      },
    });
  }

  setAsDefault(id: string): void {
    this.printService.setActiveTemplate(this.activeDocType().documentType, id).subscribe({
      next: () => {
        this.activeTemplateId.set(id);
        this.messageService.add({
          severity: 'success',
          summary: this.translate.instant('COMMON.SUCCESS'),
          detail: this.translate.instant('COMMON.SAVED'),
        });
      },
    });
  }

  closeEditor(): void {
    this.editing.set(null);
    const sel = this.selectedId();
    if (sel) this.regeneratePreviewForId(sel);
  }

  getTemplateLabel(t: TemplateCard): string {
    return this.isAr() ? t.label_ar : t.label_en;
  }

  getDocTypeLabel(config: DocumentPrintConfig): string {
    return this.isAr() ? config.labelAr : config.labelEn;
  }

  getGroupLabel(group: DocTypeGroup): string {
    return this.isAr() ? group.labelAr : group.labelEn;
  }
}
