import {
  Controller,
  Get,
  Post,
  Put,
  Patch,
  Query,
  Body,
  Param,
} from '@nestjs/common';
import { PageSeoMetadataService } from './page_seo_metadata.service';
import { PageSeoAuditService } from './page_seo_audit.service';
import { Public } from '../auth/public.decorator';

@Controller('seo')
export class PageSeoMetadataController {
  constructor(
    private readonly pageSeoMetadataService: PageSeoMetadataService,
    private readonly auditService: PageSeoAuditService,
  ) {}

  /**
   * Endpoint: GET /api/seo
   * Fetches metadata for a specific route and slug.
   * Used for both runtime fallback and dashboard loading.
   */
  @Public()
  @Get()
  async getMetadata(
    @Query('route_type') route_type: string,
    @Query('slug') slug: string,
    @Query('locale') locale?: string,
  ) {
    if (!route_type || !slug) {
      return {
        success: false,
        message: 'Missing route_type or slug arguments',
      };
    }

    const data = await this.pageSeoMetadataService.getSeoBySlug(
      route_type,
      slug,
      locale,
    );

    return {
      success: !!data,
      data: data || null,
    };
  }

  @Public()
  @Get('all')
  async getAll() {
    const list = await this.pageSeoMetadataService.findAll();
    return { success: true, data: list };
  }

  @Public()
  @Post()
  async saveMetadata(@Body() body: any) {
    try {
      const data = await this.pageSeoMetadataService.upsertPageSeo(
        body,
        body.user_id,
      );
      return { success: true, data };
    } catch (e) {
      return { success: false, message: e.message };
    }
  }

  /**
   * Endpoint: PUT /api/seo/:id
   */
  @Public()
  @Put(':id')
  async updateMetadata(@Param('id') id: string, @Body() body: any) {
    try {
      const data = await this.pageSeoMetadataService.updateSeo(
        +id,
        body,
        body.user_id,
      );
      return { success: true, data };
    } catch (e) {
      return { success: false, message: e.message };
    }
  }

  /**
   * Endpoint: PATCH /api/seo/:id
   * Explicitly for partial updates.
   */
  @Public()
  @Patch(':id')
  async partialUpdate(@Param('id') id: string, @Body() body: any) {
    try {
      const data = await this.pageSeoMetadataService.updateSeo(
        +id,
        body,
        body.user_id,
      );
      return { success: true, data };
    } catch (e) {
      return { success: false, message: e.message };
    }
  }

  /**
   * Endpoint: PATCH /api/seo/:id/toggle
   */
  @Public()
  @Patch(':id/toggle')
  async toggleStatus(@Param('id') id: string) {
    try {
      const data = await this.pageSeoMetadataService.toggleActiveStatus(+id);
      return { success: true, data };
    } catch (e) {
      return { success: false, message: e.message };
    }
  }

  /**
   * Aggregate Search Endpoint for Sidebar
   * GET /api/seo/search/:type?query=...
   */
  @Public()
  @Get('search/:type')
  async search(@Param('type') type: string, @Query('query') query: string) {
    let results = [];
    switch (type) {
      case 'cities':
        results = await this.pageSeoMetadataService.searchCities(query);
        break;
      case 'industries':
        results = await this.pageSeoMetadataService.searchIndustries(query);
        break;
      case 'education':
        results = await this.pageSeoMetadataService.searchEducation(query);
        break;
      case 'roles':
        results = await this.pageSeoMetadataService.searchRoles(query);
        break;
      case 'job-types':
        results = await this.pageSeoMetadataService.searchJobTypes(query);
        break;
      case 'categories':
        results = await this.pageSeoMetadataService.searchCategories(query);
        break;
      default:
        return { success: false, message: 'Invalid search type' };
    }
    return { success: true, data: results };
  }

  /**
   * Endpoint: GET /api/seo/history/:seoId
   * Returns paginated change history for a record.
   */
  @Public()
  @Get('history/:seoId')
  async getHistory(
    @Param('seoId') seoId: string,
    @Query('limit') limit?: string,
    @Query('offset') offset?: string,
  ) {
    const history = await this.auditService.getHistory(
      +seoId,
      limit ? +limit : 20,
      offset ? +offset : 0,
    );
    return { success: true, data: history };
  }
}
